forked from AkkomaGang/akkoma-fe
Sync develop with 2023.02 stable branch #6
6 changed files with 126 additions and 5 deletions
|
@ -6,11 +6,13 @@ import TimelineMenuTabs from '../timeline_menu_tabs/timeline_menu_tabs.vue'
|
|||
import TimelineQuickSettings from './timeline_quick_settings.vue'
|
||||
import { debounce, throttle, keyBy } from 'lodash'
|
||||
import { library } from '@fortawesome/fontawesome-svg-core'
|
||||
import { faCircleNotch, faCog } from '@fortawesome/free-solid-svg-icons'
|
||||
import { faCircleNotch, faCog, faPlus, faMinus } from '@fortawesome/free-solid-svg-icons'
|
||||
|
||||
library.add(
|
||||
faCircleNotch,
|
||||
faCog
|
||||
faCog,
|
||||
faPlus,
|
||||
faMinus
|
||||
)
|
||||
|
||||
const Timeline = {
|
||||
|
@ -90,6 +92,15 @@ const Timeline = {
|
|||
},
|
||||
showPanelNavShortcuts () {
|
||||
return this.$store.getters.mergedConfig.showPanelNavShortcuts
|
||||
},
|
||||
currentUser () {
|
||||
return this.$store.state.users.currentUser
|
||||
},
|
||||
tagData () {
|
||||
return this.$store.state.tags.tags[this.tag]
|
||||
},
|
||||
tagFollowed () {
|
||||
return this.$store.state.tags.tags[this.tag]?.following
|
||||
}
|
||||
},
|
||||
created () {
|
||||
|
@ -118,6 +129,10 @@ const Timeline = {
|
|||
}
|
||||
window.addEventListener('keydown', this.handleShortKey)
|
||||
setTimeout(this.determineVisibleStatuses, 250)
|
||||
|
||||
if (this.tag) {
|
||||
this.$store.dispatch('getTag', this.tag)
|
||||
}
|
||||
},
|
||||
unmounted () {
|
||||
window.removeEventListener('scroll', this.handleScroll)
|
||||
|
@ -232,6 +247,12 @@ const Timeline = {
|
|||
}, 200),
|
||||
handleVisibilityChange () {
|
||||
this.unfocused = document.hidden
|
||||
},
|
||||
followTag (tag) {
|
||||
return this.$store.dispatch('followTag', tag)
|
||||
},
|
||||
unfollowTag (tag) {
|
||||
return this.$store.dispatch('unfollowTag', tag)
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
|
|
|
@ -21,6 +21,36 @@
|
|||
{{ $t('timeline.up_to_date') }}
|
||||
</div>
|
||||
<TimelineQuickSettings v-if="!embedded" />
|
||||
<div
|
||||
v-if="currentUser && tag !== undefined && tagData && !tagFollowed"
|
||||
class="followTag"
|
||||
>
|
||||
<button
|
||||
class="button-default"
|
||||
:title="$t('timeline.follow_tag')"
|
||||
@click="followTag(tag)"
|
||||
>
|
||||
<FAIcon
|
||||
size="sm"
|
||||
icon="plus"
|
||||
/>
|
||||
</button>
|
||||
</div>
|
||||
<div
|
||||
v-if="currentUser && tag !== undefined && tagData && tagFollowed"
|
||||
class="followTag"
|
||||
>
|
||||
<button
|
||||
class="button-default"
|
||||
:title="$t('timeline.unfollow_tag')"
|
||||
@click="unfollowTag(tag)"
|
||||
>
|
||||
<FAIcon
|
||||
size="sm"
|
||||
icon="minus"
|
||||
/>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<div :class="classes.body">
|
||||
<div
|
||||
|
|
|
@ -1055,7 +1055,9 @@
|
|||
"show_new": "Show new",
|
||||
"socket_broke": "Realtime connection lost: CloseEvent code {0}",
|
||||
"socket_reconnected": "Realtime connection established",
|
||||
"up_to_date": "Up-to-date"
|
||||
"up_to_date": "Up-to-date",
|
||||
"follow_tag": "Follow hashtag",
|
||||
"unfollow_tag": "Unfollow hashtag"
|
||||
},
|
||||
"toast": {
|
||||
"no_translation_target_set": "No translation target language set - this may fail. Please set a target language in your settings."
|
||||
|
|
|
@ -21,6 +21,7 @@ import postStatusModule from './modules/postStatus.js'
|
|||
import announcementsModule from './modules/announcements.js'
|
||||
import editStatusModule from './modules/editStatus.js'
|
||||
import statusHistoryModule from './modules/statusHistory.js'
|
||||
import tagModule from './modules/tags.js'
|
||||
|
||||
import { createI18n } from 'vue-i18n'
|
||||
|
||||
|
@ -96,7 +97,8 @@ const persistedStateOptions = {
|
|||
postStatus: postStatusModule,
|
||||
announcements: announcementsModule,
|
||||
editStatus: editStatusModule,
|
||||
statusHistory: statusHistoryModule
|
||||
statusHistory: statusHistoryModule,
|
||||
tags: tagModule
|
||||
},
|
||||
plugins,
|
||||
strict: false // Socket modifies itself, let's ignore this for now.
|
||||
|
|
37
src/modules/tags.js
Normal file
37
src/modules/tags.js
Normal file
|
@ -0,0 +1,37 @@
|
|||
import { merge } from 'lodash'
|
||||
|
||||
const tags = {
|
||||
state: {
|
||||
// Contains key = id, value = number of trackers for this poll
|
||||
tags: {}
|
||||
},
|
||||
mutations: {
|
||||
setTag (state, { name, data }) {
|
||||
state.tags[name] = data
|
||||
}
|
||||
},
|
||||
actions: {
|
||||
getTag ({ rootState, commit }, tagName) {
|
||||
return rootState.api.backendInteractor.getHashtag({ tag: tagName }).then(tag => {
|
||||
commit('setTag', { name: tagName, data: tag })
|
||||
return tag
|
||||
})
|
||||
},
|
||||
followTag (store, tagName) {
|
||||
return store.rootState.api.backendInteractor.followHashtag({ tag: tagName })
|
||||
.then((resp) => {
|
||||
store.commit('setTag', { name: tagName, data: resp })
|
||||
return resp
|
||||
})
|
||||
},
|
||||
unfollowTag ({ rootState, commit }, tag) {
|
||||
return rootState.api.backendInteractor.unfollowHashtag({ tag })
|
||||
.then((resp) => {
|
||||
commit('setTag', { name: tag, data: resp })
|
||||
return resp
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export default tags
|
|
@ -108,6 +108,9 @@ const PLEROMA_EDIT_ANNOUNCEMENT_URL = id => `/api/v1/pleroma/admin/announcements
|
|||
const PLEROMA_DELETE_ANNOUNCEMENT_URL = id => `/api/v1/pleroma/admin/announcements/${id}`
|
||||
const AKKOMA_SETTING_PROFILE_URL = (name) => `/api/v1/akkoma/frontend_settings/pleroma-fe/${name}`
|
||||
const AKKOMA_SETTING_PROFILE_LIST = `/api/v1/akkoma/frontend_settings/pleroma-fe`
|
||||
const MASTODON_TAG_URL = (name) => `/api/v1/tags/${name}`
|
||||
const MASTODON_FOLLOW_TAG_URL = (name) => `/api/v1/tags/${name}/follow`
|
||||
const MASTODON_UNFOLLOW_TAG_URL = (name) => `/api/v1/tags/${name}/unfollow`
|
||||
|
||||
const oldfetch = window.fetch
|
||||
|
||||
|
@ -1549,6 +1552,29 @@ const listSettingsProfiles = ({ credentials }) => {
|
|||
})
|
||||
}
|
||||
|
||||
const getHashtag = ({ tag, credentials }) => {
|
||||
return promisedRequest({
|
||||
url: MASTODON_TAG_URL(tag),
|
||||
credentials
|
||||
})
|
||||
}
|
||||
|
||||
const followHashtag = ({ tag, credentials }) => {
|
||||
return promisedRequest({
|
||||
url: MASTODON_FOLLOW_TAG_URL(tag),
|
||||
method: 'POST',
|
||||
credentials
|
||||
})
|
||||
}
|
||||
|
||||
const unfollowHashtag = ({ tag, credentials }) => {
|
||||
return promisedRequest({
|
||||
url: MASTODON_UNFOLLOW_TAG_URL(tag),
|
||||
method: 'POST',
|
||||
credentials
|
||||
})
|
||||
}
|
||||
|
||||
export const getMastodonSocketURI = ({ credentials, stream, args = {} }) => {
|
||||
return Object.entries({
|
||||
...(credentials
|
||||
|
@ -1784,7 +1810,10 @@ const apiService = {
|
|||
getReports,
|
||||
updateReportStates,
|
||||
addNoteToReport,
|
||||
deleteNoteFromReport
|
||||
deleteNoteFromReport,
|
||||
getHashtag,
|
||||
followHashtag,
|
||||
unfollowHashtag
|
||||
}
|
||||
|
||||
export default apiService
|
||||
|
|
Loading…
Reference in a new issue