This commit is contained in:
Henry Jameson 2026-08-13 01:22:44 +03:00
commit c13ee07530
7 changed files with 33 additions and 106 deletions

View file

@ -1,4 +1,4 @@
import { debounce, keyBy, throttle } from 'lodash'
import { debounce, throttle } from 'lodash'
import { mapState } from 'pinia'
import Conversation from 'src/components/conversation/conversation.vue'
@ -9,9 +9,7 @@ import TimelineMenu from 'src/components/timeline_menu/timeline_menu.vue'
import { useInterfaceStore } from 'src/stores/interface.js'
import { useMergedConfigStore } from 'src/stores/merged_config.js'
import { useStatusesStore } from 'src/stores/statuses.js'
import { useTimelinesStore } from 'src/stores/timelines.js'
import { useUsersStore } from 'src/stores/users.js'
import { library } from '@fortawesome/fontawesome-svg-core'
import {

View file

@ -1,32 +1,15 @@
import { Socket } from 'phoenix'
import { maybeShowChatNotification } from '../services/chat_utils/chat_utils.js'
import { useChatsStore } from 'src/stores/chats.js'
import { useInstanceCapabilitiesStore } from 'src/stores/instance_capabilities.js'
import { useInterfaceStore } from 'src/stores/interface.js'
import { useNotificationsStore } from 'src/stores/notifications.js'
import { useOAuthStore } from 'src/stores/oauth.js'
import { useShoutStore } from 'src/stores/shout.js'
import { useStatusesStore } from 'src/stores/statuses.js'
import {
getMastodonSocketURI,
ProcessedWS,
WSConnectionStatus,
} from 'src/api/websocket.js'
import followRequestFetcher from 'src/services/follow_request_fetcher/follow_request_fetcher.service'
import notificationsFetcher from 'src/services/notifications_fetcher/notifications_fetcher.service.js'
const retryTimeout = (multiplier) => 1000 * multiplier
const api = {
state: {
retryMultiplier: 1,
fetchers: {},
socket: null,
mastoUserSocket: null,
mastoUserSocketStatus: null,
followRequests: [],
},
getters: {
@ -49,61 +32,8 @@ const api = {
setFollowRequests(state, value) {
state.followRequests = value
},
setMastoUserSocketStatus(state, value) {
state.mastoUserSocketStatus = value
},
incrementRetryMultiplier(state) {
state.retryMultiplier = Math.max(++state.retryMultiplier, 3)
},
resetRetryMultiplier(state) {
state.retryMultiplier = 1
},
},
actions: {
/**
* Global MastoAPI socket control, in future should disable ALL sockets/(re)start relevant sockets
*
* @param {Boolean} [initial] - whether this enabling happened at boot time or not
*/
enableMastoSockets(store, initial) {
const { state, dispatch, commit } = store
// Do not initialize unless nonexistent or closed
if (
state.mastoUserSocket &&
![WebSocket.CLOSED, WebSocket.CLOSING].includes(
state.mastoUserSocket.getState(),
)
) {
return
}
if (initial) {
commit('setMastoUserSocketStatus', WSConnectionStatus.STARTING_INITIAL)
} else {
commit('setMastoUserSocketStatus', WSConnectionStatus.STARTING)
}
return dispatch('startMastoUserSocket')
},
disableMastoSockets(store) {
const { state, dispatch, commit } = store
if (!state.mastoUserSocket) return
commit('setMastoUserSocketStatus', WSConnectionStatus.DISABLED)
return dispatch('stopMastoUserSocket')
},
// Notifications
startFetchingNotifications(store) {
if (store.state.fetchers.notifications) return
const fetcher = notificationsFetcher.startFetching({
credentials: useOAuthStore().token,
})
store.commit('addFetcher', { fetcherName: 'notifications', fetcher })
},
stopFetchingNotifications(store) {
const fetcher = store.state.fetchers.notifications
if (!fetcher) return
store.commit('removeFetcher', { fetcherName: 'notifications', fetcher })
},
// Follow requests
startFetchingFollowRequests(store) {
if (store.state.fetchers.followRequests) return

View file

@ -1,5 +1,3 @@
import { camelCase } from 'lodash'
import { promiseInterval } from '../promise_interval/promise_interval.js'
import { useInstanceCapabilitiesStore } from 'src/stores/instance_capabilities.js'
@ -66,7 +64,7 @@ const fetchAndUpdate = (
.filter(Boolean)
useTimelinesStore().addStatusesToTimeline(timeline.name, argument, {
statuses,
statuses: processed,
showImmediately,
pagination,
})

View file

@ -3,13 +3,12 @@ import { defineStore } from 'pinia'
import { useInstanceCapabilitiesStore } from 'src/stores/instance_capabilities.js'
import { useInterfaceStore } from 'src/stores/interface.js'
import { useOAuthStore } from 'src/stores/oauth.js'
import { useUsersStore } from 'src/stores/users.js'
import { useStreamingStore } from 'src/stores/streaming.js'
import { useUsersStore } from 'src/stores/users.js'
import {
fetchEmojiReactions,
fetchFavoritedByUsers,
fetchPinnedStatuses,
fetchRebloggedByUsers,
fetchScrobbles,
fetchStatus,
@ -83,7 +82,6 @@ export const useStatusesStore = defineStore('statuses', {
attachSocket() {
const et = new EventTarget()
const handleStatusMessage = ({ data, timestamp }) => {
console.log('STATUSES', data)
this.addNewStatuses({ statuses: [data.status], timestamp })
}

View file

@ -56,11 +56,11 @@ export const useStreamingStore = defineStore('streaming', {
this.subscribers.add(subscriber)
if (this.state === WSConnectionStatus.JOINED) {
this.socket.subscribe(...this.getSubArgs(stream))
subscriber.et.dispatchEvent(new CustomEvent('open'))
et.dispatchEvent(new CustomEvent('open'))
}
},
removeSubscriber(subscriber) {
const { stream, et } = subscriber
const { stream } = subscriber
this.subscribers.delete(subscriber)
this.subscriptions.get(stream.name).delete(stream.argument)
@ -128,16 +128,15 @@ export const useStreamingStore = defineStore('streaming', {
const totalSubs = [
...this.globalSubscriptions.values(),
subscriber
subscriber,
].filter(Boolean)
totalSubs.forEach(({ stream, et }) => {
et.dispatchEvent(new CustomEvent(
eventName,
{
et.dispatchEvent(
new CustomEvent(eventName, {
detail: { streamName, streamArgument, data, timestamp },
}
))
}),
)
})
console.log('WS', message)

View file

@ -3,9 +3,9 @@ import { defineStore } from 'pinia'
import { useInstanceCapabilitiesStore } from 'src/stores/instance_capabilities.js'
import { useOAuthStore } from 'src/stores/oauth.js'
import { useUsersStore } from 'src/stores/users.js'
import { useStatusesStore } from 'src/stores/statuses.js'
import { useStreamingStore, TIMELINE_STREAM_MAP } from 'src/stores/streaming.js'
import { TIMELINE_STREAM_MAP, useStreamingStore } from 'src/stores/streaming.js'
import { useUsersStore } from 'src/stores/users.js'
import timelineFetcher from 'src/services/timeline_fetcher/timeline_fetcher.service.js'
@ -67,9 +67,7 @@ const TIMELINES = new Set([
])
export const defaultState = () => {
return Object.fromEntries(
[...TIMELINES].map((name) => [name, emptyTl(name)]),
)
return Object.fromEntries([...TIMELINES].map((name) => [name, emptyTl(name)]))
}
//const CUSTOM_SORT = new Set(['bookmarks', 'favorites'])
@ -150,7 +148,7 @@ export const useTimelinesStore = defineStore('timelines', {
},
activatePersistents() {
TIMELINES.forEach(name => {
TIMELINES.forEach((name) => {
if (this[name].persistent) {
this.activate(name, undefined, true)
}
@ -180,9 +178,15 @@ export const useTimelinesStore = defineStore('timelines', {
if (streamName) {
const et = new EventTarget()
et.addEventListener('open', () => this.onStreamConnect(timelineName, argument))
et.addEventListener('close', () => this.onStreamDisconnect(timelineName, argument))
et.addEventListener('update', ({ detail: message }) => this.onStreamMessage(timelineName, argument, message))
et.addEventListener('open', () =>
this.onStreamConnect(timelineName, argument),
)
et.addEventListener('close', () =>
this.onStreamDisconnect(timelineName, argument),
)
et.addEventListener('update', ({ detail: message }) =>
this.onStreamMessage(timelineName, argument, message),
)
timeline.socket = {
stream: {

View file

@ -23,9 +23,9 @@ import { useMergedConfigStore } from 'src/stores/merged_config.js'
import { useNotificationsStore } from 'src/stores/notifications.js'
import { useOAuthStore } from 'src/stores/oauth.js'
import { useStatusesStore } from 'src/stores/statuses.js'
import { useStreamingStore } from 'src/stores/streaming.js'
import { useSyncConfigStore } from 'src/stores/sync_config.js'
import { useTimelinesStore } from 'src/stores/timelines.js'
import { useStreamingStore } from 'src/stores/streaming.js'
import { useUserHighlightStore } from 'src/stores/user_highlight.js'
import { revokeToken } from 'src/api/oauth.js'
@ -134,7 +134,7 @@ export const useUsersStore = defineStore('users', {
saveFollowerIds(id, followerIds) {
const user = this.users.get(id)
const list = this.relationshipsLists.followers.get(user)
followersIds.forEach((id) => list.add(id))
followerIds.forEach((id) => list.add(id))
},
// Because frontend doesn't have a reason to keep these stuff in memory
// outside of viewing someones user profile.
@ -168,7 +168,6 @@ export const useUsersStore = defineStore('users', {
// implicit: if oldTimestamp is undefined this will still be false
if (oldTimestamp > timestamp) return existing // not overwriting old data with new
const { relationship: unused0, ...oldUser } = existing
const { relationship: unused1, ...newUser } = user
// Initializing reactivity
@ -463,7 +462,7 @@ export const useUsersStore = defineStore('users', {
return Promise.all(data.map((d) => unblockUser(d)))
},
editUserNote({ id, comment }) {
return editUserNote({ id, comment }).then((relationship) =>
return editUserNote({ id, comment }).then(({ data }) =>
this.updateUserRelationships(data),
)
},
@ -501,7 +500,7 @@ export const useUsersStore = defineStore('users', {
id,
expiresIn,
credentials: useOAuthStore().token,
}).then(({ data: relationship }) => {
}).then(({ data }) => {
this.updateUserRelationships(data)
this.addMuteId(id)
})
@ -514,7 +513,7 @@ export const useUsersStore = defineStore('users', {
data: [predictedRelationship],
})
return unmuteUser({ id }).then(({ data: relationship }) =>
return unmuteUser({ id }).then(({ data }) =>
this.updateUserRelationships(data),
)
},
@ -523,14 +522,14 @@ export const useUsersStore = defineStore('users', {
id,
reblogs: false,
credentials: useOAuthStore().token,
}).then(({ data: relationship }) => this.updateUserRelationships(data))
}).then(({ data }) => this.updateUserRelationships(data))
},
showReblogs(id) {
return followUser({
id,
reblogs: true,
credentials: useOAuthStore().token,
}).then(({ data: relationship }) => this.updateUserRelationships(data))
}).then(({ data }) => this.updateUserRelationships(data))
},
muteUsers(data = []) {
return Promise.all(data.map((d) => this.muteUser(d)))
@ -595,14 +594,14 @@ export const useUsersStore = defineStore('users', {
id,
notify: true,
credentials: useOAuthStore().token,
}).then(({ data: relationship }) => this.updateUserRelationships(data))
}).then(({ data }) => this.updateUserRelationships(data))
},
unsubscribeUser(id) {
return followUser({
id,
notify: false,
credentials: useOAuthStore().token,
}).then(({ data: relationship }) => this.updateUserRelationships(data))
}).then(({ data }) => this.updateUserRelationships(data))
},
registerPushNotifications() {
const token = this.currentUser.credentials
@ -660,6 +659,7 @@ export const useUsersStore = defineStore('users', {
store.dispatch('stopFetchingFollowRequests')
store.commit('clearNotifications')
useStatusesStore().resetStatuses()
useNotificationsStore().clearNotifications()
useChatsStore().resetChats()
oauth.clearToken()
Cookies.remove('__Host-pleroma_key', { path: '/' })