Merge branch 'users-statuses-pinia' into shigusegubu-themes3
This commit is contained in:
commit
c0bbb1a768
27 changed files with 227 additions and 97 deletions
|
|
@ -1 +0,0 @@
|
|||
If user avatars next to mentions are enabled it will show empty placeholder avatar next to label while user is being fetched, to avoid jumps
|
||||
|
|
@ -29,6 +29,7 @@ import {
|
|||
import routes from './routes'
|
||||
|
||||
import { useAuthFlowStore } from 'src/stores/auth_flow'
|
||||
import { useChatsStore } from 'src/stores/chats.js'
|
||||
import { useEmojiStore } from 'src/stores/emoji.js'
|
||||
import { useI18nStore } from 'src/stores/i18n'
|
||||
import { useInstanceStore } from 'src/stores/instance.js'
|
||||
|
|
@ -593,6 +594,7 @@ const afterStoreSetup = async ({ pinia, store, storageError, i18n }) => {
|
|||
useI18nStore().setI18n(i18n)
|
||||
|
||||
// Global WS handlers
|
||||
useChatsStore().attachSocket()
|
||||
useInterfaceStore().attachSocket()
|
||||
useStatusesStore().attachSocket()
|
||||
|
||||
|
|
|
|||
|
|
@ -89,14 +89,15 @@ const Chat = {
|
|||
fetcher: null,
|
||||
socket: null,
|
||||
streaming: false,
|
||||
fetching: true,
|
||||
errorLoadingChat: false,
|
||||
messageRetriers: {},
|
||||
idempotencyKeyIndex: {},
|
||||
}
|
||||
},
|
||||
created() {
|
||||
async created() {
|
||||
if (this.testMode) return
|
||||
this.activate()
|
||||
await this.activate()
|
||||
this.attachSocket()
|
||||
},
|
||||
mounted() {
|
||||
|
|
@ -243,10 +244,11 @@ const Chat = {
|
|||
accountId: this.chatUserId,
|
||||
credentials: useOAuthStore().token,
|
||||
})
|
||||
useUsersStore().addNewUsers(result)
|
||||
const { data } = result
|
||||
useUsersStore().addNewUsers({ ...result, data: data.account })
|
||||
data.account = useUsersStore().findUser(data.account.id)
|
||||
this.chat = data
|
||||
this.maxId = this.chat.lastMessage?.id
|
||||
} catch (e) {
|
||||
console.error('Error creating or getting a chat', e)
|
||||
this.errorLoadingChat = true
|
||||
|
|
@ -254,33 +256,38 @@ const Chat = {
|
|||
}
|
||||
|
||||
if (this.isConversation || this.chat) {
|
||||
this.startFetching('Chat activated', true)
|
||||
this.$nextTick(() => {
|
||||
this.scrollDown({ forceRead: true })
|
||||
})
|
||||
this.startFetching('Chat activated', true)
|
||||
}
|
||||
},
|
||||
deactivate() {
|
||||
this.clear()
|
||||
if (!this.streaming) {
|
||||
this.stopFetching()
|
||||
if (this.fetching) {
|
||||
this.stopFetching('Chat deactivated')
|
||||
}
|
||||
},
|
||||
attachSocket() {
|
||||
const et = new EventTarget()
|
||||
const socket = { et }
|
||||
const socket = {
|
||||
name: 'chatview',
|
||||
et,
|
||||
}
|
||||
|
||||
et.addEventListener('update', this.onStreamMessage)
|
||||
et.addEventListener('pleroma:chat_update', this.onChatUpdate)
|
||||
et.addEventListener('open', this.onStreamConnect)
|
||||
et.addEventListener('close', this.onStreamDisconnect)
|
||||
|
||||
useStreamingStore().addSubscriber(socket)
|
||||
this.socket = socket
|
||||
useStreamingStore().addSubscriber(this.socket)
|
||||
},
|
||||
detachSocket() {
|
||||
const { et } = this.socket
|
||||
|
||||
et.removeEventListener('update', this.onStreamMessage)
|
||||
et.removeEventListener('pleroma:chat_update', this.onChatUpdate)
|
||||
et.removeEventListener('open', this.onStreamConnect)
|
||||
et.removeEventListener('close', this.onStreamDisconnect)
|
||||
|
||||
|
|
@ -303,11 +310,13 @@ const Chat = {
|
|||
5000,
|
||||
)
|
||||
this.fetchChat({ isFirstFetch })
|
||||
this.fetching = true
|
||||
},
|
||||
stopFetching(reason) {
|
||||
console.debug('[Chat View] Stopped fetching', 'Reason:', reason)
|
||||
this.fetcher.stop()
|
||||
this.fetcher = null
|
||||
this.fetching = false
|
||||
},
|
||||
|
||||
// Actions
|
||||
|
|
@ -437,6 +446,10 @@ const Chat = {
|
|||
)
|
||||
this.addMessages({ messages })
|
||||
},
|
||||
onChatUpdate({ data: { chatUpdate } }) {
|
||||
const messages = [chatUpdate.lastMessage]
|
||||
this.addMessages({ messages })
|
||||
},
|
||||
addMessages({ messages: newMessages }) {
|
||||
for (let i = 0; i < newMessages.length; i++) {
|
||||
const message = newMessages[i]
|
||||
|
|
|
|||
|
|
@ -155,9 +155,9 @@ const conversation = {
|
|||
return this.otherRepliesButtonPosition === 'inside'
|
||||
},
|
||||
suspendable() {
|
||||
return this.unsuspendibleIds.size > 0
|
||||
return this.unsuspendibleIds.size === 0
|
||||
},
|
||||
hideStatus() {
|
||||
hide() {
|
||||
return this.virtualHidden && this.suspendable
|
||||
},
|
||||
originalStatusId() {
|
||||
|
|
@ -365,7 +365,6 @@ const conversation = {
|
|||
return !!(this.expanded || this.isPage)
|
||||
},
|
||||
hiddenStyle() {
|
||||
if (this.isExpanded || !this.virtualHidden) return {}
|
||||
return { height: this.virtualHeight + 'px' }
|
||||
},
|
||||
threadDisplayStatus() {
|
||||
|
|
@ -621,6 +620,7 @@ const conversation = {
|
|||
}
|
||||
},
|
||||
updateVirtualHeight() {
|
||||
if (this.hide) return // no updates when not rendering
|
||||
this.$nextTick(() => {
|
||||
this.virtualHeight = this.$refs.body.getBoundingClientRect().height
|
||||
this.$emit('update:virtualHeight', {
|
||||
|
|
|
|||
|
|
@ -1,7 +1,6 @@
|
|||
<template>
|
||||
<div
|
||||
v-if="!hideStatus"
|
||||
:style="hiddenStyle"
|
||||
v-if="!hide"
|
||||
class="Conversation"
|
||||
:class="{ '-expanded' : isExpanded, 'panel' : isExpanded }"
|
||||
>
|
||||
|
|
|
|||
|
|
@ -62,7 +62,7 @@ const EmojiReactions = {
|
|||
},
|
||||
async fetchEmojiReactionsIfMissing() {
|
||||
const hasNoAccounts = this.status.emoji_reactions.find((r) => !r.accounts)
|
||||
if (!hasNoAccounts) {
|
||||
if (hasNoAccounts) {
|
||||
return await useStatusesStore().fetchEmojiReactions(this.status.id)
|
||||
}
|
||||
},
|
||||
|
|
|
|||
|
|
@ -8,20 +8,15 @@
|
|||
:href="url"
|
||||
class="original"
|
||||
target="_blank"
|
||||
><!-- eslint-enable vue/no-v-html -->
|
||||
<UserAvatar
|
||||
v-if="shouldShowAvatar"
|
||||
class="mention-avatar"
|
||||
:user-id="null"
|
||||
/>
|
||||
<span v-html="content" />
|
||||
</a>
|
||||
v-html="content"
|
||||
/><!-- eslint-enable vue/no-v-html -->
|
||||
<UserPopover
|
||||
v-else
|
||||
:user-id="user.id"
|
||||
:disabled="!shouldShowTooltip"
|
||||
>
|
||||
<span
|
||||
v-if="user"
|
||||
class="new"
|
||||
:style="style"
|
||||
:class="classnames"
|
||||
|
|
|
|||
|
|
@ -121,10 +121,10 @@ const Notifications = {
|
|||
)
|
||||
},
|
||||
loading() {
|
||||
return useNotificationsStore().fetcher.loading.value
|
||||
return useNotificationsStore().fetcher.loading
|
||||
},
|
||||
bottomedOut() {
|
||||
return useNotificationsStore().fetcher.bottomedOut.value
|
||||
return useNotificationsStore().fetcher.bottomedOut
|
||||
},
|
||||
noHeading() {
|
||||
const { layoutType } = useInterfaceStore()
|
||||
|
|
|
|||
|
|
@ -119,7 +119,7 @@
|
|||
>
|
||||
<router-link
|
||||
class="list-item hashtag"
|
||||
:to="{ name: 'tag-timeline', params: { tag: hashtag.name } }"
|
||||
:to="{ name: 'tag-timeline', params: { id: hashtag.name } }"
|
||||
>
|
||||
<span class="name">
|
||||
#{{ hashtag.name }}
|
||||
|
|
|
|||
|
|
@ -128,7 +128,6 @@ const Status = {
|
|||
return {
|
||||
replying: false,
|
||||
unmuted: false,
|
||||
userExpanded: false,
|
||||
mediaPlaying: new Set(),
|
||||
error: null,
|
||||
headTailLinks: null,
|
||||
|
|
@ -524,9 +523,6 @@ const Status = {
|
|||
toggleMute() {
|
||||
this.unmuted = !this.unmuted
|
||||
},
|
||||
toggleUserExpanded() {
|
||||
this.userExpanded = !this.userExpanded
|
||||
},
|
||||
generateUserProfileLink(id, name) {
|
||||
return generateProfileLink(
|
||||
id,
|
||||
|
|
@ -576,6 +572,12 @@ const Status = {
|
|||
this.$emit('heightChange')
|
||||
},
|
||||
},
|
||||
unmuted() {
|
||||
this.$emit('heightChange')
|
||||
},
|
||||
error() {
|
||||
this.$emit('heightChange')
|
||||
},
|
||||
replying() {
|
||||
this.$emit('heightChange')
|
||||
},
|
||||
|
|
@ -604,7 +606,6 @@ const Status = {
|
|||
},
|
||||
isSuspendable: function (suspend) {
|
||||
this.$emit('suspendableStateChange', { id: this.status.id, suspend })
|
||||
this.$emit('heightChange')
|
||||
},
|
||||
},
|
||||
}
|
||||
|
|
|
|||
|
|
@ -549,6 +549,7 @@
|
|||
@posted="closeReplyForm"
|
||||
@draft-done="closeReplyForm"
|
||||
@close-accepted="closeReplyForm"
|
||||
@resize="$emit('heightChange')"
|
||||
/>
|
||||
</div>
|
||||
</template>
|
||||
|
|
|
|||
|
|
@ -239,7 +239,7 @@ const Timeline = {
|
|||
const bodyBRect = document.body.getBoundingClientRect()
|
||||
const height = Math.max(bodyBRect.height, -bodyBRect.y)
|
||||
if (
|
||||
!this.timeline.fetcher.loadingOlder.value &&
|
||||
!this.timeline.fetcher.loadingOlder &&
|
||||
window.innerHeight + window.pageYOffset >= height - 750
|
||||
) {
|
||||
this.fetchOlderStatuses()
|
||||
|
|
|
|||
|
|
@ -12,7 +12,7 @@ const UserAvatar = {
|
|||
props: {
|
||||
// UserID of a user to show avatar of
|
||||
userId: {
|
||||
required: false, // You can pass null to just render a placeholder
|
||||
required: true,
|
||||
type: String,
|
||||
},
|
||||
// Use less space and use alternative roundness
|
||||
|
|
|
|||
|
|
@ -70,7 +70,6 @@
|
|||
|
||||
&.-placeholder {
|
||||
background-color: var(--background);
|
||||
border: 1px solid var(--border)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -30,8 +30,8 @@ function showWhoToFollow(panel, reply) {
|
|||
})
|
||||
}
|
||||
|
||||
function getWhoToFollow(panel) {
|
||||
const credentials = panel.$useUsersStore().currentUser.credentials
|
||||
function getWhoToFollow() {
|
||||
const credentials = useOAuthStore().token
|
||||
if (credentials) {
|
||||
panel.usersToFollow.forEach((toFollow) => {
|
||||
toFollow.name = 'Loading...'
|
||||
|
|
@ -66,7 +66,7 @@ const WhoToFollowPanel = {
|
|||
watch: {
|
||||
user: function () {
|
||||
if (this.suggestionsEnabled) {
|
||||
getWhoToFollow(this)
|
||||
getWhoToFollow()
|
||||
}
|
||||
},
|
||||
},
|
||||
|
|
@ -77,7 +77,7 @@ const WhoToFollowPanel = {
|
|||
id: 0,
|
||||
}))
|
||||
if (this.suggestionsEnabled) {
|
||||
getWhoToFollow(this)
|
||||
getWhoToFollow()
|
||||
}
|
||||
},
|
||||
}
|
||||
|
|
|
|||
|
|
@ -11,13 +11,14 @@ export const maybeShowChatNotification = (chat) => {
|
|||
title: chat.account.name,
|
||||
icon: chat.account.profile_image_url,
|
||||
body: chat.lastMessage.content,
|
||||
type: 'chatMention',
|
||||
}
|
||||
|
||||
if (chat.lastMessage.attachment?.type === 'image') {
|
||||
opts.image = chat.lastMessage.attachment.preview_url
|
||||
}
|
||||
|
||||
showDesktopNotification(window.vuex.state, opts)
|
||||
showDesktopNotification(opts)
|
||||
}
|
||||
|
||||
export const buildFakeMessage = ({
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@ import { map } from 'lodash'
|
|||
|
||||
import { useStatusesStore } from 'src/stores/statuses.js'
|
||||
import { useTimelinesStore } from 'src/stores/timelines.js'
|
||||
import { useUsersStore } from 'src/stores/users.js'
|
||||
import { useOAuthStore } from 'src/stores/oauth.js'
|
||||
|
||||
import {
|
||||
editStatus as apiEditStatus,
|
||||
|
|
@ -28,7 +28,7 @@ const postStatus = ({
|
|||
const mediaIds = map(media, 'id')
|
||||
|
||||
return apiPostStatus({
|
||||
credentials: useUsersStore().currentUser.credentials,
|
||||
credentials: useOAuthStore().token,
|
||||
status,
|
||||
spoilerText,
|
||||
visibility,
|
||||
|
|
@ -71,7 +71,7 @@ const editStatus = ({
|
|||
|
||||
return apiEditStatus({
|
||||
id: statusId,
|
||||
credentials: useUsersStore().currentUser.credentials,
|
||||
credentials: useOAuthStore().token,
|
||||
status,
|
||||
spoilerText,
|
||||
sensitive,
|
||||
|
|
@ -101,12 +101,12 @@ const editStatus = ({
|
|||
}
|
||||
|
||||
const uploadMedia = ({ store, formData }) => {
|
||||
const credentials = useUsersStore().currentUser.credentials
|
||||
const credentials = useOAuthStore().token
|
||||
return apiUploadMedia({ credentials, formData }).then(({ data }) => data)
|
||||
}
|
||||
|
||||
const setMediaDescription = ({ store, id, description }) => {
|
||||
const credentials = useUsersStore().currentUser.credentials
|
||||
const credentials = useOAuthStore().token
|
||||
return apiSetMediaDescription({ credentials, id, description }).then(
|
||||
({ data }) => data,
|
||||
)
|
||||
|
|
|
|||
|
|
@ -37,7 +37,10 @@ export const useChatsStore = defineStore('chats', {
|
|||
actions: {
|
||||
attachSocket() {
|
||||
const et = new EventTarget()
|
||||
const socket = { et }
|
||||
const socket = {
|
||||
name: 'chats',
|
||||
et,
|
||||
}
|
||||
|
||||
et.addEventListener('pleroma:chat_update', this.updateChat)
|
||||
|
||||
|
|
@ -83,9 +86,6 @@ export const useChatsStore = defineStore('chats', {
|
|||
chat.lastMessage = updatedChat.lastMessage
|
||||
chat.unread = updatedChat.unread
|
||||
chat.updated_at = updatedChat.updated_at
|
||||
if (isNewMessage && chat.unread) {
|
||||
maybeShowChatNotification(chat)
|
||||
}
|
||||
} else {
|
||||
this.chatList.data.push(updatedChat)
|
||||
this.chatList.idStore[updatedChat.id] = updatedChat
|
||||
|
|
@ -98,16 +98,16 @@ export const useChatsStore = defineStore('chats', {
|
|||
chat.unread = 0
|
||||
}
|
||||
},
|
||||
updateChat({ chat: updatedChat }) {
|
||||
updateChat({ data: { chatUpdate: updatedChat } }) {
|
||||
const chat = getChatById(this, updatedChat.id)
|
||||
if (chat) {
|
||||
chat.lastMessage = updatedChat.lastMessage
|
||||
chat.unread = updatedChat.unread
|
||||
chat.updated_at = updatedChat.updated_at
|
||||
}
|
||||
if (!chat) {
|
||||
} else {
|
||||
this.chatList.data.unshift(updatedChat)
|
||||
}
|
||||
maybeShowChatNotification(chat)
|
||||
this.chatList.idStore[updatedChat.id] = updatedChat
|
||||
},
|
||||
deleteChat(id) {
|
||||
|
|
|
|||
|
|
@ -14,6 +14,7 @@ import {
|
|||
|
||||
import { useInterfaceStore } from 'src/stores/interface.js'
|
||||
import { useUsersStore } from 'src/stores/users.js'
|
||||
import { useOAuthStore } from 'src/stores/oauth.js'
|
||||
|
||||
import { fetchKnownDomains } from 'src/api/public.js'
|
||||
|
||||
|
|
@ -213,7 +214,7 @@ export const useInstanceStore = defineStore('instance', {
|
|||
async getKnownDomains() {
|
||||
try {
|
||||
const { data } = await fetchKnownDomains({
|
||||
credentials: useUsersStore().currentUser.credentials,
|
||||
credentials: useOAuthStore().token
|
||||
})
|
||||
this.knownDomains = data
|
||||
} catch (e) {
|
||||
|
|
|
|||
|
|
@ -96,7 +96,10 @@ export const useInterfaceStore = defineStore('interface', {
|
|||
actions: {
|
||||
attachSocket() {
|
||||
const et = new EventTarget()
|
||||
const socket = { et }
|
||||
const socket = {
|
||||
name: 'interface',
|
||||
et,
|
||||
}
|
||||
|
||||
et.addEventListener('open', this.onStreamConnect)
|
||||
et.addEventListener('close', this.onStreamDisconnect)
|
||||
|
|
@ -854,7 +857,7 @@ export const useInterfaceStore = defineStore('interface', {
|
|||
},
|
||||
|
||||
unregisterPushNotifications() {
|
||||
const token = this.currentUser.credentials
|
||||
const token = useOAuthStore().token
|
||||
|
||||
unregisterPushNotifications(token)
|
||||
},
|
||||
|
|
|
|||
|
|
@ -31,7 +31,9 @@ export const defaultState = () => ({
|
|||
statusIdStore: new Set(),
|
||||
socket: null,
|
||||
streaming: false,
|
||||
fetching: true,
|
||||
fetcher: null,
|
||||
paused: false,
|
||||
})
|
||||
|
||||
export const useNotificationsStore = defineStore('notifications', {
|
||||
|
|
@ -40,14 +42,29 @@ export const useNotificationsStore = defineStore('notifications', {
|
|||
// Init
|
||||
attachSocket() {
|
||||
const et = new EventTarget()
|
||||
const socket = { et }
|
||||
const socket = {
|
||||
name: 'notifications',
|
||||
et,
|
||||
}
|
||||
|
||||
et.addEventListener('notification', this.addNewNotifications)
|
||||
et.addEventListener('open', this.onStreamConnect)
|
||||
et.addEventListener('close', this.onStreamDisconnect)
|
||||
|
||||
useStreamingStore().addSubscriber(socket)
|
||||
this.socket = socket
|
||||
useStreamingStore().addSubscriber(this.socket)
|
||||
},
|
||||
pause() {
|
||||
this.paused = true
|
||||
if (this.fetcher && this.fetching) {
|
||||
this.stopFetching('Notifications paused')
|
||||
}
|
||||
},
|
||||
resume() {
|
||||
this.paused = false
|
||||
if (this.fetcher && this.fetching) {
|
||||
this.startFetching('Notifications resumed')
|
||||
}
|
||||
},
|
||||
activate() {
|
||||
this.attachSocket()
|
||||
|
|
@ -62,7 +79,7 @@ export const useNotificationsStore = defineStore('notifications', {
|
|||
this.startFetching('Notifications activated')
|
||||
},
|
||||
deactivate() {
|
||||
if (!this.streaming) {
|
||||
if (this.fetching) {
|
||||
this.stopFetching('Notifications deactivated')
|
||||
}
|
||||
|
||||
|
|
@ -77,6 +94,7 @@ export const useNotificationsStore = defineStore('notifications', {
|
|||
Object.keys(blankState).forEach((k) => {
|
||||
this[k] = blankState[k]
|
||||
})
|
||||
console.log('[Notifications] Deactivated', this.fetcher)
|
||||
},
|
||||
|
||||
// Poll & Push
|
||||
|
|
@ -91,20 +109,30 @@ export const useNotificationsStore = defineStore('notifications', {
|
|||
this.startFetching('Socket disconnected')
|
||||
},
|
||||
startFetching(reason) {
|
||||
if (this.paused) {
|
||||
console.debug(
|
||||
'[Notificatiosn] NOT Starting notifications fetcher because it is paused',
|
||||
'Original Reason:',
|
||||
reason,
|
||||
)
|
||||
return
|
||||
}
|
||||
console.debug(
|
||||
'[Notifications] Starting fetching notifications',
|
||||
'[Notifications] Starting notifications fetcher',
|
||||
'Reason:',
|
||||
reason,
|
||||
)
|
||||
this.fetcher.startFetching()
|
||||
this.fetching = true
|
||||
},
|
||||
stopFetching(reason) {
|
||||
this.fetcher.stopFetching()
|
||||
this.fetching = false
|
||||
console.debug(
|
||||
'[Notifications] Stopped fetching notifications',
|
||||
'[Notifications] Stopped notifications fetcher',
|
||||
'Reason:',
|
||||
reason,
|
||||
)
|
||||
this.fetcher.stopFetching()
|
||||
},
|
||||
|
||||
// Updates
|
||||
|
|
@ -223,7 +251,7 @@ export const useNotificationsStore = defineStore('notifications', {
|
|||
case 'follow_request':
|
||||
break
|
||||
default:
|
||||
this.markSingleNotificationAsSeen({ id })
|
||||
this.markSingleNotificationAsSeen(id)
|
||||
}
|
||||
}
|
||||
},
|
||||
|
|
|
|||
|
|
@ -19,7 +19,7 @@ export const useSearchStore = defineStore('search', {
|
|||
credentials: useOAuthStore().token,
|
||||
})
|
||||
|
||||
const { accounts, statuses } = data
|
||||
const { accounts, statuses, hashtags } = data
|
||||
|
||||
useUsersStore().addNewUsers({
|
||||
...rest,
|
||||
|
|
@ -36,6 +36,7 @@ export const useSearchStore = defineStore('search', {
|
|||
useStatusesStore().allStatuses.get(s.id),
|
||||
)
|
||||
output.accounts = accounts.map((s) => useUsersStore().findUser(s.id))
|
||||
output.hashtags = hashtags ?? []
|
||||
return output
|
||||
},
|
||||
|
||||
|
|
|
|||
|
|
@ -49,6 +49,7 @@ export const useStatusesStore = defineStore('statuses', {
|
|||
data.forEach((id) => this.setDeleted(id))
|
||||
|
||||
const socket = {
|
||||
name: 'statuses',
|
||||
et,
|
||||
handlers: {
|
||||
handleUpdate,
|
||||
|
|
@ -64,15 +65,9 @@ export const useStatusesStore = defineStore('statuses', {
|
|||
this.socket = socket
|
||||
},
|
||||
resetStatuses() {
|
||||
this.socket.et.removeEventListener('update', this.socket.handleUpdate)
|
||||
this.socket.et.removeEventListener(
|
||||
'status.update',
|
||||
this.socket.handleUpdate,
|
||||
)
|
||||
this.socket.et.removeEventListener('delete', this.socket.handleDelete)
|
||||
|
||||
const emptyState = defaultState()
|
||||
Object.entries(emptyState).forEach(([key, value]) => {
|
||||
if (key === 'socket') return
|
||||
this[key] = value
|
||||
})
|
||||
},
|
||||
|
|
@ -154,7 +149,7 @@ export const useStatusesStore = defineStore('statuses', {
|
|||
|
||||
const newStatus = {
|
||||
...old,
|
||||
...neu,
|
||||
...Object.fromEntries(Object.entries(neu).filter(([, v]) => v !== undefined)),
|
||||
user,
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -131,6 +131,7 @@ export const useStreamingStore = defineStore('streaming', {
|
|||
},
|
||||
|
||||
getSubArgs(stream) {
|
||||
if (stream === undefined) return undefined
|
||||
const argumentKey = ARGUMENT_MAP[stream.name]
|
||||
const args = argumentKey
|
||||
? {
|
||||
|
|
|
|||
|
|
@ -16,9 +16,11 @@ const emptyTl = (name, argument = null) => {
|
|||
maxId: '',
|
||||
minId: '',
|
||||
streaming: false,
|
||||
fetching: false,
|
||||
reloadNeeded: false,
|
||||
fetcher: null,
|
||||
socket: null,
|
||||
paused: false,
|
||||
}
|
||||
|
||||
const property = ARGUMENT_MAP[name]
|
||||
|
|
@ -105,16 +107,16 @@ export const useTimelinesStore = defineStore('timelines', {
|
|||
const openHandler = () => this.onStreamConnect(timelineName, argument)
|
||||
const closeHandler = () =>
|
||||
this.onStreamDisconnect(timelineName, argument)
|
||||
const messageHandler =
|
||||
() =>
|
||||
({ detail: message }) =>
|
||||
this.onStreamMessage(timelineName, argument, message)
|
||||
const messageHandler = (message) => {
|
||||
this.onStreamMessage(timelineName, argument, message)
|
||||
}
|
||||
|
||||
et.addEventListener('open', openHandler)
|
||||
et.addEventListener('close', closeHandler)
|
||||
et.addEventListener('update', messageHandler)
|
||||
|
||||
timeline.socket = {
|
||||
name: 'timelines',
|
||||
stream: {
|
||||
name: streamName,
|
||||
argument,
|
||||
|
|
@ -133,7 +135,7 @@ export const useTimelinesStore = defineStore('timelines', {
|
|||
deactivate(timelineName, persistent) {
|
||||
const timeline = this[timelineName]
|
||||
if (timeline.persistent && !persistent) return
|
||||
if (!timeline.streaming) {
|
||||
if (timeline.fetching) {
|
||||
this.stopFetchingTimeline(timelineName, 'Timeline deactivation')
|
||||
}
|
||||
|
||||
|
|
@ -177,6 +179,48 @@ export const useTimelinesStore = defineStore('timelines', {
|
|||
})
|
||||
},
|
||||
|
||||
// Pause
|
||||
pause(name) {
|
||||
const timeline = this[name]
|
||||
timeline.paused = true
|
||||
console.debug(
|
||||
'[Timelines] Pausing timeline',
|
||||
name,
|
||||
)
|
||||
if (timeline.fetcher && timeline.fetching) {
|
||||
timeline.fetcher.stopFetching()
|
||||
}
|
||||
},
|
||||
resume(name) {
|
||||
const timeline = this[name]
|
||||
timeline.paused = false
|
||||
console.debug(
|
||||
'[Timelines] Resuming timeline',
|
||||
name,
|
||||
)
|
||||
if (timeline.fetcher && timeline.fetching) {
|
||||
timeline.fetcher.startFetching()
|
||||
}
|
||||
},
|
||||
pauseAll() {
|
||||
TIMELINES.forEach((name) => {
|
||||
try {
|
||||
this.pause(name)
|
||||
} catch (e) {
|
||||
console.error(`[Timelines] Failed to pause timeline ${name}:`, e)
|
||||
}
|
||||
})
|
||||
},
|
||||
resumeAll() {
|
||||
TIMELINES.forEach((name) => {
|
||||
try {
|
||||
this.resume(name)
|
||||
} catch (e) {
|
||||
console.error(`[Timelines] Failed to pause timeline ${name}:`, e)
|
||||
}
|
||||
})
|
||||
},
|
||||
|
||||
// Update stuff
|
||||
addStatusesToTimeline(
|
||||
timelineName,
|
||||
|
|
@ -231,7 +275,7 @@ export const useTimelinesStore = defineStore('timelines', {
|
|||
},
|
||||
onStreamMessage(timeline, argument, event) {
|
||||
this.addStatusesToTimeline(timeline, argument, {
|
||||
statuses: [event.data.status.id],
|
||||
statuses: event.data.map(({ id }) => id),
|
||||
})
|
||||
},
|
||||
|
||||
|
|
@ -247,15 +291,28 @@ export const useTimelinesStore = defineStore('timelines', {
|
|||
this.startFetchingTimeline(timeline, argument, 'Socket disconnected')
|
||||
},
|
||||
startFetchingTimeline(timelineName, argument, reason) {
|
||||
const timeline = this[timelineName]
|
||||
console.log('[Timelines]', toValue(timeline))
|
||||
if (timeline.paused) {
|
||||
console.debug(
|
||||
'[Timelines] NOT Starting timeline fetcher because it is paused',
|
||||
timelineName,
|
||||
argument,
|
||||
'Original Reason:',
|
||||
reason,
|
||||
)
|
||||
return
|
||||
}
|
||||
|
||||
console.debug(
|
||||
'[Timelines] Starting fetching timeline',
|
||||
'[Timelines] Starting timeline fetcher',
|
||||
timelineName,
|
||||
argument,
|
||||
'Reason:',
|
||||
reason,
|
||||
)
|
||||
const timeline = this[timelineName]
|
||||
timeline.fetcher.startFetching()
|
||||
timeline.fetching = true
|
||||
},
|
||||
stopFetchingTimeline(timelineName, reason) {
|
||||
const timeline = this[timelineName]
|
||||
|
|
@ -275,6 +332,7 @@ export const useTimelinesStore = defineStore('timelines', {
|
|||
'Reason:',
|
||||
reason,
|
||||
)
|
||||
timeline.fetching = false
|
||||
}
|
||||
},
|
||||
|
||||
|
|
|
|||
|
|
@ -2,6 +2,8 @@ import Cookies from 'js-cookie'
|
|||
import { last } from 'lodash'
|
||||
import { defineStore } from 'pinia'
|
||||
|
||||
import { WSConnectionStatus } from 'src/api/websocket.js'
|
||||
|
||||
import { useAnnouncementsStore } from 'src/stores/announcements.js'
|
||||
import { useBookmarkFoldersStore } from 'src/stores/bookmark_folders.js'
|
||||
import { useChatsStore } from 'src/stores/chats.js'
|
||||
|
|
@ -615,12 +617,15 @@ export const useUsersStore = defineStore('users', {
|
|||
user.domainMutes = new Set()
|
||||
|
||||
this.lastLoginName = user.screen_name
|
||||
this.currentUser = user
|
||||
useTimelinesStore().deactivateAll()
|
||||
useStatusesStore().resetStatuses()
|
||||
|
||||
this.users = new Map()
|
||||
this.usersByName = new Map()
|
||||
this.usersByURL = new Map()
|
||||
this.relationships = new Map()
|
||||
this.currentUser = user
|
||||
this.addNewUsers({ data: user, ...rest })
|
||||
|
||||
useInterfaceStore().onLogin()
|
||||
useSyncConfigStore()
|
||||
|
|
@ -634,7 +639,6 @@ export const useUsersStore = defineStore('users', {
|
|||
})
|
||||
|
||||
useUserHighlightStore().initUserHighlight(user)
|
||||
this.addNewUsers({ data: user, ...rest })
|
||||
|
||||
useEmojiStore().fetchEmoji()
|
||||
|
||||
|
|
@ -660,8 +664,8 @@ export const useUsersStore = defineStore('users', {
|
|||
}
|
||||
|
||||
// DMs and Home
|
||||
useNotificationsStore().activate()
|
||||
useTimelinesStore().activatePersistents()
|
||||
useNotificationsStore().activate()
|
||||
|
||||
if (useInstanceCapabilitiesStore().pleromaChatMessagesAvailable) {
|
||||
// Start fetching chats
|
||||
|
|
@ -708,6 +712,16 @@ export const useUsersStore = defineStore('users', {
|
|||
const store = window.vuex
|
||||
const oauth = useOAuthStore()
|
||||
|
||||
// Pause fetching
|
||||
useNotificationsStore().pause()
|
||||
useTimelinesStore().pauseAll()
|
||||
|
||||
// Pause-less stores
|
||||
useAnnouncementsStore().stopFetching()
|
||||
useListsStore().stopFetching()
|
||||
useBookmarkFoldersStore().stopFetching()
|
||||
store?.dispatch('stopFetchingFollowRequests')
|
||||
|
||||
// NOTE: No need to verify the app still exists, because if it doesn't,
|
||||
// the token will be invalid too
|
||||
return oauth
|
||||
|
|
@ -722,28 +736,53 @@ export const useUsersStore = defineStore('users', {
|
|||
return revokeToken(params)
|
||||
})
|
||||
.then(() => {
|
||||
oauth.clearToken()
|
||||
|
||||
this.currentUser = null
|
||||
this.lastLoginName = null
|
||||
|
||||
useNotificationsStore().deactivate()
|
||||
|
||||
// Full reset on logout success
|
||||
useTimelinesStore().deactivateAll()
|
||||
useStatusesStore().resetStatuses()
|
||||
useChatsStore().resetChats()
|
||||
|
||||
this.users = new Map()
|
||||
this.usersByName = new Map()
|
||||
this.usersByURL = new Map()
|
||||
this.relationships = new Map()
|
||||
useNotificationsStore().deactivate()
|
||||
useAnnouncementsStore().stopFetching()
|
||||
useListsStore().stopFetching()
|
||||
useBookmarkFoldersStore().stopFetching()
|
||||
store?.dispatch('stopFetchingFollowRequests')
|
||||
useTimelinesStore().deactivateAll()
|
||||
useStatusesStore().resetStatuses()
|
||||
if (useMergedConfigStore().mergedConfig.useStreamingApi) {
|
||||
|
||||
// Socket is most likely already closed by server
|
||||
if (
|
||||
useMergedConfigStore().mergedConfig.useStreamingApi
|
||||
&& useStreamingStore().state !== WSConnectionStatus.CLOSED
|
||||
) {
|
||||
useStreamingStore().stopSocket()
|
||||
}
|
||||
useChatsStore().resetChats()
|
||||
oauth.clearToken()
|
||||
|
||||
Cookies.remove('__Host-pleroma_key', { path: '/' })
|
||||
useInterfaceStore().onLogout()
|
||||
})
|
||||
.catch((e) => {
|
||||
useInterfaceStore().pushGlobalNotice({
|
||||
messageKey: 'user.logout_failure',
|
||||
messageArgs: {
|
||||
error: e,
|
||||
},
|
||||
level: 'error',
|
||||
})
|
||||
console.error('Logout error!', e)
|
||||
|
||||
useAnnouncementsStore().startFetching()
|
||||
useListsStore().startFetching()
|
||||
useBookmarkFoldersStore().startFetching()
|
||||
store?.dispatch('startFetchingFollowRequests')
|
||||
})
|
||||
.finally(() => {
|
||||
useNotificationsStore().resume()
|
||||
useTimelinesStore().resumeAll()
|
||||
})
|
||||
},
|
||||
},
|
||||
persist: {
|
||||
|
|
|
|||
|
|
@ -354,13 +354,11 @@ describe('RichContent', () => {
|
|||
'<span class="MentionLink mention-link">',
|
||||
'<a href="lol" class="original" target="_blank">',
|
||||
'<span>',
|
||||
'<span>',
|
||||
'https://</span>',
|
||||
'<span>',
|
||||
'lol.tld/</span>',
|
||||
'<span>',
|
||||
'</span>',
|
||||
'</span>',
|
||||
'</a>',
|
||||
'</span>',
|
||||
'</span>',
|
||||
|
|
@ -420,25 +418,21 @@ describe('RichContent', () => {
|
|||
'<span class="MentionLink mention-link">',
|
||||
'<a href="lol" class="original" target="_blank">',
|
||||
'<span>',
|
||||
'<span>',
|
||||
'https://</span>',
|
||||
'<span>',
|
||||
'lol.tld/</span>',
|
||||
'<span>',
|
||||
'</span>',
|
||||
'</span>',
|
||||
'</a>',
|
||||
'</span>',
|
||||
'<span class="MentionLink mention-link">',
|
||||
'<a href="lol" class="original" target="_blank">',
|
||||
'<span>',
|
||||
'<span>',
|
||||
'https://</span>',
|
||||
'<span>',
|
||||
'lol.tld/</span>',
|
||||
'<span>',
|
||||
'</span>',
|
||||
'</span>',
|
||||
'</a>',
|
||||
'</span>',
|
||||
'</span>',
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue