diff --git a/.changeset/slimy-olives-march.md b/.changeset/slimy-olives-march.md new file mode 100644 index 000000000000..3959ad46463f --- /dev/null +++ b/.changeset/slimy-olives-march.md @@ -0,0 +1,6 @@ +--- +'@rocket.chat/rest-typings': minor +'@rocket.chat/meteor': minor +--- + +Reintroduce an user preference to allow users to see all thread messages in the main channel diff --git a/apps/meteor/app/ui-utils/client/lib/RoomHistoryManager.ts b/apps/meteor/app/ui-utils/client/lib/RoomHistoryManager.ts index ba4f8a436fed..879977f7052d 100644 --- a/apps/meteor/app/ui-utils/client/lib/RoomHistoryManager.ts +++ b/apps/meteor/app/ui-utils/client/lib/RoomHistoryManager.ts @@ -8,6 +8,7 @@ import type { MutableRefObject } from 'react'; import { waitForElement } from '../../../../client/lib/utils/waitForElement'; import { readMessage } from './readMessages'; +import { getUserPreference } from '../../../utils/client'; import { getConfig } from '../../../../client/lib/utils/getConfig'; import { ChatMessage, ChatSubscription } from '../../../models/client'; import { callWithErrorHandling } from '../../../../client/lib/utils/callWithErrorHandling'; @@ -140,7 +141,15 @@ class RoomHistoryManagerClass extends Emitter { ({ ls } = subscription); } - const result = await callWithErrorHandling('loadHistory', rid, room.oldestTs, limit, ls ? String(ls) : undefined, false); + const showThreadsInMainChannel = getUserPreference(Meteor.userId(), 'showThreadsInMainChannel', false); + const result = await callWithErrorHandling( + 'loadHistory', + rid, + room.oldestTs, + limit, + ls ? String(ls) : undefined, + showThreadsInMainChannel, + ); if (!result) { throw new Error('loadHistory returned nothing'); @@ -174,7 +183,7 @@ class RoomHistoryManagerClass extends Emitter { room.loaded = 0; } - const visibleMessages = messages.filter((msg) => !msg.tmid || msg.tshow); + const visibleMessages = messages.filter((msg) => !msg.tmid || showThreadsInMainChannel || msg.tshow); room.loaded += visibleMessages.length; diff --git a/apps/meteor/client/components/message/variants/threadPreview/ThreadMessagePreviewBody.tsx b/apps/meteor/client/components/message/variants/threadPreview/ThreadMessagePreviewBody.tsx index 0327ee327acd..33bce63745e2 100644 --- a/apps/meteor/client/components/message/variants/threadPreview/ThreadMessagePreviewBody.tsx +++ b/apps/meteor/client/components/message/variants/threadPreview/ThreadMessagePreviewBody.tsx @@ -26,6 +26,9 @@ const ThreadMessagePreviewBody = ({ message }: ThreadMessagePreviewBodyProps): R ) { mdTokens?.shift(); } + if (message.attachments && message.msg === '') { + return <>{t('Message_with_attachment')}; + } if (!isEncryptedMessage || message.e2e === 'done') { return mdTokens ? ( diff --git a/apps/meteor/client/views/account/preferences/PreferencesMessagesSection.tsx b/apps/meteor/client/views/account/preferences/PreferencesMessagesSection.tsx index ebb0e1728131..25f143772be6 100644 --- a/apps/meteor/client/views/account/preferences/PreferencesMessagesSection.tsx +++ b/apps/meteor/client/views/account/preferences/PreferencesMessagesSection.tsx @@ -9,6 +9,7 @@ import type { FormSectionProps } from './AccountPreferencesPage'; type Values = { unreadAlert: boolean; + showThreadsInMainChannel: boolean; alsoSendThreadToChannel: 'default' | 'always' | 'never'; useEmojis: boolean; convertAsciiEmoji: boolean; @@ -30,6 +31,7 @@ const PreferencesMessagesSection = ({ onChange, commitRef, ...props }: FormSecti const settings = { unreadAlert: useUserPreference('unreadAlert'), + showThreadsInMainChannel: useUserPreference('showThreadsInMainChannel'), alsoSendThreadToChannel: useUserPreference('alsoSendThreadToChannel'), useEmojis: useUserPreference('useEmojis'), convertAsciiEmoji: useUserPreference('convertAsciiEmoji'), @@ -48,6 +50,7 @@ const PreferencesMessagesSection = ({ onChange, commitRef, ...props }: FormSecti const { unreadAlert, + showThreadsInMainChannel, alsoSendThreadToChannel, useEmojis, convertAsciiEmoji, @@ -64,6 +67,7 @@ const PreferencesMessagesSection = ({ onChange, commitRef, ...props }: FormSecti const { handleUnreadAlert, + handleShowThreadsInMainChannel, handleAlsoSendThreadToChannel, handleUseEmojis, handleConvertAsciiEmoji, @@ -121,6 +125,18 @@ const PreferencesMessagesSection = ({ onChange, commitRef, ...props }: FormSecti ), [handleUnreadAlert, t, unreadAlert], )} + {useMemo( + () => ( + + {t('Always_show_thread_replies_in_main_channel')} + + + + {t('Accounts_Default_User_Preferences_showThreadsInMainChannel_Description')} + + ), + [handleShowThreadsInMainChannel, showThreadsInMainChannel, t], + )} {useMemo( () => ( diff --git a/apps/meteor/client/views/room/MessageList/hooks/useMessages.ts b/apps/meteor/client/views/room/MessageList/hooks/useMessages.ts index fbc987e68e63..a4a52fe84575 100644 --- a/apps/meteor/client/views/room/MessageList/hooks/useMessages.ts +++ b/apps/meteor/client/views/room/MessageList/hooks/useMessages.ts @@ -1,6 +1,6 @@ import type { IRoom, IMessage, MessageTypesValues } from '@rocket.chat/core-typings'; import { useStableArray } from '@rocket.chat/fuselage-hooks'; -import { useSetting } from '@rocket.chat/ui-contexts'; +import { useSetting, useUserPreference } from '@rocket.chat/ui-contexts'; import type { Mongo } from 'meteor/mongo'; import { useCallback, useMemo } from 'react'; @@ -16,6 +16,7 @@ const mergeHideSysMessages = ( }; export const useMessages = ({ rid }: { rid: IRoom['_id'] }): IMessage[] => { + const showThreadsInMainChannel = useUserPreference('showThreadsInMainChannel', false); const hideSysMesSetting = useSetting('Hide_System_Messages') ?? []; const room = useRoom(); const hideRoomSysMes: Array = Array.isArray(room.sysMes) ? room.sysMes : []; @@ -27,9 +28,11 @@ export const useMessages = ({ rid }: { rid: IRoom['_id'] }): IMessage[] => { rid, _hidden: { $ne: true }, t: { $nin: hideSysMessages }, - $or: [{ tmid: { $exists: false } }, { tshow: { $eq: true } }], + ...(!showThreadsInMainChannel && { + $or: [{ tmid: { $exists: false } }, { tshow: { $eq: true } }], + }), }), - [rid, hideSysMessages], + [rid, hideSysMessages, showThreadsInMainChannel], ); return useReactiveValue( diff --git a/apps/meteor/packages/rocketchat-i18n/i18n/en.i18n.json b/apps/meteor/packages/rocketchat-i18n/i18n/en.i18n.json index 1be1de77221f..b2c18812828e 100644 --- a/apps/meteor/packages/rocketchat-i18n/i18n/en.i18n.json +++ b/apps/meteor/packages/rocketchat-i18n/i18n/en.i18n.json @@ -91,6 +91,7 @@ "Accounts_Default_User_Preferences_desktopNotifications": "Desktop Notifications Default Alert", "Accounts_Default_User_Preferences_pushNotifications": "Push Notifications Default Alert", "Accounts_Default_User_Preferences_not_available": "Failed to retrieve User Preferences because they haven't been set up by the user yet", + "Accounts_Default_User_Preferences_showThreadsInMainChannel_Description": "When enabled, all replies under a thread will also be displayed directly in the main room. When disabled, thread replies will be displayed based on the sender's choice.", "Accounts_DefaultUsernamePrefixSuggestion": "Default Username Prefix Suggestion", "Accounts_denyUnverifiedEmail": "Deny unverified email", "Accounts_Directory_DefaultView": "Default Directory Listing", @@ -395,6 +396,7 @@ "Also_send_thread_message_to_channel_behavior": "Also send thread message to channel behavior", "Also_send_to_channel": "Also send to channel", "Always_open_in_new_window": "Always Open in New Window", + "Always_show_thread_replies_in_main_channel": "Always show thread replies in main channel", "Analytics": "Analytics", "Analytics_Description": "See how users interact with your workspace.", "Analytics_features_enabled": "Features Enabled", @@ -3335,6 +3337,7 @@ "Message_Attachments_Thumbnails_Enabled": "Enable image thumbnails to save bandwith", "Message_Attachments_Thumbnails_Width": "Thumbnail's max width (in pixels)", "Message_Attachments_Thumbnails_Height": "Thumbnail's max height (in pixels)", + "Message_with_attachment": "Message with attachment", "Report_sent": "Report sent", "Message_Attachments_Thumbnails_EnabledDesc": "Thumbnails will be served instead of the original image to reduce bandwith usage. Images at original resolution can be downloaded using the icon next to the attachment's name.", "Message_Attachments_Strip_Exif": "Remove EXIF metadata from supported files", @@ -4582,7 +4585,6 @@ "Show_default_content": "Show default content", "Show_email_field": "Show email field", "Show_mentions": "Show badge for mentions", - "Show_Message_In_Main_Thread": "Show thread messages in the main thread", "Show_more": "Show more", "Show_name_field": "Show name field", "show_offline_users": "show offline users", diff --git a/apps/meteor/server/settings/accounts.ts b/apps/meteor/server/settings/accounts.ts index a4db6512ed16..76f1c344b94f 100644 --- a/apps/meteor/server/settings/accounts.ts +++ b/apps/meteor/server/settings/accounts.ts @@ -572,6 +572,12 @@ export const createAccountSettings = () => i18nLabel: 'Sort_By', }); + await this.add('Accounts_Default_User_Preferences_showThreadsInMainChannel', false, { + type: 'boolean', + public: true, + i18nLabel: 'Always_show_thread_replies_in_main_channel', + }); + await this.add('Accounts_Default_User_Preferences_alsoSendThreadToChannel', 'default', { type: 'select', values: [ diff --git a/apps/meteor/tests/end-to-end/api/00-miscellaneous.js b/apps/meteor/tests/end-to-end/api/00-miscellaneous.js index 5b07a0d34b4e..971ed7d8e7b8 100644 --- a/apps/meteor/tests/end-to-end/api/00-miscellaneous.js +++ b/apps/meteor/tests/end-to-end/api/00-miscellaneous.js @@ -142,6 +142,7 @@ describe('miscellaneous', function () { // 'language', 'newRoomNotification', 'newMessageNotification', + 'showThreadsInMainChannel', // 'clockMode', 'useEmojis', 'convertAsciiEmoji', diff --git a/packages/rest-typings/src/v1/users/UsersSetPreferenceParamsPOST.ts b/packages/rest-typings/src/v1/users/UsersSetPreferenceParamsPOST.ts index 5a07797dc80a..69ac5440189a 100644 --- a/packages/rest-typings/src/v1/users/UsersSetPreferenceParamsPOST.ts +++ b/packages/rest-typings/src/v1/users/UsersSetPreferenceParamsPOST.ts @@ -24,6 +24,7 @@ export type UsersSetPreferencesParamsPOST = { highlights?: string[]; alsoSendThreadToChannel?: 'never' | 'always' | 'default'; desktopNotificationRequireInteraction?: boolean; + showThreadsInMainChannel?: boolean; hideUsernames?: boolean; hideRoles?: boolean; displayAvatars?: boolean; @@ -124,6 +125,10 @@ const UsersSetPreferencesParamsPostSchema = { }, nullable: true, }, + showThreadsInMainChannel: { + type: 'boolean', + nullable: true, + }, desktopNotificationRequireInteraction: { type: 'boolean', nullable: true,