diff --git a/src/components/chat_message/chat_message.js b/src/components/chat_message/chat_message.js
index 5d086aade..aabdec31f 100644
--- a/src/components/chat_message/chat_message.js
+++ b/src/components/chat_message/chat_message.js
@@ -1,5 +1,6 @@
-import { mapState } from 'pinia'
+import { mapState as mapPiniaState } from 'pinia'
import { defineAsyncComponent } from 'vue'
+import { mapState } from 'vuex'
import Attachment from 'src/components/attachment/attachment.vue'
import ChatMessageDate from 'src/components/chat_message_date/chat_message_date.vue'
@@ -19,8 +20,6 @@ import UserPopover from 'src/components/user_popover/user_popover.vue'
import { useInstanceStore } from 'src/stores/instance.js'
import { useInterfaceStore } from 'src/stores/interface'
import { useMergedConfigStore } from 'src/stores/merged_config.js'
-import { useStatusesStore } from 'src/stores/statuses.js'
-import { useUsersStore } from 'src/stores/users.js'
import { library } from '@fortawesome/fontawesome-svg-core'
import {
@@ -80,7 +79,7 @@ const ChatMessage = {
return this.isStatus ? this.message.user.id : this.message.account_id
},
author() {
- return useUsersStore().findUser(this.authorId)
+ return this.$store.getters.findUser(this.authorId)
},
isCurrentUser() {
// mini-hack/optimizaiton:
@@ -101,21 +100,25 @@ const ChatMessage = {
return !this.message.in_reply_to_status_id
},
customReplyTo() {
- return useStatusesStore().allStatuses.get(
- this.message.in_reply_to_status_id,
- )
+ return this.$store.state.statuses.allStatusesObject[
+ this.message.in_reply_to_status_id
+ ]
},
replyToName() {
if (this.message.in_reply_to_screen_name) {
return this.message.in_reply_to_screen_name
} else {
- const user = useUsersStore().findUser(this.message.in_reply_to_user_id)
+ const user = this.$store.getters.findUser(
+ this.message.in_reply_to_user_id,
+ )
return user?.screen_name_ui
}
},
replyProfileLink() {
if (this.isCustomReply) {
- const user = useUsersStore().findUser(this.message.in_reply_to_user_id)
+ const user = this.$store.getters.findUser(
+ this.message.in_reply_to_user_id,
+ )
// FIXME Why user not found sometimes???
return user ? user.statusnet_profile_url : 'NOT_FOUND'
}
@@ -164,12 +167,14 @@ const ChatMessage = {
},
// Global stuff
- ...mapState(useInterfaceStore, {
+ ...mapPiniaState(useInterfaceStore, {
betterShadow: (store) => store.browserSupport.cssFilter,
}),
- ...mapState(useUsersStore, ['currentUser']),
- ...mapState(useInstanceStore, ['restrictedNicknames']),
- ...mapState(useMergedConfigStore, ['mergedConfig']),
+ ...mapState({
+ currentUser: (state) => state.users.currentUser,
+ restrictedNicknames: (state) => useInstanceStore().restrictedNicknames,
+ }),
+ ...mapPiniaState(useMergedConfigStore, ['mergedConfig']),
},
data() {
return {
diff --git a/src/components/chat_message/chat_message.vue b/src/components/chat_message/chat_message.vue
index a6700201d..88ab2fc0a 100644
--- a/src/components/chat_message/chat_message.vue
+++ b/src/components/chat_message/chat_message.vue
@@ -83,7 +83,7 @@
state.users.currentUser,
+ }),
+ ...mapGetters(['findUser']),
},
methods: {
goBack() {
@@ -71,8 +73,7 @@ const chatNew = {
this.loading = true
this.userIds = []
this.$store
- this.useSearchStore()
- .search({ q: query, resolve: true, type: 'accounts' })
+ .dispatch('search', { q: query, resolve: true, type: 'accounts' })
.then((data) => {
this.loading = false
this.userIds = data.accounts.map((a) => a.id)
diff --git a/src/components/chat_title/chat_title.vue b/src/components/chat_title/chat_title.vue
index cae9064d2..905a32d85 100644
--- a/src/components/chat_title/chat_title.vue
+++ b/src/components/chat_title/chat_title.vue
@@ -10,7 +10,7 @@
>
store.layoutType === 'mobile',
}),
- ...mapState(useMergedConfigStore, ['mergedConfig']),
- ...mapState(useUsersStore, ['currentUser']),
+ ...mapPiniaState(useMergedConfigStore, ['mergedConfig']),
+ ...mapState({
+ mastoUserSocketStatus: (state) => state.api.mastoUserSocketStatus,
+ currentUser: (state) => state.users.currentUser,
+ }),
},
watch: {
messages(old, neu) {
@@ -231,85 +226,16 @@ const Chat = {
return
}
- this.deactivate()
- this.activate()
+ this.clear()
+ this.startFetching()
+ },
+ mastoUserSocketStatus(newValue) {
+ if (newValue === WSConnectionStatus.JOINED) {
+ this.fetchChat({ isFirstFetch: true })
+ }
},
},
methods: {
- async activate() {
- if (!this.isConversation) {
- try {
- const result = await getOrCreateChat({
- accountId: this.chatUserId,
- credentials: useOAuthStore().token,
- })
- useUsersStore().addNewUsers(result)
- const { data } = result
- data.account = useUsersStore().findUser(data.account.id)
- this.chat = data
- } catch (e) {
- console.error('Error creating or getting a chat', e)
- this.errorLoadingChat = true
- }
- }
-
- if (this.isConversation || this.chat) {
- this.$nextTick(() => {
- this.scrollDown({ forceRead: true })
- })
- this.startFetching('Chat activated', true)
- }
- },
- deactivate() {
- this.clear()
- if (!this.streaming) {
- this.stopFetching()
- }
- },
- attachSocket() {
- const et = new EventTarget()
- const socket = { et }
-
- et.addEventListener('update', this.onStreamMessage)
- et.addEventListener('open', this.onStreamConnect)
- et.addEventListener('close', this.onStreamDisconnect)
-
- useStreamingStore().addSubscriber(socket)
- this.socket = socket
- },
- detachSocket() {
- const { et } = this.socket
-
- et.removeEventListener('update', this.onStreamMessage)
- et.removeEventListener('open', this.onStreamConnect)
- et.removeEventListener('close', this.onStreamDisconnect)
-
- useStreamingStore().removeSubscriber(this.socket)
- },
-
- // Poll & Push
- onStreamConnect() {
- this.streaming = true
- this.stopFetching('Socket connected')
- },
- onStreamDisconnect(closeEvent) {
- this.streaming = false
- this.startFetching('Socket disconnected')
- },
- startFetching(reason, isFirstFetch) {
- console.debug('[Chat View] Started fetching', 'Reason:', reason)
- this.fetcher = promiseInterval(
- () => this.fetchChat({ fetchLatest: true }),
- 5000,
- )
- this.fetchChat({ isFirstFetch })
- },
- stopFetching(reason) {
- console.debug('[Chat View] Stopped fetching', 'Reason:', reason)
- this.fetcher.stop()
- this.fetcher = null
- },
-
// Actions
async readChat() {
if (this.conversationId) return // Unsupported
@@ -333,8 +259,18 @@ const Chat = {
this.lastReadMessageId = this.maxId
this.newMessageCount = 0
},
-
- // Clears
+ scrollDown(options = {}) {
+ const { behavior = 'auto', forceRead = false } = options
+ this.$nextTick(() => {
+ window.scrollTo({
+ top: document.documentElement.scrollHeight,
+ behavior,
+ })
+ })
+ if (forceRead) {
+ this.readChat()
+ }
+ },
cullOlder() {
const maxIndex = this.messages.length
const minIndex = maxIndex - 50
@@ -430,12 +366,35 @@ const Chat = {
})
}
},
- onStreamMessage({ data }) {
- const messages = data.filter(
- ({ statusnet_conversation_id }) =>
- statusnet_conversation_id === this.conversationId,
+ async startFetching() {
+ if (!this.isConversation) {
+ try {
+ const { data } = await getOrCreateChat({
+ accountId: this.chatUserId,
+ credentials: useOAuthStore().token,
+ })
+ this.$store.commit('addNewUsers', [data.account])
+ data.account = this.$store.getters.findUser(data.account.id)
+ this.chat = data
+ } catch (e) {
+ console.error('Error creating or getting a chat', e)
+ this.errorLoadingChat = true
+ }
+ }
+
+ if (this.isConversation || this.chat) {
+ this.$nextTick(() => {
+ this.scrollDown({ forceRead: true })
+ })
+ this.doStartFetching()
+ }
+ },
+ doStartFetching() {
+ this.fetcher = promiseInterval(
+ () => this.fetchChat({ fetchLatest: true }),
+ 5000,
)
- this.addMessages({ messages })
+ this.fetchChat({ isFirstFetch: true })
},
addMessages({ messages: newMessages }) {
for (let i = 0; i < newMessages.length; i++) {
@@ -479,6 +438,9 @@ const Chat = {
}
}
},
+ goBack() {
+ this.$router.back()
+ },
// Optimistic posting (chats only)
async sendMessage({ status, media, idempotencyKey }) {
@@ -656,23 +618,6 @@ const Chat = {
})
},
- // Misc
- scrollDown(options = {}) {
- const { behavior = 'auto', forceRead = false } = options
- this.$nextTick(() => {
- window.scrollTo({
- top: document.documentElement.scrollHeight,
- behavior,
- })
- })
- if (forceRead) {
- this.readChat()
- }
- },
- goBack() {
- this.$router.back()
- },
-
// Ugly
// TODO move to ChatMessage
async deleteChatMessage({ chatId, messageId }) {
diff --git a/src/components/confirm_modal/mute_confirm.js b/src/components/confirm_modal/mute_confirm.js
index 2247c2e91..c2f5ff888 100644
--- a/src/components/confirm_modal/mute_confirm.js
+++ b/src/components/confirm_modal/mute_confirm.js
@@ -4,8 +4,6 @@ import { defineAsyncComponent } from 'vue'
import Select from 'src/components/select/select.vue'
import { useMergedConfigStore } from 'src/stores/merged_config.js'
-import { useStatusesStore } from 'src/stores/statuses.js'
-import { useUsersStore } from 'src/stores/users.js'
export default {
props: ['type', 'user', 'status'],
@@ -35,7 +33,9 @@ export default {
return this.status.conversation_muted
},
domainIsMuted() {
- return new Set(useUsersStore().currentUser.domainMutes).has(this.domain)
+ return new Set(this.$store.state.users.currentUser.domainMutes).has(
+ this.domain,
+ )
},
shouldConfirm() {
switch (this.type) {
@@ -70,17 +70,17 @@ export default {
switch (this.type) {
case 'domain': {
if (!this.domainIsMuted) {
- useUsersStore().muteDomain(this.domain)
+ this.$store.dispatch('muteDomain', this.domain)
} else {
- useUsersStore().unmuteDomain(this.domain)
+ this.$store.dispatch('unmuteDomain', this.domain)
}
break
}
case 'conversation': {
if (!this.conversationIsMuted) {
- useStatusesStore().muteConversation(this.status.id)
+ this.$store.dispatch('muteConversation', { id: this.status.id })
} else {
- useStatusesStore().unmuteConversation(this.status.id)
+ this.$store.dispatch('unmuteConversation', { id: this.status.id })
}
break
}
diff --git a/src/components/conversation/conversation.js b/src/components/conversation/conversation.js
index cc4aecfe3..ea5637944 100644
--- a/src/components/conversation/conversation.js
+++ b/src/components/conversation/conversation.js
@@ -1,4 +1,4 @@
-import { get, reduce } from 'lodash'
+import { clone, filter, findIndex, get, reduce } from 'lodash'
import { mapState as mapPiniaState } from 'pinia'
import { mapState } from 'vuex'
@@ -9,10 +9,9 @@ import QuickViewSettings from 'src/components/quick_view_settings/quick_view_set
import RichContent from 'src/components/rich_content/rich_content.jsx'
import ThreadTree from 'src/components/thread_tree/thread_tree.vue'
-import { useInterfaceStore } from 'src/stores/interface.js'
+import { useInterfaceStore } from 'src/stores/interface'
import { useMergedConfigStore } from 'src/stores/merged_config.js'
import { useOAuthStore } from 'src/stores/oauth.js'
-import { useStatusesStore } from 'src/stores/statuses.js'
import { fetchConversation, fetchStatus } from 'src/api/public.js'
import { WSConnectionStatus } from 'src/api/websocket.js'
@@ -52,6 +51,20 @@ const sortById = (a, b) => {
}
}
+const sortAndFilterConversation = (conversation, statusoid) => {
+ if (statusoid.type === 'retweet') {
+ conversation = filter(
+ conversation,
+ (status) =>
+ status.type === 'retweet' ||
+ status.id !== statusoid.retweeted_status.id,
+ )
+ } else {
+ conversation = filter(conversation, (status) => status.type !== 'retweet')
+ }
+ return conversation.filter(Boolean).sort(sortById)
+}
+
const conversation = {
props: {
statusId: {
@@ -109,9 +122,6 @@ const conversation = {
}
},
computed: {
- status() {
- return useStatusesStore().allStatuses.get(this.statusId)
- },
maxDepthToShowByDefault() {
// maxDepthInThread = max number of depths that is *visible*
// since our depth starts with 0 and "showing" means "showing children"
@@ -155,6 +165,9 @@ const conversation = {
hideStatus() {
return this.virtualHidden && this.suspendable
},
+ status() {
+ return this.$store.state.statuses.allStatusesObject[this.statusId]
+ },
originalStatusId() {
if (this.status.retweeted_status) {
return this.status.retweeted_status.id
@@ -174,13 +187,15 @@ const conversation = {
return [this.status]
}
- const conversation = useStatusesStore().conversations.get(
- this.conversationId,
+ const conversation = clone(
+ this.$store.state.statuses.conversationsObject[this.conversationId],
)
+ const statusIndex = findIndex(conversation, { id: this.originalStatusId })
+ if (statusIndex !== -1) {
+ conversation[statusIndex] = this.status
+ }
- return [...conversation.keys()]
- .map((k) => useStatusesStore().allStatuses.get(k))
- .toSorted(sortById)
+ return sortAndFilterConversation(conversation, this.status)
},
statusMap() {
return this.conversation.reduce((res, s) => {
@@ -426,7 +441,7 @@ const conversation = {
}
},
virtualHidden() {
- useStatusesStore().setVirtualHeight({
+ this.$store.dispatch('setVirtualHeight', {
statusId: this.statusId,
height: `${this.$el.clientHeight}px`,
})
@@ -438,12 +453,9 @@ const conversation = {
fetchConversation({
id: this.statusId,
credentials: useOAuthStore().token,
- }).then(({ data: { ancestors, descendants }, timestamp }) => {
- useStatusesStore().addNewStatuses({ statuses: ancestors, timestamp })
- useStatusesStore().addNewStatuses({
- statuses: descendants,
- timestamp,
- })
+ }).then(({ data: { ancestors, descendants } }) => {
+ this.$store.dispatch('addNewStatuses', { statuses: ancestors })
+ this.$store.dispatch('addNewStatuses', { statuses: descendants })
this.setFocused(this.originalStatusId)
})
} else {
@@ -453,7 +465,7 @@ const conversation = {
credentials: useOAuthStore().token,
})
.then(({ data: status }) => {
- useStatusesStore().addNewStatuses({ statuses: [status] })
+ this.$store.dispatch('addNewStatuses', { statuses: [status] })
this.fetchConversation()
})
.catch((error) => {
@@ -470,17 +482,17 @@ const conversation = {
this.focused = id
if (!this.streamingEnabled) {
- useStatusesStore().fetchStatus(id)
+ this.$store.dispatch('fetchStatus', id)
}
- useStatusesStore().fetchFavsAndRepeats(id)
- useStatusesStore().fetchEmojiReactions(id)
+ this.$store.dispatch('fetchFavsAndRepeats', id)
+ this.$store.dispatch('fetchEmojiReactionsBy', id)
},
toggleExpanded() {
this.expanded = !this.expanded
},
getConversationId(statusId) {
- const status = useStatusesStore().allStatuses.get(statusId)
+ const status = this.$store.state.statuses.allStatusesObject[statusId]
return get(
status,
'retweeted_status.statusnet_conversation_id',
diff --git a/src/components/conversation/conversation.vue b/src/components/conversation/conversation.vue
index ae6e3a0ce..0833c4f89 100644
--- a/src/components/conversation/conversation.vue
+++ b/src/components/conversation/conversation.vue
@@ -99,7 +99,7 @@
ref="statusComponent"
class="conversation-status status-fadein panel-body"
- :status-id="status.id"
+ :statusoid="status"
:replies="getReplies(status.id)"
:expandable="!isExpanded"
@@ -152,7 +152,7 @@
ref="statusComponent"
:depth="0"
- :status-id="status.id"
+ :status="status"
:in-profile="inProfile"
:conversation="conversation"
:collapsable="collapsable"
@@ -186,7 +186,7 @@
:key="status.id"
ref="statusComponent"
class="conversation-status status-fadein panel-body"
- :status-id="status.id"
+ :statusoid="status"
:replies="getReplies(status.id)"
:expandable="!isExpanded"
diff --git a/src/components/desktop_nav/desktop_nav.js b/src/components/desktop_nav/desktop_nav.js
index 32d0b37a9..cc2c5aca9 100644
--- a/src/components/desktop_nav/desktop_nav.js
+++ b/src/components/desktop_nav/desktop_nav.js
@@ -5,10 +5,6 @@ import { defineAsyncComponent } from 'vue'
import { useInstanceStore } from 'src/stores/instance.js'
import { useInterfaceStore } from 'src/stores/interface'
import { useMergedConfigStore } from 'src/stores/merged_config.js'
-import { useStreamingStore } from 'src/stores/streaming.js'
-import { useUsersStore } from 'src/stores/users.js'
-
-import { WSConnectionStatus } from 'src/api/websocket.js'
import { library } from '@fortawesome/fontawesome-svg-core'
import {
@@ -18,8 +14,6 @@ import {
faComments,
faHome,
faInfoCircle,
- faPlug,
- faPlugCircleXmark,
faSearch,
faSignInAlt,
faSignOutAlt,
@@ -39,8 +33,6 @@ library.add(
faTachometerAlt,
faCog,
faInfoCircle,
- faPlug,
- faPlugCircleXmark,
)
export default {
@@ -99,23 +91,11 @@ export default {
sitename: (store) => store.instanceIdentity.name,
hideSitename: (store) => store.instanceIdentity.hideSitename,
}),
- ...mapState(useUsersStore, ['currentUser']),
- ...mapState(useStreamingStore, {
- streamingConnected: (store) => store.state === WSConnectionStatus.JOINED,
- }),
- ...mapState(useMergedConfigStore, ['mergedConfig']),
+ currentUser() {
+ return this.$store.state.users.currentUser
+ },
shouldConfirmLogout() {
- return this.mergedConfig.modalOnLogout
- },
- streamingEnabled() {
- return this.mergedConfig.useStreamingApi
- },
- streamingTooltip() {
- if (this.streamingConnected) {
- return this.$t('timeline.socket_reconnected')
- } else {
- return this.$t('timeline.socket_disconnected')
- }
+ return useMergedConfigStore().mergedConfig.modalOnLogout
},
},
methods: {
@@ -137,7 +117,7 @@ export default {
},
doLogout() {
this.$router.replace('/main/public')
- useUsersStore().logout()
+ this.$store.dispatch('logout')
this.hideConfirmLogout()
},
onSearchBarToggled(hidden) {
diff --git a/src/components/desktop_nav/desktop_nav.vue b/src/components/desktop_nav/desktop_nav.vue
index 52370a57f..3883b3c6f 100644
--- a/src/components/desktop_nav/desktop_nav.vue
+++ b/src/components/desktop_nav/desktop_nav.vue
@@ -15,24 +15,6 @@
>
{{ sitename }}
-
-
-
-
+
+
+
+
diff --git a/src/components/domain_mute_card/domain_mute_card.js b/src/components/domain_mute_card/domain_mute_card.js
index 274679b8d..d83896618 100644
--- a/src/components/domain_mute_card/domain_mute_card.js
+++ b/src/components/domain_mute_card/domain_mute_card.js
@@ -1,7 +1,5 @@
import ProgressButton from 'src/components/progress_button/progress_button.vue'
-import { useUsersStore } from 'src/stores/users.js'
-
const DomainMuteCard = {
props: ['domain'],
components: {
@@ -9,7 +7,7 @@ const DomainMuteCard = {
},
computed: {
user() {
- return useUsersStore().currentUser
+ return this.$store.state.users.currentUser
},
muted() {
return this.user.domainMutes.includes(this.domain)
@@ -17,10 +15,10 @@ const DomainMuteCard = {
},
methods: {
unmuteDomain() {
- return useUsersStore().unmuteDomain(this.domain)
+ return this.$store.dispatch('unmuteDomain', this.domain)
},
muteDomain() {
- return useUsersStore().muteDomain(this.domain)
+ return this.$store.dispatch('muteDomain', this.domain)
},
},
}
diff --git a/src/components/draft/draft.js b/src/components/draft/draft.js
index 1c7f419c6..49e186eae 100644
--- a/src/components/draft/draft.js
+++ b/src/components/draft/draft.js
@@ -6,7 +6,6 @@ import PostStatusForm from 'src/components/post_status_form/post_status_form.vue
import StatusContent from 'src/components/status_content/status_content.vue'
import { useMergedConfigStore } from 'src/stores/merged_config.js'
-import { useStatusesStore } from 'src/stores/statuses.js'
import { library } from '@fortawesome/fontawesome-svg-core'
import { faPollH } from '@fortawesome/free-solid-svg-icons'
@@ -66,7 +65,7 @@ const Draft = {
},
refStatus() {
return this.draft.refId
- ? useStatusesStore().allStatuses.get(this.draft.refId)
+ ? this.$store.state.statuses.allStatusesObject[this.draft.refId]
: undefined
},
localCollapseSubjectDefault() {
diff --git a/src/components/edit_status_modal/edit_status_modal.js b/src/components/edit_status_modal/edit_status_modal.js
index 12072d7a2..59c142d08 100644
--- a/src/components/edit_status_modal/edit_status_modal.js
+++ b/src/components/edit_status_modal/edit_status_modal.js
@@ -4,7 +4,6 @@ import { defineAsyncComponent } from 'vue'
import Modal from 'src/components/modal/modal.vue'
import { useEditStatusStore } from 'src/stores/editStatus.js'
-import { useUsersStore } from 'src/stores/users.js'
const EditStatusModal = {
components: {
@@ -20,7 +19,7 @@ const EditStatusModal = {
},
computed: {
isLoggedIn() {
- return !!useUsersStore().currentUser
+ return !!this.$store.state.users.currentUser
},
modalActivated() {
return useEditStatusStore().modalActivated
diff --git a/src/components/emoji_input/suggestor.js b/src/components/emoji_input/suggestor.js
index 6a7dbff9a..c31cb6717 100644
--- a/src/components/emoji_input/suggestor.js
+++ b/src/components/emoji_input/suggestor.js
@@ -1,5 +1,3 @@
-import { useSearchStore } from 'src/stores/search.js'
-
/**
* suggest - generates a suggestor function to be used by emoji-input
* data: object providing source information for specific types of suggestions:
@@ -79,7 +77,7 @@ export const suggestUsers = ({ dispatch, state }) => {
let timeout = null
let cancelUserSearch = null
- const userSearch = (query) => useSearchStore().searchUsers({ query })
+ const userSearch = (query) => dispatch('searchUsers', { query })
const debounceUserSearch = (query) => {
cancelUserSearch?.()
return new Promise((resolve, reject) => {
diff --git a/src/components/emoji_reactions/emoji_reactions.js b/src/components/emoji_reactions/emoji_reactions.js
index 3077ed212..acb5404c0 100644
--- a/src/components/emoji_reactions/emoji_reactions.js
+++ b/src/components/emoji_reactions/emoji_reactions.js
@@ -3,8 +3,6 @@ import UserListPopover from 'src/components/user_list_popover/user_list_popover.
import { useInstanceStore } from 'src/stores/instance.js'
import { useMergedConfigStore } from 'src/stores/merged_config.js'
-import { useStatusesStore } from 'src/stores/statuses.js'
-import { useUsersStore } from 'src/stores/users.js'
import { library } from '@fortawesome/fontawesome-svg-core'
import { faCheck, faMinus, faPlus } from '@fortawesome/free-solid-svg-icons'
@@ -42,7 +40,7 @@ const EmojiReactions = {
}, {})
},
loggedIn() {
- return !!useUsersStore().currentUser
+ return !!this.$store.state.users.currentUser
},
remoteInteractionLink() {
return useInstanceStore().getRemoteInteractionLink({
@@ -60,22 +58,25 @@ const EmojiReactions = {
reactedWith(emoji) {
return this.status.emoji_reactions.find((r) => r.name === emoji).me
},
- async fetchEmojiReactionsIfMissing() {
+ async fetchEmojiReactionsByIfMissing() {
const hasNoAccounts = this.status.emoji_reactions.find((r) => !r.accounts)
- if (!hasNoAccounts) {
- return await useStatusesStore().fetchEmojiReactions(this.status.id)
+ if (hasNoAccounts) {
+ return await this.$store.dispatch(
+ 'fetchEmojiReactionsBy',
+ this.status.id,
+ )
}
},
reactWith(emoji) {
- useStatusesStore().reactWithEmoji(this.status.id, emoji)
+ this.$store.dispatch('reactWithEmoji', { id: this.status.id, emoji })
},
unreact(emoji) {
- useStatusesStore().unreactWithEmoji(this.status.id, emoji)
+ this.$store.dispatch('unreactWithEmoji', { id: this.status.id, emoji })
},
async emojiOnClick(emoji) {
if (!this.loggedIn) return
- await this.fetchEmojiReactionsIfMissing()
+ await this.fetchEmojiReactionsByIfMissing()
if (this.reactedWith(emoji)) {
this.unreact(emoji)
} else {
diff --git a/src/components/emoji_reactions/emoji_reactions.vue b/src/components/emoji_reactions/emoji_reactions.vue
index a8100c0d4..16c69fa40 100644
--- a/src/components/emoji_reactions/emoji_reactions.vue
+++ b/src/components/emoji_reactions/emoji_reactions.vue
@@ -56,7 +56,7 @@
class="emoji-reaction-popover"
:normal-button="true"
:trigger-attrs="counterTriggerAttrs(reaction)"
- @show="fetchEmojiReactionsIfMissing()"
+ @show="fetchEmojiReactionsByIfMissing()"
>
{{ reaction.count }}
diff --git a/src/components/extra_notifications/extra_notifications.js b/src/components/extra_notifications/extra_notifications.js
index 851656ae5..24ed074af 100644
--- a/src/components/extra_notifications/extra_notifications.js
+++ b/src/components/extra_notifications/extra_notifications.js
@@ -6,7 +6,6 @@ import { useChatsStore } from 'src/stores/chats.js'
import { useInterfaceStore } from 'src/stores/interface.js'
import { useMergedConfigStore } from 'src/stores/merged_config.js'
import { useSyncConfigStore } from 'src/stores/sync_config.js'
-import { useUsersStore } from 'src/stores/users.js'
import { library } from '@fortawesome/fontawesome-svg-core'
import {
@@ -53,7 +52,7 @@ const ExtraNotifications = {
)
},
currentUser() {
- return useUsersStore().currentUser
+ return this.$store.state.users.currentUser
},
...mapGetters(['followRequestCount']),
...mapState(useAnnouncementsStore, {
diff --git a/src/components/follow_button/follow_button.js b/src/components/follow_button/follow_button.js
index e4d243ff9..3fecc025f 100644
--- a/src/components/follow_button/follow_button.js
+++ b/src/components/follow_button/follow_button.js
@@ -1,8 +1,11 @@
import { defineAsyncComponent } from 'vue'
-import { useMergedConfigStore } from 'src/stores/merged_config.js'
-import { useUsersStore } from 'src/stores/users.js'
+import {
+ requestFollow,
+ requestUnfollow,
+} from '../../services/follow_manipulate/follow_manipulate'
+import { useMergedConfigStore } from 'src/stores/merged_config.js'
export default {
props: ['relationship', 'user', 'labelFollowing', 'buttonClass'],
components: {
@@ -61,11 +64,9 @@ export default {
},
follow() {
this.inProgress = true
- useUsersStore()
- .followUser(this.relationship.id)
- .finally(() => {
- this.inProgress = false
- })
+ requestFollow(this.relationship.id, this.$store).then(() => {
+ this.inProgress = false
+ })
},
unfollow() {
if (this.shouldConfirmUnfollow) {
@@ -75,12 +76,15 @@ export default {
}
},
doUnfollow() {
+ const store = this.$store
this.inProgress = true
- useUsersStore()
- .unfollowUser(this.relationship.id)
- .finally(() => {
- this.inProgress = false
+ requestUnfollow(this.relationship.id, store).then(() => {
+ this.inProgress = false
+ store.commit('removeStatus', {
+ timeline: 'friends',
+ userId: this.relationship.id,
})
+ })
this.hideConfirmUnfollow()
},
diff --git a/src/components/follow_card/follow_card.js b/src/components/follow_card/follow_card.js
index 9a8b8746f..8fffbf730 100644
--- a/src/components/follow_card/follow_card.js
+++ b/src/components/follow_card/follow_card.js
@@ -3,8 +3,6 @@ import FollowButton from 'src/components/follow_button/follow_button.vue'
import RemoteFollow from 'src/components/remote_follow/remote_follow.vue'
import RemoveFollowerButton from 'src/components/remove_follower_button/remove_follower_button.vue'
-import { useUsersStore } from 'src/stores/users.js'
-
const FollowCard = {
props: ['user', 'noFollowsYou'],
components: {
@@ -15,13 +13,13 @@ const FollowCard = {
},
computed: {
isMe() {
- return useUsersStore().currentUser.id === this.user.id
+ return this.$store.state.users.currentUser.id === this.user.id
},
loggedIn() {
- return useUsersStore().currentUser
+ return this.$store.state.users.currentUser
},
relationship() {
- return useUsersStore().relationships.get(this.user.id)
+ return this.$store.getters.relationship(this.user.id)
},
},
}
diff --git a/src/components/follow_card/follow_card.vue b/src/components/follow_card/follow_card.vue
index d9a508a95..bdb6b8092 100644
--- a/src/components/follow_card/follow_card.vue
+++ b/src/components/follow_card/follow_card.vue
@@ -1,5 +1,5 @@
-
+
-
+
diff --git a/src/components/follow_request_card/follow_request_card.js b/src/components/follow_request_card/follow_request_card.js
index c4b43811a..294dd2472 100644
--- a/src/components/follow_request_card/follow_request_card.js
+++ b/src/components/follow_request_card/follow_request_card.js
@@ -1,9 +1,9 @@
import { defineAsyncComponent } from 'vue'
+import { notificationsFromStore } from '../../services/notification_utils/notification_utils.js'
import BasicUserCard from '../basic_user_card/basic_user_card.vue'
import { useMergedConfigStore } from 'src/stores/merged_config.js'
-import { useNotificationsStore } from 'src/stores/notifications.js'
import { useOAuthStore } from 'src/stores/oauth.js'
import { approveUser, denyUser } from 'src/api/user.js'
@@ -24,7 +24,7 @@ const FollowRequestCard = {
},
methods: {
findFollowRequestNotificationId() {
- const notif = useNotificationsStore().data.find(
+ const notif = notificationsFromStore(this.$store).find(
(notif) =>
notif.from_profile.id === this.user.id &&
notif.type === 'follow_request',
@@ -55,11 +55,16 @@ const FollowRequestCard = {
id: this.user.id,
credentials: useOAuthStore().token,
})
- // TODO fix
this.$store.dispatch('removeFollowRequest', this.user)
const notifId = this.findFollowRequestNotificationId()
- useNotificationsStore().markSingleNotificationAsSeen(notifId)
+ this.$store.dispatch('markSingleNotificationAsSeen', { id: notifId })
+ this.$store.dispatch('updateNotification', {
+ id: notifId,
+ updater: (notification) => {
+ notification.type = 'follow'
+ },
+ })
this.hideApproveConfirmDialog()
},
denyUser() {
@@ -76,8 +81,7 @@ const FollowRequestCard = {
id: this.user.id,
credentials: useOAuthStore().token,
}).then(() => {
- useNotificationsStore().dismissNotificationLocal(notifId)
- // TODO fix
+ this.$store.dispatch('dismissNotificationLocal', { id: notifId })
this.$store.dispatch('removeFollowRequest', this.user)
})
this.hideDenyConfirmDialog()
diff --git a/src/components/friends_timeline/friends_timeline.js b/src/components/friends_timeline/friends_timeline.js
new file mode 100644
index 000000000..b6bee7305
--- /dev/null
+++ b/src/components/friends_timeline/friends_timeline.js
@@ -0,0 +1,14 @@
+import Timeline from 'src/components/timeline/timeline.vue'
+
+const FriendsTimeline = {
+ components: {
+ Timeline,
+ },
+ computed: {
+ timeline() {
+ return this.$store.state.statuses.timelines.friends
+ },
+ },
+}
+
+export default FriendsTimeline
diff --git a/src/components/friends_timeline/friends_timeline.vue b/src/components/friends_timeline/friends_timeline.vue
new file mode 100644
index 000000000..01a568123
--- /dev/null
+++ b/src/components/friends_timeline/friends_timeline.vue
@@ -0,0 +1,9 @@
+
+
+
+
+
diff --git a/src/components/interactions/interactions.js b/src/components/interactions/interactions.js
index 37873605f..d008c4b30 100644
--- a/src/components/interactions/interactions.js
+++ b/src/components/interactions/interactions.js
@@ -1,8 +1,6 @@
import Notifications from 'src/components/notifications/notifications.vue'
import TabSwitcher from 'src/components/tab_switcher/tab_switcher.jsx'
-import { useUsersStore } from 'src/stores/users.js'
-
const tabModeDict = {
mentions: ['mention'],
statuses: ['status'],
@@ -16,9 +14,10 @@ const tabModeDict = {
const Interactions = {
data() {
return {
- allowFollowingMove: useUsersStore().currentUser.allow_following_move,
+ allowFollowingMove:
+ this.$store.state.users.currentUser.allow_following_move,
filterMode: tabModeDict.mentions,
- canSeeReports: useUsersStore().currentUser.privileges.has(
+ canSeeReports: this.$store.state.users.currentUser.privileges.has(
'reports_manage_reports',
),
}
diff --git a/src/components/list/list.js b/src/components/list/list.js
index 20b7c5a78..c7b924258 100644
--- a/src/components/list/list.js
+++ b/src/components/list/list.js
@@ -98,13 +98,12 @@ const List = {
this.fetchFunction(this.page)
.then((result) => {
- console.log(result)
this.loading = false
- this.bottomedOut = isEmpty(result)
+ this.bottomedOut = isEmpty(result.items)
if (this.externalItems) return
this.page += 1
- this.total = result.length
- this.items.push(...result)
+ this.total = result.count
+ this.items.push(...result.items)
})
.catch((error) => {
this.loading = false
diff --git a/src/components/lists_edit/lists_edit.js b/src/components/lists_edit/lists_edit.js
index cea9236a5..7eb035091 100644
--- a/src/components/lists_edit/lists_edit.js
+++ b/src/components/lists_edit/lists_edit.js
@@ -1,4 +1,5 @@
-import { mapState } from 'pinia'
+import { mapState as mapPiniaState } from 'pinia'
+import { mapGetters, mapState } from 'vuex'
import BasicUserCard from 'src/components/basic_user_card/basic_user_card.vue'
import ListsUserSearch from 'src/components/lists_user_search/lists_user_search.vue'
@@ -8,7 +9,6 @@ import UserAvatar from 'src/components/user_avatar/user_avatar.vue'
import { useInterfaceStore } from 'src/stores/interface.js'
import { useListsStore } from 'src/stores/lists.js'
-import { useUsersStore } from 'src/stores/users.js'
import { library } from '@fortawesome/fontawesome-svg-core'
import { faChevronLeft, faSearch } from '@fortawesome/free-solid-svg-icons'
@@ -47,8 +47,8 @@ const ListsNew = {
.fetchListAccounts({ listId: this.id })
.then(() => {
this.membersUserIds = this.findListAccounts(this.id)
- this.membersUserIds.forEach((id) => {
- useUsersStore().fetchUserIfMissing({ id })
+ this.membersUserIds.forEach((userId) => {
+ this.$store.dispatch('fetchUserIfMissing', userId)
})
})
},
@@ -66,8 +66,11 @@ const ListsNew = {
.map((userId) => this.findUser(userId))
.filter(Boolean)
},
- ...mapState(useUsersStore, ['currentUser', 'findUser']),
- ...mapState(useListsStore, ['findListTitle', 'findListAccounts']),
+ ...mapState({
+ currentUser: (state) => state.users.currentUser,
+ }),
+ ...mapPiniaState(useListsStore, ['findListTitle', 'findListAccounts']),
+ ...mapGetters(['findUser']),
},
methods: {
onInput() {
diff --git a/src/components/lists_menu/lists_menu_content.js b/src/components/lists_menu/lists_menu_content.js
index 7c422d033..337ee4d4f 100644
--- a/src/components/lists_menu/lists_menu_content.js
+++ b/src/components/lists_menu/lists_menu_content.js
@@ -1,10 +1,10 @@
-import { mapState } from 'pinia'
+import { mapState as mapPiniaState } from 'pinia'
+import { mapState } from 'vuex'
import { getListEntries } from 'src/components/navigation/filter.js'
import NavigationEntry from 'src/components/navigation/navigation_entry.vue'
import { useListsStore } from 'src/stores/lists.js'
-import { useUsersStore } from 'src/stores/users.js'
export const ListsMenuContent = {
props: ['showPin'],
@@ -12,10 +12,12 @@ export const ListsMenuContent = {
NavigationEntry,
},
computed: {
- ...mapState(useListsStore, {
+ ...mapPiniaState(useListsStore, {
lists: getListEntries,
}),
- ...mapState(useUsersStore, ['currentUser']),
+ ...mapState({
+ currentUser: (state) => state.users.currentUser,
+ }),
},
}
diff --git a/src/components/lists_timeline/lists_timeline.js b/src/components/lists_timeline/lists_timeline.js
new file mode 100644
index 000000000..a06220a37
--- /dev/null
+++ b/src/components/lists_timeline/lists_timeline.js
@@ -0,0 +1,47 @@
+import Timeline from 'src/components/timeline/timeline.vue'
+
+import { useListsStore } from 'src/stores/lists.js'
+
+const ListsTimeline = {
+ data() {
+ return {
+ listId: null,
+ }
+ },
+ components: {
+ Timeline,
+ },
+ computed: {
+ timeline() {
+ return this.$store.state.statuses.timelines.list
+ },
+ },
+ watch: {
+ $route: function (route) {
+ if (route.name === 'lists-timeline' && route.params.id !== this.listId) {
+ this.listId = route.params.id
+ this.$store.dispatch('stopFetchingTimeline', 'list')
+ this.$store.commit('clearTimeline', { timeline: 'list' })
+ useListsStore().fetchList({ listId: this.listId })
+ this.$store.dispatch('startFetchingTimeline', {
+ timeline: 'list',
+ listId: this.listId,
+ })
+ }
+ },
+ },
+ created() {
+ this.listId = this.$route.params.id
+ useListsStore().fetchList({ listId: this.listId })
+ this.$store.dispatch('startFetchingTimeline', {
+ timeline: 'list',
+ listId: this.listId,
+ })
+ },
+ unmounted() {
+ this.$store.dispatch('stopFetchingTimeline', 'list')
+ this.$store.commit('clearTimeline', { timeline: 'list' })
+ },
+}
+
+export default ListsTimeline
diff --git a/src/components/lists_timeline/lists_timeline.vue b/src/components/lists_timeline/lists_timeline.vue
new file mode 100644
index 000000000..18156b812
--- /dev/null
+++ b/src/components/lists_timeline/lists_timeline.vue
@@ -0,0 +1,10 @@
+
+
+
+
+
diff --git a/src/components/lists_user_search/lists_user_search.js b/src/components/lists_user_search/lists_user_search.js
index 5ac6e679a..aed3f1ce7 100644
--- a/src/components/lists_user_search/lists_user_search.js
+++ b/src/components/lists_user_search/lists_user_search.js
@@ -32,8 +32,8 @@ const ListsUserSearch = {
this.loading = true
this.$emit('loading')
this.userIds = []
- this.useSearchStore()
- .search({
+ this.$store
+ .dispatch('search', {
q: query,
resolve: true,
type: 'accounts',
diff --git a/src/components/mention_link/mention_link.js b/src/components/mention_link/mention_link.js
index 374e62259..0309079e8 100644
--- a/src/components/mention_link/mention_link.js
+++ b/src/components/mention_link/mention_link.js
@@ -1,4 +1,5 @@
-import { mapState } from 'pinia'
+import { mapState as mapPiniaState } from 'pinia'
+import { mapState } from 'vuex'
import UnicodeDomainIndicator from 'src/components/unicode_domain_indicator/unicode_domain_indicator.vue'
import UserAvatar from 'src/components/user_avatar/user_avatar.vue'
@@ -11,7 +12,6 @@ import {
import { useInstanceStore } from 'src/stores/instance.js'
import { useMergedConfigStore } from 'src/stores/merged_config.js'
import { useUserHighlightStore } from 'src/stores/user_highlight.js'
-import { useUsersStore } from 'src/stores/users.js'
import generateProfileLink from 'src/services/user_profile_link_generator/user_profile_link_generator'
@@ -75,7 +75,7 @@ const MentionLink = {
},
computed: {
user() {
- return this.url && useUsersStore().findUserByUrl(this.url)
+ return this.url && this.$store?.getters.findUserByUrl(this.url)
},
isYou() {
// FIXME why user !== currentUser???
@@ -156,9 +156,11 @@ const MentionLink = {
shouldFadeDomain() {
return this.mergedConfig.mentionLinkFadeDomain
},
- ...mapState(useMergedConfigStore, ['mergedConfig']),
- ...mapState(useUserHighlightStore, ['highlight']),
- ...mapState(useUsersStore, ['currentUser']),
+ ...mapPiniaState(useMergedConfigStore, ['mergedConfig']),
+ ...mapPiniaState(useUserHighlightStore, ['highlight']),
+ ...mapState({
+ currentUser: (state) => state.users.currentUser,
+ }),
},
}
diff --git a/src/components/mention_link/mention_link.vue b/src/components/mention_link/mention_link.vue
index 33f0d9db7..0452cad58 100644
--- a/src/components/mention_link/mention_link.vue
+++ b/src/components/mention_link/mention_link.vue
@@ -31,7 +31,7 @@
@
+
+
+
+
diff --git a/src/components/mobile_nav/mobile_nav.js b/src/components/mobile_nav/mobile_nav.js
index 163c0e9aa..4eb956f64 100644
--- a/src/components/mobile_nav/mobile_nav.js
+++ b/src/components/mobile_nav/mobile_nav.js
@@ -5,15 +5,13 @@ import NavigationPins from 'src/components/navigation/navigation_pins.vue'
import GestureService from '../../services/gesture_service/gesture_service'
import {
countExtraNotifications,
- unseenNotifications,
+ unseenNotificationsFromStore,
} from '../../services/notification_utils/notification_utils'
import { useAnnouncementsStore } from 'src/stores/announcements.js'
import { useChatsStore } from 'src/stores/chats.js'
import { useInstanceStore } from 'src/stores/instance.js'
import { useMergedConfigStore } from 'src/stores/merged_config.js'
-import { useNotificationsStore } from 'src/stores/notifications.js'
-import { useUsersStore } from 'src/stores/users.js'
import { library } from '@fortawesome/fontawesome-svg-core'
import {
@@ -55,10 +53,11 @@ const MobileNav = {
},
computed: {
currentUser() {
- return useUsersStore().currentUser
+ return this.$store.state.users.currentUser
},
unseenNotifications() {
- return unseenNotifications(
+ return unseenNotificationsFromStore(
+ this.$store,
useMergedConfigStore().mergedConfig.notificationVisibility,
useMergedConfigStore().mergedConfig.ignoreInactionableSeen,
)
@@ -146,11 +145,11 @@ const MobileNav = {
},
doLogout() {
this.$router.replace('/main/public')
- useUsersStore().logout()
+ this.$store.dispatch('logout')
this.hideConfirmLogout()
},
markNotificationsAsSeen() {
- useNotificationsStore().markNotificationsAsSeen()
+ this.$store.dispatch('markNotificationsAsSeen')
},
onScroll({ target: { scrollTop, clientHeight, scrollHeight } }) {
this.notificationsAtTop = scrollTop > 0
diff --git a/src/components/mobile_post_status_button/mobile_post_status_button.js b/src/components/mobile_post_status_button/mobile_post_status_button.js
index d137331c9..4969352f6 100644
--- a/src/components/mobile_post_status_button/mobile_post_status_button.js
+++ b/src/components/mobile_post_status_button/mobile_post_status_button.js
@@ -2,7 +2,6 @@ import { debounce } from 'lodash'
import { useMergedConfigStore } from 'src/stores/merged_config.js'
import { usePostStatusStore } from 'src/stores/post_status.js'
-import { useUsersStore } from 'src/stores/users.js'
import { library } from '@fortawesome/fontawesome-svg-core'
import { faPen } from '@fortawesome/free-solid-svg-icons'
@@ -35,7 +34,7 @@ const MobilePostStatusButton = {
},
computed: {
isLoggedIn() {
- return useUsersStore().loggedIn
+ return !!this.$store.state.users.currentUser
},
isHidden() {
if (HIDDEN_FOR_PAGES.has(this.$route.name)) {
diff --git a/src/components/moderation_tools/moderation_tools.js b/src/components/moderation_tools/moderation_tools.js
index 9b948e306..ba13afc8b 100644
--- a/src/components/moderation_tools/moderation_tools.js
+++ b/src/components/moderation_tools/moderation_tools.js
@@ -5,7 +5,6 @@ import Popover from 'src/components/popover/popover.vue'
import { useAdminSettingsStore } from 'src/stores/admin_settings.js'
import { useInstanceCapabilitiesStore } from 'src/stores/instance_capabilities.js'
-import { useUsersStore } from 'src/stores/users.js'
import { library } from '@fortawesome/fontawesome-svg-core'
import { faChevronDown } from '@fortawesome/free-solid-svg-icons'
@@ -406,7 +405,7 @@ const ModerationTools = {
)
},
isAdmin() {
- return useUsersStore().currentUser.role === 'admin'
+ return this.$store.state.users.currentUser.role === 'admin'
},
},
methods: {
@@ -453,7 +452,7 @@ const ModerationTools = {
},
privileged(privilege) {
if (this.isAdmin) return true
- return useUsersStore().currentUser.privileges.has(privilege)
+ return this.$store.state.users.currentUser.privileges.has(privilege)
},
setTag(tag, value) {
useAdminSettingsStore().setUsersTags({
@@ -517,7 +516,8 @@ const ModerationTools = {
setOpen(value) {
this.open = value
},
- maybeShowConfirm({ group, name, action, value }) {
+ maybeShowConfirm(close, { group, name, action, value }) {
+ close()
this.confirmDialogName = name
this.confirmDialogGroup = group
this.confirmDialogAction = () => action()
diff --git a/src/components/moderation_tools/moderation_tools.vue b/src/components/moderation_tools/moderation_tools.vue
index e3da1a84d..4da0be0ee 100644
--- a/src/components/moderation_tools/moderation_tools.vue
+++ b/src/components/moderation_tools/moderation_tools.vue
@@ -9,7 +9,7 @@
@show="setOpen(true)"
@close="setOpen(false)"
>
-
+