diff --git a/src/components/chat_message/chat_message.js b/src/components/chat_message/chat_message.js
index aabdec31f..5d086aade 100644
--- a/src/components/chat_message/chat_message.js
+++ b/src/components/chat_message/chat_message.js
@@ -1,6 +1,5 @@
-import { mapState as mapPiniaState } from 'pinia'
+import { mapState } 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'
@@ -20,6 +19,8 @@ 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 {
@@ -79,7 +80,7 @@ const ChatMessage = {
return this.isStatus ? this.message.user.id : this.message.account_id
},
author() {
- return this.$store.getters.findUser(this.authorId)
+ return useUsersStore().findUser(this.authorId)
},
isCurrentUser() {
// mini-hack/optimizaiton:
@@ -100,25 +101,21 @@ const ChatMessage = {
return !this.message.in_reply_to_status_id
},
customReplyTo() {
- return this.$store.state.statuses.allStatusesObject[
- this.message.in_reply_to_status_id
- ]
+ return useStatusesStore().allStatuses.get(
+ 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 = this.$store.getters.findUser(
- this.message.in_reply_to_user_id,
- )
+ const user = useUsersStore().findUser(this.message.in_reply_to_user_id)
return user?.screen_name_ui
}
},
replyProfileLink() {
if (this.isCustomReply) {
- const user = this.$store.getters.findUser(
- this.message.in_reply_to_user_id,
- )
+ const user = useUsersStore().findUser(this.message.in_reply_to_user_id)
// FIXME Why user not found sometimes???
return user ? user.statusnet_profile_url : 'NOT_FOUND'
}
@@ -167,14 +164,12 @@ const ChatMessage = {
},
// Global stuff
- ...mapPiniaState(useInterfaceStore, {
+ ...mapState(useInterfaceStore, {
betterShadow: (store) => store.browserSupport.cssFilter,
}),
- ...mapState({
- currentUser: (state) => state.users.currentUser,
- restrictedNicknames: (state) => useInstanceStore().restrictedNicknames,
- }),
- ...mapPiniaState(useMergedConfigStore, ['mergedConfig']),
+ ...mapState(useUsersStore, ['currentUser']),
+ ...mapState(useInstanceStore, ['restrictedNicknames']),
+ ...mapState(useMergedConfigStore, ['mergedConfig']),
},
data() {
return {
diff --git a/src/components/chat_message/chat_message.vue b/src/components/chat_message/chat_message.vue
index 88ab2fc0a..a6700201d 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']),
+ ...mapState(useUsersStore, ['currentUser', 'findUser']),
},
methods: {
goBack() {
@@ -73,7 +71,8 @@ const chatNew = {
this.loading = true
this.userIds = []
this.$store
- .dispatch('search', { q: query, resolve: true, type: 'accounts' })
+ this.useSearchStore()
+ .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 905a32d85..cae9064d2 100644
--- a/src/components/chat_title/chat_title.vue
+++ b/src/components/chat_title/chat_title.vue
@@ -10,7 +10,7 @@
>
store.layoutType === 'mobile',
}),
- ...mapPiniaState(useMergedConfigStore, ['mergedConfig']),
- ...mapState({
- mastoUserSocketStatus: (state) => state.api.mastoUserSocketStatus,
- currentUser: (state) => state.users.currentUser,
- }),
+ ...mapState(useMergedConfigStore, ['mergedConfig']),
+ ...mapState(useUsersStore, ['currentUser']),
},
watch: {
messages(old, neu) {
@@ -226,16 +231,85 @@ const Chat = {
return
}
- this.clear()
- this.startFetching()
- },
- mastoUserSocketStatus(newValue) {
- if (newValue === WSConnectionStatus.JOINED) {
- this.fetchChat({ isFirstFetch: true })
- }
+ this.deactivate()
+ this.activate()
},
},
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
@@ -259,18 +333,8 @@ const Chat = {
this.lastReadMessageId = this.maxId
this.newMessageCount = 0
},
- scrollDown(options = {}) {
- const { behavior = 'auto', forceRead = false } = options
- this.$nextTick(() => {
- window.scrollTo({
- top: document.documentElement.scrollHeight,
- behavior,
- })
- })
- if (forceRead) {
- this.readChat()
- }
- },
+
+ // Clears
cullOlder() {
const maxIndex = this.messages.length
const minIndex = maxIndex - 50
@@ -366,35 +430,12 @@ const Chat = {
})
}
},
- 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,
+ onStreamMessage({ data }) {
+ const messages = data.filter(
+ ({ statusnet_conversation_id }) =>
+ statusnet_conversation_id === this.conversationId,
)
- this.fetchChat({ isFirstFetch: true })
+ this.addMessages({ messages })
},
addMessages({ messages: newMessages }) {
for (let i = 0; i < newMessages.length; i++) {
@@ -438,9 +479,6 @@ const Chat = {
}
}
},
- goBack() {
- this.$router.back()
- },
// Optimistic posting (chats only)
async sendMessage({ status, media, idempotencyKey }) {
@@ -538,11 +576,14 @@ const Chat = {
// Event handlers
onPosted(data) {
- this.explicitReplyStatus = null
- this.$router.push({
- name: 'conversation2',
- params: { statusId: data.id },
- })
+ // only conversation poster has the returned data
+ if (this.isConversation) {
+ this.explicitReplyStatus = null
+ this.$router.push({
+ name: 'conversation2',
+ params: { statusId: data.id },
+ })
+ }
},
handleVisibilityChange() {
this.$nextTick(() => {
@@ -618,6 +659,23 @@ 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 c2f5ff888..2247c2e91 100644
--- a/src/components/confirm_modal/mute_confirm.js
+++ b/src/components/confirm_modal/mute_confirm.js
@@ -4,6 +4,8 @@ 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'],
@@ -33,9 +35,7 @@ export default {
return this.status.conversation_muted
},
domainIsMuted() {
- return new Set(this.$store.state.users.currentUser.domainMutes).has(
- this.domain,
- )
+ return new Set(useUsersStore().currentUser.domainMutes).has(this.domain)
},
shouldConfirm() {
switch (this.type) {
@@ -70,17 +70,17 @@ export default {
switch (this.type) {
case 'domain': {
if (!this.domainIsMuted) {
- this.$store.dispatch('muteDomain', this.domain)
+ useUsersStore().muteDomain(this.domain)
} else {
- this.$store.dispatch('unmuteDomain', this.domain)
+ useUsersStore().unmuteDomain(this.domain)
}
break
}
case 'conversation': {
if (!this.conversationIsMuted) {
- this.$store.dispatch('muteConversation', { id: this.status.id })
+ useStatusesStore().muteConversation(this.status.id)
} else {
- this.$store.dispatch('unmuteConversation', { id: this.status.id })
+ useStatusesStore().unmuteConversation(this.status.id)
}
break
}
diff --git a/src/components/conversation/conversation.js b/src/components/conversation/conversation.js
index ea5637944..cc4aecfe3 100644
--- a/src/components/conversation/conversation.js
+++ b/src/components/conversation/conversation.js
@@ -1,4 +1,4 @@
-import { clone, filter, findIndex, get, reduce } from 'lodash'
+import { get, reduce } from 'lodash'
import { mapState as mapPiniaState } from 'pinia'
import { mapState } from 'vuex'
@@ -9,9 +9,10 @@ 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'
+import { useInterfaceStore } from 'src/stores/interface.js'
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'
@@ -51,20 +52,6 @@ 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: {
@@ -122,6 +109,9 @@ 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"
@@ -165,9 +155,6 @@ 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
@@ -187,15 +174,13 @@ const conversation = {
return [this.status]
}
- const conversation = clone(
- this.$store.state.statuses.conversationsObject[this.conversationId],
+ const conversation = useStatusesStore().conversations.get(
+ this.conversationId,
)
- const statusIndex = findIndex(conversation, { id: this.originalStatusId })
- if (statusIndex !== -1) {
- conversation[statusIndex] = this.status
- }
- return sortAndFilterConversation(conversation, this.status)
+ return [...conversation.keys()]
+ .map((k) => useStatusesStore().allStatuses.get(k))
+ .toSorted(sortById)
},
statusMap() {
return this.conversation.reduce((res, s) => {
@@ -441,7 +426,7 @@ const conversation = {
}
},
virtualHidden() {
- this.$store.dispatch('setVirtualHeight', {
+ useStatusesStore().setVirtualHeight({
statusId: this.statusId,
height: `${this.$el.clientHeight}px`,
})
@@ -453,9 +438,12 @@ const conversation = {
fetchConversation({
id: this.statusId,
credentials: useOAuthStore().token,
- }).then(({ data: { ancestors, descendants } }) => {
- this.$store.dispatch('addNewStatuses', { statuses: ancestors })
- this.$store.dispatch('addNewStatuses', { statuses: descendants })
+ }).then(({ data: { ancestors, descendants }, timestamp }) => {
+ useStatusesStore().addNewStatuses({ statuses: ancestors, timestamp })
+ useStatusesStore().addNewStatuses({
+ statuses: descendants,
+ timestamp,
+ })
this.setFocused(this.originalStatusId)
})
} else {
@@ -465,7 +453,7 @@ const conversation = {
credentials: useOAuthStore().token,
})
.then(({ data: status }) => {
- this.$store.dispatch('addNewStatuses', { statuses: [status] })
+ useStatusesStore().addNewStatuses({ statuses: [status] })
this.fetchConversation()
})
.catch((error) => {
@@ -482,17 +470,17 @@ const conversation = {
this.focused = id
if (!this.streamingEnabled) {
- this.$store.dispatch('fetchStatus', id)
+ useStatusesStore().fetchStatus(id)
}
- this.$store.dispatch('fetchFavsAndRepeats', id)
- this.$store.dispatch('fetchEmojiReactionsBy', id)
+ useStatusesStore().fetchFavsAndRepeats(id)
+ useStatusesStore().fetchEmojiReactions(id)
},
toggleExpanded() {
this.expanded = !this.expanded
},
getConversationId(statusId) {
- const status = this.$store.state.statuses.allStatusesObject[statusId]
+ const status = useStatusesStore().allStatuses.get(statusId)
return get(
status,
'retweeted_status.statusnet_conversation_id',
diff --git a/src/components/conversation/conversation.vue b/src/components/conversation/conversation.vue
index 0833c4f89..ae6e3a0ce 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"
- :statusoid="status"
+ :status-id="status.id"
:replies="getReplies(status.id)"
:expandable="!isExpanded"
@@ -152,7 +152,7 @@
ref="statusComponent"
:depth="0"
- :status="status"
+ :status-id="status.id"
:in-profile="inProfile"
:conversation="conversation"
:collapsable="collapsable"
@@ -186,7 +186,7 @@
:key="status.id"
ref="statusComponent"
class="conversation-status status-fadein panel-body"
- :statusoid="status"
+ :status-id="status.id"
: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 cc2c5aca9..32d0b37a9 100644
--- a/src/components/desktop_nav/desktop_nav.js
+++ b/src/components/desktop_nav/desktop_nav.js
@@ -5,6 +5,10 @@ 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 {
@@ -14,6 +18,8 @@ import {
faComments,
faHome,
faInfoCircle,
+ faPlug,
+ faPlugCircleXmark,
faSearch,
faSignInAlt,
faSignOutAlt,
@@ -33,6 +39,8 @@ library.add(
faTachometerAlt,
faCog,
faInfoCircle,
+ faPlug,
+ faPlugCircleXmark,
)
export default {
@@ -91,11 +99,23 @@ export default {
sitename: (store) => store.instanceIdentity.name,
hideSitename: (store) => store.instanceIdentity.hideSitename,
}),
- currentUser() {
- return this.$store.state.users.currentUser
- },
+ ...mapState(useUsersStore, ['currentUser']),
+ ...mapState(useStreamingStore, {
+ streamingConnected: (store) => store.state === WSConnectionStatus.JOINED,
+ }),
+ ...mapState(useMergedConfigStore, ['mergedConfig']),
shouldConfirmLogout() {
- return useMergedConfigStore().mergedConfig.modalOnLogout
+ 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')
+ }
},
},
methods: {
@@ -117,7 +137,7 @@ export default {
},
doLogout() {
this.$router.replace('/main/public')
- this.$store.dispatch('logout')
+ useUsersStore().logout()
this.hideConfirmLogout()
},
onSearchBarToggled(hidden) {
diff --git a/src/components/desktop_nav/desktop_nav.vue b/src/components/desktop_nav/desktop_nav.vue
index 3883b3c6f..52370a57f 100644
--- a/src/components/desktop_nav/desktop_nav.vue
+++ b/src/components/desktop_nav/desktop_nav.vue
@@ -15,6 +15,24 @@
>
{{ sitename }}
+
+
+
+
-
-
-
-
diff --git a/src/components/domain_mute_card/domain_mute_card.js b/src/components/domain_mute_card/domain_mute_card.js
index d83896618..274679b8d 100644
--- a/src/components/domain_mute_card/domain_mute_card.js
+++ b/src/components/domain_mute_card/domain_mute_card.js
@@ -1,5 +1,7 @@
import ProgressButton from 'src/components/progress_button/progress_button.vue'
+import { useUsersStore } from 'src/stores/users.js'
+
const DomainMuteCard = {
props: ['domain'],
components: {
@@ -7,7 +9,7 @@ const DomainMuteCard = {
},
computed: {
user() {
- return this.$store.state.users.currentUser
+ return useUsersStore().currentUser
},
muted() {
return this.user.domainMutes.includes(this.domain)
@@ -15,10 +17,10 @@ const DomainMuteCard = {
},
methods: {
unmuteDomain() {
- return this.$store.dispatch('unmuteDomain', this.domain)
+ return useUsersStore().unmuteDomain(this.domain)
},
muteDomain() {
- return this.$store.dispatch('muteDomain', this.domain)
+ return useUsersStore().muteDomain(this.domain)
},
},
}
diff --git a/src/components/draft/draft.js b/src/components/draft/draft.js
index 49e186eae..1c7f419c6 100644
--- a/src/components/draft/draft.js
+++ b/src/components/draft/draft.js
@@ -6,6 +6,7 @@ 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'
@@ -65,7 +66,7 @@ const Draft = {
},
refStatus() {
return this.draft.refId
- ? this.$store.state.statuses.allStatusesObject[this.draft.refId]
+ ? useStatusesStore().allStatuses.get(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 59c142d08..12072d7a2 100644
--- a/src/components/edit_status_modal/edit_status_modal.js
+++ b/src/components/edit_status_modal/edit_status_modal.js
@@ -4,6 +4,7 @@ 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: {
@@ -19,7 +20,7 @@ const EditStatusModal = {
},
computed: {
isLoggedIn() {
- return !!this.$store.state.users.currentUser
+ return !!useUsersStore().currentUser
},
modalActivated() {
return useEditStatusStore().modalActivated
diff --git a/src/components/emoji_input/suggestor.js b/src/components/emoji_input/suggestor.js
index c31cb6717..6a7dbff9a 100644
--- a/src/components/emoji_input/suggestor.js
+++ b/src/components/emoji_input/suggestor.js
@@ -1,3 +1,5 @@
+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:
@@ -77,7 +79,7 @@ export const suggestUsers = ({ dispatch, state }) => {
let timeout = null
let cancelUserSearch = null
- const userSearch = (query) => dispatch('searchUsers', { query })
+ const userSearch = (query) => useSearchStore().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 acb5404c0..3077ed212 100644
--- a/src/components/emoji_reactions/emoji_reactions.js
+++ b/src/components/emoji_reactions/emoji_reactions.js
@@ -3,6 +3,8 @@ 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'
@@ -40,7 +42,7 @@ const EmojiReactions = {
}, {})
},
loggedIn() {
- return !!this.$store.state.users.currentUser
+ return !!useUsersStore().currentUser
},
remoteInteractionLink() {
return useInstanceStore().getRemoteInteractionLink({
@@ -58,25 +60,22 @@ const EmojiReactions = {
reactedWith(emoji) {
return this.status.emoji_reactions.find((r) => r.name === emoji).me
},
- async fetchEmojiReactionsByIfMissing() {
+ async fetchEmojiReactionsIfMissing() {
const hasNoAccounts = this.status.emoji_reactions.find((r) => !r.accounts)
- if (hasNoAccounts) {
- return await this.$store.dispatch(
- 'fetchEmojiReactionsBy',
- this.status.id,
- )
+ if (!hasNoAccounts) {
+ return await useStatusesStore().fetchEmojiReactions(this.status.id)
}
},
reactWith(emoji) {
- this.$store.dispatch('reactWithEmoji', { id: this.status.id, emoji })
+ useStatusesStore().reactWithEmoji(this.status.id, emoji)
},
unreact(emoji) {
- this.$store.dispatch('unreactWithEmoji', { id: this.status.id, emoji })
+ useStatusesStore().unreactWithEmoji(this.status.id, emoji)
},
async emojiOnClick(emoji) {
if (!this.loggedIn) return
- await this.fetchEmojiReactionsByIfMissing()
+ await this.fetchEmojiReactionsIfMissing()
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 16c69fa40..a8100c0d4 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="fetchEmojiReactionsByIfMissing()"
+ @show="fetchEmojiReactionsIfMissing()"
>
{{ reaction.count }}
diff --git a/src/components/extra_notifications/extra_notifications.js b/src/components/extra_notifications/extra_notifications.js
index 24ed074af..851656ae5 100644
--- a/src/components/extra_notifications/extra_notifications.js
+++ b/src/components/extra_notifications/extra_notifications.js
@@ -6,6 +6,7 @@ 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 {
@@ -52,7 +53,7 @@ const ExtraNotifications = {
)
},
currentUser() {
- return this.$store.state.users.currentUser
+ return useUsersStore().currentUser
},
...mapGetters(['followRequestCount']),
...mapState(useAnnouncementsStore, {
diff --git a/src/components/follow_button/follow_button.js b/src/components/follow_button/follow_button.js
index 3fecc025f..e4d243ff9 100644
--- a/src/components/follow_button/follow_button.js
+++ b/src/components/follow_button/follow_button.js
@@ -1,11 +1,8 @@
import { defineAsyncComponent } from 'vue'
-import {
- requestFollow,
- requestUnfollow,
-} from '../../services/follow_manipulate/follow_manipulate'
-
import { useMergedConfigStore } from 'src/stores/merged_config.js'
+import { useUsersStore } from 'src/stores/users.js'
+
export default {
props: ['relationship', 'user', 'labelFollowing', 'buttonClass'],
components: {
@@ -64,9 +61,11 @@ export default {
},
follow() {
this.inProgress = true
- requestFollow(this.relationship.id, this.$store).then(() => {
- this.inProgress = false
- })
+ useUsersStore()
+ .followUser(this.relationship.id)
+ .finally(() => {
+ this.inProgress = false
+ })
},
unfollow() {
if (this.shouldConfirmUnfollow) {
@@ -76,15 +75,12 @@ export default {
}
},
doUnfollow() {
- const store = this.$store
this.inProgress = true
- requestUnfollow(this.relationship.id, store).then(() => {
- this.inProgress = false
- store.commit('removeStatus', {
- timeline: 'friends',
- userId: this.relationship.id,
+ useUsersStore()
+ .unfollowUser(this.relationship.id)
+ .finally(() => {
+ this.inProgress = false
})
- })
this.hideConfirmUnfollow()
},
diff --git a/src/components/follow_card/follow_card.js b/src/components/follow_card/follow_card.js
index 8fffbf730..9a8b8746f 100644
--- a/src/components/follow_card/follow_card.js
+++ b/src/components/follow_card/follow_card.js
@@ -3,6 +3,8 @@ 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: {
@@ -13,13 +15,13 @@ const FollowCard = {
},
computed: {
isMe() {
- return this.$store.state.users.currentUser.id === this.user.id
+ return useUsersStore().currentUser.id === this.user.id
},
loggedIn() {
- return this.$store.state.users.currentUser
+ return useUsersStore().currentUser
},
relationship() {
- return this.$store.getters.relationship(this.user.id)
+ return useUsersStore().relationships.get(this.user.id)
},
},
}
diff --git a/src/components/follow_card/follow_card.vue b/src/components/follow_card/follow_card.vue
index bdb6b8092..d9a508a95 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 294dd2472..c4b43811a 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 = notificationsFromStore(this.$store).find(
+ const notif = useNotificationsStore().data.find(
(notif) =>
notif.from_profile.id === this.user.id &&
notif.type === 'follow_request',
@@ -55,16 +55,11 @@ const FollowRequestCard = {
id: this.user.id,
credentials: useOAuthStore().token,
})
+ // TODO fix
this.$store.dispatch('removeFollowRequest', this.user)
const notifId = this.findFollowRequestNotificationId()
- this.$store.dispatch('markSingleNotificationAsSeen', { id: notifId })
- this.$store.dispatch('updateNotification', {
- id: notifId,
- updater: (notification) => {
- notification.type = 'follow'
- },
- })
+ useNotificationsStore().markSingleNotificationAsSeen(notifId)
this.hideApproveConfirmDialog()
},
denyUser() {
@@ -81,7 +76,8 @@ const FollowRequestCard = {
id: this.user.id,
credentials: useOAuthStore().token,
}).then(() => {
- this.$store.dispatch('dismissNotificationLocal', { id: notifId })
+ useNotificationsStore().dismissNotificationLocal(notifId)
+ // TODO fix
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
deleted file mode 100644
index b6bee7305..000000000
--- a/src/components/friends_timeline/friends_timeline.js
+++ /dev/null
@@ -1,14 +0,0 @@
-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
deleted file mode 100644
index 01a568123..000000000
--- a/src/components/friends_timeline/friends_timeline.vue
+++ /dev/null
@@ -1,9 +0,0 @@
-
-
-
-
-
diff --git a/src/components/interactions/interactions.js b/src/components/interactions/interactions.js
index d008c4b30..37873605f 100644
--- a/src/components/interactions/interactions.js
+++ b/src/components/interactions/interactions.js
@@ -1,6 +1,8 @@
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'],
@@ -14,10 +16,9 @@ const tabModeDict = {
const Interactions = {
data() {
return {
- allowFollowingMove:
- this.$store.state.users.currentUser.allow_following_move,
+ allowFollowingMove: useUsersStore().currentUser.allow_following_move,
filterMode: tabModeDict.mentions,
- canSeeReports: this.$store.state.users.currentUser.privileges.has(
+ canSeeReports: useUsersStore().currentUser.privileges.has(
'reports_manage_reports',
),
}
diff --git a/src/components/list/list.js b/src/components/list/list.js
index c7b924258..20b7c5a78 100644
--- a/src/components/list/list.js
+++ b/src/components/list/list.js
@@ -98,12 +98,13 @@ const List = {
this.fetchFunction(this.page)
.then((result) => {
+ console.log(result)
this.loading = false
- this.bottomedOut = isEmpty(result.items)
+ this.bottomedOut = isEmpty(result)
if (this.externalItems) return
this.page += 1
- this.total = result.count
- this.items.push(...result.items)
+ this.total = result.length
+ this.items.push(...result)
})
.catch((error) => {
this.loading = false
diff --git a/src/components/lists_edit/lists_edit.js b/src/components/lists_edit/lists_edit.js
index 7eb035091..cea9236a5 100644
--- a/src/components/lists_edit/lists_edit.js
+++ b/src/components/lists_edit/lists_edit.js
@@ -1,5 +1,4 @@
-import { mapState as mapPiniaState } from 'pinia'
-import { mapGetters, mapState } from 'vuex'
+import { mapState } from 'pinia'
import BasicUserCard from 'src/components/basic_user_card/basic_user_card.vue'
import ListsUserSearch from 'src/components/lists_user_search/lists_user_search.vue'
@@ -9,6 +8,7 @@ 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((userId) => {
- this.$store.dispatch('fetchUserIfMissing', userId)
+ this.membersUserIds.forEach((id) => {
+ useUsersStore().fetchUserIfMissing({ id })
})
})
},
@@ -66,11 +66,8 @@ const ListsNew = {
.map((userId) => this.findUser(userId))
.filter(Boolean)
},
- ...mapState({
- currentUser: (state) => state.users.currentUser,
- }),
- ...mapPiniaState(useListsStore, ['findListTitle', 'findListAccounts']),
- ...mapGetters(['findUser']),
+ ...mapState(useUsersStore, ['currentUser', 'findUser']),
+ ...mapState(useListsStore, ['findListTitle', 'findListAccounts']),
},
methods: {
onInput() {
diff --git a/src/components/lists_menu/lists_menu_content.js b/src/components/lists_menu/lists_menu_content.js
index 337ee4d4f..7c422d033 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 as mapPiniaState } from 'pinia'
-import { mapState } from 'vuex'
+import { mapState } from 'pinia'
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,12 +12,10 @@ export const ListsMenuContent = {
NavigationEntry,
},
computed: {
- ...mapPiniaState(useListsStore, {
+ ...mapState(useListsStore, {
lists: getListEntries,
}),
- ...mapState({
- currentUser: (state) => state.users.currentUser,
- }),
+ ...mapState(useUsersStore, ['currentUser']),
},
}
diff --git a/src/components/lists_timeline/lists_timeline.js b/src/components/lists_timeline/lists_timeline.js
deleted file mode 100644
index a06220a37..000000000
--- a/src/components/lists_timeline/lists_timeline.js
+++ /dev/null
@@ -1,47 +0,0 @@
-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
deleted file mode 100644
index 18156b812..000000000
--- a/src/components/lists_timeline/lists_timeline.vue
+++ /dev/null
@@ -1,10 +0,0 @@
-
-
-
-
-
diff --git a/src/components/lists_user_search/lists_user_search.js b/src/components/lists_user_search/lists_user_search.js
index aed3f1ce7..5ac6e679a 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.$store
- .dispatch('search', {
+ this.useSearchStore()
+ .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 0309079e8..374e62259 100644
--- a/src/components/mention_link/mention_link.js
+++ b/src/components/mention_link/mention_link.js
@@ -1,5 +1,4 @@
-import { mapState as mapPiniaState } from 'pinia'
-import { mapState } from 'vuex'
+import { mapState } from 'pinia'
import UnicodeDomainIndicator from 'src/components/unicode_domain_indicator/unicode_domain_indicator.vue'
import UserAvatar from 'src/components/user_avatar/user_avatar.vue'
@@ -12,6 +11,7 @@ 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 && this.$store?.getters.findUserByUrl(this.url)
+ return this.url && useUsersStore().findUserByUrl(this.url)
},
isYou() {
// FIXME why user !== currentUser???
@@ -156,11 +156,9 @@ const MentionLink = {
shouldFadeDomain() {
return this.mergedConfig.mentionLinkFadeDomain
},
- ...mapPiniaState(useMergedConfigStore, ['mergedConfig']),
- ...mapPiniaState(useUserHighlightStore, ['highlight']),
- ...mapState({
- currentUser: (state) => state.users.currentUser,
- }),
+ ...mapState(useMergedConfigStore, ['mergedConfig']),
+ ...mapState(useUserHighlightStore, ['highlight']),
+ ...mapState(useUsersStore, ['currentUser']),
},
}
diff --git a/src/components/mention_link/mention_link.vue b/src/components/mention_link/mention_link.vue
index 0452cad58..33f0d9db7 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 4eb956f64..163c0e9aa 100644
--- a/src/components/mobile_nav/mobile_nav.js
+++ b/src/components/mobile_nav/mobile_nav.js
@@ -5,13 +5,15 @@ import NavigationPins from 'src/components/navigation/navigation_pins.vue'
import GestureService from '../../services/gesture_service/gesture_service'
import {
countExtraNotifications,
- unseenNotificationsFromStore,
+ unseenNotifications,
} 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 {
@@ -53,11 +55,10 @@ const MobileNav = {
},
computed: {
currentUser() {
- return this.$store.state.users.currentUser
+ return useUsersStore().currentUser
},
unseenNotifications() {
- return unseenNotificationsFromStore(
- this.$store,
+ return unseenNotifications(
useMergedConfigStore().mergedConfig.notificationVisibility,
useMergedConfigStore().mergedConfig.ignoreInactionableSeen,
)
@@ -145,11 +146,11 @@ const MobileNav = {
},
doLogout() {
this.$router.replace('/main/public')
- this.$store.dispatch('logout')
+ useUsersStore().logout()
this.hideConfirmLogout()
},
markNotificationsAsSeen() {
- this.$store.dispatch('markNotificationsAsSeen')
+ useNotificationsStore().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 4969352f6..d137331c9 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,6 +2,7 @@ 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'
@@ -34,7 +35,7 @@ const MobilePostStatusButton = {
},
computed: {
isLoggedIn() {
- return !!this.$store.state.users.currentUser
+ return useUsersStore().loggedIn
},
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 ba13afc8b..9b948e306 100644
--- a/src/components/moderation_tools/moderation_tools.js
+++ b/src/components/moderation_tools/moderation_tools.js
@@ -5,6 +5,7 @@ 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'
@@ -405,7 +406,7 @@ const ModerationTools = {
)
},
isAdmin() {
- return this.$store.state.users.currentUser.role === 'admin'
+ return useUsersStore().currentUser.role === 'admin'
},
},
methods: {
@@ -452,7 +453,7 @@ const ModerationTools = {
},
privileged(privilege) {
if (this.isAdmin) return true
- return this.$store.state.users.currentUser.privileges.has(privilege)
+ return useUsersStore().currentUser.privileges.has(privilege)
},
setTag(tag, value) {
useAdminSettingsStore().setUsersTags({
@@ -516,8 +517,7 @@ const ModerationTools = {
setOpen(value) {
this.open = value
},
- maybeShowConfirm(close, { group, name, action, value }) {
- close()
+ maybeShowConfirm({ group, name, action, value }) {
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 4da0be0ee..e3da1a84d 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)"
>
-
+