diff --git a/src/api/helpers.js b/src/api/helpers.js index ce41eca77..4bf16e0cc 100644 --- a/src/api/helpers.js +++ b/src/api/helpers.js @@ -17,7 +17,6 @@ export const paramsString = (params = {}) => { } })() - const arrays = [] const nonArrays = [] diff --git a/src/components/chat_message/chat_message.js b/src/components/chat_message/chat_message.js index b3436191b..8444899e2 100644 --- a/src/components/chat_message/chat_message.js +++ b/src/components/chat_message/chat_message.js @@ -7,9 +7,9 @@ import ChatMessageDate from 'src/components/chat_message_date/chat_message_date. import Gallery from 'src/components/gallery/gallery.vue' import LinkPreview from 'src/components/link-preview/link-preview.vue' import Popover from 'src/components/popover/popover.vue' -import StatusContent from 'src/components/status_content/status_content.vue' -import StatusBody from 'src/components/status_body/status_body.vue' import StatusActionButtons from 'src/components/status_action_buttons/status_action_buttons.vue' +import StatusBody from 'src/components/status_body/status_body.vue' +import StatusContent from 'src/components/status_content/status_content.vue' import UserAvatar from 'src/components/user_avatar/user_avatar.vue' import UserPopover from 'src/components/user_popover/user_popover.vue' @@ -28,7 +28,14 @@ library.add(faTimes, faEllipsisH, faCircleNotch) const ChatMessage = { name: 'ChatMessage', - props: ['edited', 'noHeading', 'previousItem', 'chatItem', 'previousItem', 'hoveredMessageChain'], + props: [ + 'edited', + 'noHeading', + 'previousItem', + 'chatItem', + 'previousItem', + 'hoveredMessageChain', + ], emits: ['hover', 'replyRequested'], components: { Popover, @@ -40,7 +47,8 @@ const ChatMessage = { Gallery, LinkPreview, ChatMessageDate, - UserPopover,}, + UserPopover, + }, computed: { // Returns HH:MM (hours and minutes) in local time. createdAt() { @@ -74,10 +82,14 @@ const ChatMessage = { console.log('==') console.log('PREV', toValue(this.previousItem.data.raw_html)) console.log('CURR', toValue(this.chatItem.data.raw_html)) - return this.previousItem.data.id !== this.chatItem.data.in_reply_to_status_id + return ( + this.previousItem.data.id !== this.chatItem.data.in_reply_to_status_id + ) }, customReplyTo() { - return find(this.$store.state.statuses.allStatuses, { id: this.chatItem.data.in_reply_to_status_id }) + return find(this.$store.state.statuses.allStatuses, { + id: this.chatItem.data.in_reply_to_status_id, + }) }, messageForStatusContent() { return { diff --git a/src/components/chat_view/chat_view.js b/src/components/chat_view/chat_view.js index 8cdb3535f..ee72d592f 100644 --- a/src/components/chat_view/chat_view.js +++ b/src/components/chat_view/chat_view.js @@ -51,6 +51,9 @@ const Chat = { ChatTitle, PostStatusForm, }, + props: { + testMode: Boolean, + }, data() { return { // Main info @@ -76,6 +79,7 @@ const Chat = { } }, created() { + if (this.testMode) return this.startFetching() window.addEventListener('resize', this.handleResize) }, @@ -210,13 +214,16 @@ const Chat = { if (!isNewMessage) return - await readChat({ - id: this.chat.id, - lastReadId, - credentials: useOAuthStore().token, - }) + if (!this.testMode) + await readChat({ + id: this.chat.id, + lastReadId, + credentials: useOAuthStore().token, + }) useChatsStore().readChat(this.chat.id) + this.lastReadMessageId = this.maxId + this.newMessageCount = 0 }, bottomedOut(offset) { return isBottomedOut(offset) @@ -224,24 +231,27 @@ const Chat = { reachedTop() { return window.scrollY <= 0 }, + cullOlder() { + const maxIndex = this.messages.length + const minIndex = maxIndex - 50 + if (maxIndex <= 50) return + + this.messages = sortBy(this.messages, ['id']) + this.minId = this.messages[minIndex].id + + for (const message of this.messages) { + if (message.id < this.minId) { + delete this.messagesIndex[message.id] + delete this.idempotencyKeyIndex[message.idempotency_key] + } + } + + this.messages = this.messages.slice(minIndex, maxIndex) + }, cullOlderCheck() { window.setTimeout(() => { if (this.bottomedOut(JUMP_TO_BOTTOM_BUTTON_VISIBILITY_OFFSET)) { - const maxIndex = this.messages.length - const minIndex = maxIndex - 50 - if (maxIndex <= 50) return - - this.messages = sortBy(this.messages, ['id']) - this.minId = this.messages[minIndex].id - - for (const message of this.messages) { - if (message.id < this.minId) { - delete this.messagesIndex[message.id] - delete this.idempotencyKeyIndex[message.idempotency_key] - } - } - - this.messages = this.messages.slice(minIndex, maxIndex) + this.cullOlder() } }, 5000) }, @@ -354,11 +364,12 @@ const Chat = { this.fetchChat({ isFirstFetch: true }) }, async deleteChatMessage({ chatId, messageId }) { - await deleteChatMessage({ - chatId, - messageId, - credentials: useOAuthStore().token, - }) + if (!this.testMode) + await deleteChatMessage({ + chatId, + messageId, + credentials: useOAuthStore().token, + }) this.messages = this.messages.filter((m) => m.id !== messageId) delete this.messagesIndex[messageId] @@ -406,7 +417,7 @@ const Chat = { } if (!this.messagesIndex[message.id] && !isConfirmation(this, message)) { - if (this.lastSeenMessageId < message.id) { + if (this.lastReadMessageId < message.id) { this.newMessageCount++ } this.messagesIndex[message.id] = message diff --git a/src/components/conversation/conversation.js b/src/components/conversation/conversation.js index 67ed1c307..91ffc09a3 100644 --- a/src/components/conversation/conversation.js +++ b/src/components/conversation/conversation.js @@ -2,11 +2,11 @@ import { clone, filter, findIndex, get, reduce } from 'lodash' import { mapState as mapPiniaState } from 'pinia' import { mapState } from 'vuex' -import StatusContent from 'src/components/status_content/status_content.vue' -import PostStatusForm from 'src/components/post_status_form/post_status_form.vue' import ChatMessageList from 'src/components/chat_message_list/chat_message_list.vue' +import PostStatusForm from 'src/components/post_status_form/post_status_form.vue' import QuickFilterSettings from 'src/components/quick_filter_settings/quick_filter_settings.vue' import QuickViewSettings from 'src/components/quick_view_settings/quick_view_settings.vue' +import StatusContent from 'src/components/status_content/status_content.vue' import ThreadTree from 'src/components/thread_tree/thread_tree.vue' import { useInterfaceStore } from 'src/stores/interface' @@ -25,7 +25,13 @@ import { faTimes, } from '@fortawesome/free-solid-svg-icons' -library.add(faAngleDoubleDown, faAngleDoubleLeft, faChevronLeft, faReply, faTimes) +library.add( + faAngleDoubleDown, + faAngleDoubleLeft, + faChevronLeft, + faReply, + faTimes, +) const sortById = (a, b) => { const idA = a.type === 'retweet' ? a.retweeted_status.id : a.id diff --git a/src/components/side_drawer/side_drawer.js b/src/components/side_drawer/side_drawer.js index 2098b3dff..369177c7a 100644 --- a/src/components/side_drawer/side_drawer.js +++ b/src/components/side_drawer/side_drawer.js @@ -7,12 +7,12 @@ import GestureService from '../../services/gesture_service/gesture_service' import { unseenNotificationsFromStore } from '../../services/notification_utils/notification_utils' import { useAnnouncementsStore } from 'src/stores/announcements' +import { useChatsStore } from 'src/stores/chats.js' import { useInstanceStore } from 'src/stores/instance.js' import { useInstanceCapabilitiesStore } from 'src/stores/instance_capabilities.js' import { useInterfaceStore } from 'src/stores/interface' import { useMergedConfigStore } from 'src/stores/merged_config.js' import { useShoutStore } from 'src/stores/shout' -import { useChatsStore } from 'src/stores/chats.js' import { library } from '@fortawesome/fontawesome-svg-core' import { diff --git a/src/components/status_action_buttons/action_button.js b/src/components/status_action_buttons/action_button.js index 17a67afc7..eed8cad9a 100644 --- a/src/components/status_action_buttons/action_button.js +++ b/src/components/status_action_buttons/action_button.js @@ -105,7 +105,9 @@ export default { return useMergedConfigStore().mergedConfig.hidePostStats }, buttonInnerClass() { - const buttonStyleClass = this.defaultButtonStyle ? 'button-default' : 'button-unstyled' + const buttonStyleClass = this.defaultButtonStyle + ? 'button-default' + : 'button-unstyled' return [ this.button.name + '-button', { diff --git a/src/components/status_action_buttons/action_button_container.js b/src/components/status_action_buttons/action_button_container.js index 4d316741d..fa4a529c6 100644 --- a/src/components/status_action_buttons/action_button_container.js +++ b/src/components/status_action_buttons/action_button_container.js @@ -42,7 +42,7 @@ export default { ), ), }, - props: ['button', 'status', 'defaultButton','hideLabel'], + props: ['button', 'status', 'defaultButton', 'hideLabel'], emits: ['emojiPickerShown'], mounted() { if (this.button.name === 'mute') { diff --git a/src/components/status_action_buttons/status_action_buttons.js b/src/components/status_action_buttons/status_action_buttons.js index d952faa6a..5309f44a3 100644 --- a/src/components/status_action_buttons/status_action_buttons.js +++ b/src/components/status_action_buttons/status_action_buttons.js @@ -38,7 +38,7 @@ const StatusActionButtons = { hideLabels: { type: Boolean, default: false, - } + }, }, emits: ['toggleReplying', 'onSuccess', 'onError'], data() { @@ -64,7 +64,8 @@ const StatusActionButtons = { }, computed: { ...mapState(useSyncConfigStore, { - userPinnedItems: (store) => new Set(store.prefsStorage.collections.pinnedStatusActions), + userPinnedItems: (store) => + new Set(store.prefsStorage.collections.pinnedStatusActions), }), pinnedItems() { if (this.fixedPinned) { diff --git a/test/unit/specs/components/chat_view.spec.js b/test/unit/specs/components/chat_view.spec.js index 5f9c1fca2..90adffa86 100644 --- a/test/unit/specs/components/chat_view.spec.js +++ b/test/unit/specs/components/chat_view.spec.js @@ -1,7 +1,7 @@ +import { createTestingPinia } from '@pinia/testing' import { shallowMount } from '@vue/test-utils' import { setActivePinia } from 'pinia' -import { createTestingPinia } from '@pinia/testing' -import { HttpResponse, http } from 'msw' + import ChatView from './chat_view.vue' const message1 = { @@ -32,7 +32,7 @@ const global = { $store: { state: { api: {}, - users: {} + users: {}, }, }, $route: { @@ -41,8 +41,10 @@ const global = { }, }, $router: { - push: () => {} - } + push: () => { + /* noop */ + }, + }, }, stubs: { FAIcon: true,