From f4ad9b29acd686167ceb447c16dbae02035c63b0 Mon Sep 17 00:00:00 2001 From: Germain Date: Thu, 12 Jan 2023 12:34:40 +0000 Subject: [PATCH] [Release] Switch threads on for everyone (#9890) Co-authored-by: Andy Balaam --- cypress/e2e/polls/polls.spec.ts | 2 +- cypress/e2e/threads/threads.spec.ts | 2 +- src/MatrixClientPeg.ts | 2 +- src/components/structures/MessagePanel.tsx | 2 +- src/components/structures/RoomSearchView.tsx | 2 +- src/components/structures/RoomView.tsx | 2 +- src/components/structures/ThreadPanel.tsx | 2 +- src/components/structures/TimelinePanel.tsx | 2 +- src/components/views/context_menus/MessageContextMenu.tsx | 4 ++-- src/components/views/messages/MessageActionBar.tsx | 8 ++++---- src/components/views/right_panel/RoomHeaderButtons.tsx | 2 +- src/components/views/rooms/EventTile.tsx | 6 +++--- src/components/views/rooms/SearchResultTile.tsx | 2 +- src/components/views/rooms/SendMessageComposer.tsx | 2 +- .../views/rooms/wysiwyg_composer/utils/message.ts | 2 +- src/settings/Settings.tsx | 4 ++-- src/stores/TypingStore.ts | 2 +- src/stores/right-panel/RightPanelStore.ts | 4 ++-- src/stores/widgets/StopGapWidgetDriver.ts | 2 +- src/utils/Reply.ts | 4 ++-- src/utils/exportUtils/HtmlExport.tsx | 2 +- test/components/structures/TimelinePanel-test.tsx | 8 ++++---- test/components/views/messages/MessageActionBar-test.tsx | 4 ++-- .../views/right_panel/RoomHeaderButtons-test.tsx | 2 +- test/components/views/rooms/EventTile-test.tsx | 2 +- 25 files changed, 38 insertions(+), 38 deletions(-) diff --git a/cypress/e2e/polls/polls.spec.ts b/cypress/e2e/polls/polls.spec.ts index 477c195ac36..f73524965cf 100644 --- a/cypress/e2e/polls/polls.spec.ts +++ b/cypress/e2e/polls/polls.spec.ts @@ -77,7 +77,7 @@ describe("Polls", () => { }; beforeEach(() => { - cy.enableLabsFeature("feature_threadstable"); + cy.enableLabsFeature("feature_threadenabled"); cy.window().then((win) => { win.localStorage.setItem("mx_lhs_size", "0"); // Collapse left panel for these tests }); diff --git a/cypress/e2e/threads/threads.spec.ts b/cypress/e2e/threads/threads.spec.ts index 0de87ea9cd2..84778d4be76 100644 --- a/cypress/e2e/threads/threads.spec.ts +++ b/cypress/e2e/threads/threads.spec.ts @@ -29,7 +29,7 @@ describe("Threads", () => { beforeEach(() => { // Default threads to ON for this spec - cy.enableLabsFeature("feature_threadstable"); + cy.enableLabsFeature("feature_threadenabled"); cy.window().then((win) => { win.localStorage.setItem("mx_lhs_size", "0"); // Collapse left panel for these tests }); diff --git a/src/MatrixClientPeg.ts b/src/MatrixClientPeg.ts index a18b4e9a6f0..f674892bf7c 100644 --- a/src/MatrixClientPeg.ts +++ b/src/MatrixClientPeg.ts @@ -218,7 +218,7 @@ class MatrixClientPegClass implements IMatrixClientPeg { opts.pendingEventOrdering = PendingEventOrdering.Detached; opts.lazyLoadMembers = true; opts.clientWellKnownPollPeriod = 2 * 60 * 60; // 2 hours - opts.experimentalThreadSupport = SettingsStore.getValue("feature_threadstable"); + opts.experimentalThreadSupport = SettingsStore.getValue("feature_threadenabled"); if (SettingsStore.getValue("feature_sliding_sync")) { const proxyUrl = SettingsStore.getValue("feature_sliding_sync_proxy_url"); diff --git a/src/components/structures/MessagePanel.tsx b/src/components/structures/MessagePanel.tsx index 8942f0abd48..cd3f3223694 100644 --- a/src/components/structures/MessagePanel.tsx +++ b/src/components/structures/MessagePanel.tsx @@ -287,7 +287,7 @@ export default class MessagePanel extends React.Component { // and we check this in a hot code path. This is also cached in our // RoomContext, however we still need a fallback for roomless MessagePanels. this._showHiddenEvents = SettingsStore.getValue("showHiddenEventsInTimeline"); - this.threadsEnabled = SettingsStore.getValue("feature_threadstable"); + this.threadsEnabled = SettingsStore.getValue("feature_threadenabled"); this.showTypingNotificationsWatcherRef = SettingsStore.watchSetting( "showTypingNotifications", diff --git a/src/components/structures/RoomSearchView.tsx b/src/components/structures/RoomSearchView.tsx index 269980c6a33..d7a995b5c04 100644 --- a/src/components/structures/RoomSearchView.tsx +++ b/src/components/structures/RoomSearchView.tsx @@ -100,7 +100,7 @@ export const RoomSearchView = forwardRef( return b.length - a.length; }); - if (SettingsStore.getValue("feature_threadstable")) { + if (SettingsStore.getValue("feature_threadenabled")) { // Process all thread roots returned in this batch of search results // XXX: This won't work for results coming from Seshat which won't include the bundled relationship for (const result of results.results) { diff --git a/src/components/structures/RoomView.tsx b/src/components/structures/RoomView.tsx index 3de552d1d01..eb034fd2b74 100644 --- a/src/components/structures/RoomView.tsx +++ b/src/components/structures/RoomView.tsx @@ -1182,7 +1182,7 @@ export class RoomView extends React.Component { CHAT_EFFECTS.forEach((effect) => { if (containsEmoji(ev.getContent(), effect.emojis) || ev.getContent().msgtype === effect.msgType) { // For initial threads launch, chat effects are disabled see #19731 - if (!SettingsStore.getValue("feature_threadstable") || !ev.isRelation(THREAD_RELATION_TYPE.name)) { + if (!SettingsStore.getValue("feature_threadenabled") || !ev.isRelation(THREAD_RELATION_TYPE.name)) { dis.dispatch({ action: `effects.${effect.command}` }); } } diff --git a/src/components/structures/ThreadPanel.tsx b/src/components/structures/ThreadPanel.tsx index 51990a739d0..b313a0948e4 100644 --- a/src/components/structures/ThreadPanel.tsx +++ b/src/components/structures/ThreadPanel.tsx @@ -249,7 +249,7 @@ const ThreadPanel: React.FC = ({ roomId, onClose, permalinkCreator }) => const openFeedback = shouldShowFeedback() ? () => { Modal.createDialog(BetaFeedbackDialog, { - featureId: "feature_threadstable", + featureId: "feature_threadenabled", }); } : null; diff --git a/src/components/structures/TimelinePanel.tsx b/src/components/structures/TimelinePanel.tsx index c1fc13bbb19..fedada7c3ff 100644 --- a/src/components/structures/TimelinePanel.tsx +++ b/src/components/structures/TimelinePanel.tsx @@ -1688,7 +1688,7 @@ class TimelinePanel extends React.Component { is very tied to the main room timeline, we are forcing the timeline to send read receipts for threaded events */ const isThreadTimeline = this.context.timelineRenderingType === TimelineRenderingType.Thread; - if (SettingsStore.getValue("feature_threadstable") && isThreadTimeline) { + if (SettingsStore.getValue("feature_threadenabled") && isThreadTimeline) { return 0; } const index = this.state.events.findIndex((ev) => ev.getId() === evId); diff --git a/src/components/views/context_menus/MessageContextMenu.tsx b/src/components/views/context_menus/MessageContextMenu.tsx index ed4c2ab4cb9..295a4452cdf 100644 --- a/src/components/views/context_menus/MessageContextMenu.tsx +++ b/src/components/views/context_menus/MessageContextMenu.tsx @@ -71,7 +71,7 @@ const ReplyInThreadButton = ({ mxEvent, closeMenu }: IReplyInThreadButton) => { if (Boolean(relationType) && relationType !== RelationType.Thread) return null; const onClick = (): void => { - if (!SettingsStore.getValue("feature_threadstable")) { + if (!SettingsStore.getValue("feature_threadenabled")) { dis.dispatch({ action: Action.ViewUserSettings, initialTabId: UserTab.Labs, @@ -640,7 +640,7 @@ export default class MessageContextMenu extends React.Component rightClick && contentActionable && canSendMessages && - SettingsStore.getValue("feature_threadstable") && + SettingsStore.getValue("feature_threadenabled") && Thread.hasServerSideSupport && timelineRenderingType !== TimelineRenderingType.Thread ) { diff --git a/src/components/views/messages/MessageActionBar.tsx b/src/components/views/messages/MessageActionBar.tsx index 1ec7fae7517..5b78a2614ff 100644 --- a/src/components/views/messages/MessageActionBar.tsx +++ b/src/components/views/messages/MessageActionBar.tsx @@ -204,7 +204,7 @@ const ReplyInThreadButton = ({ mxEvent }: IReplyInThreadButton) => { const relationType = mxEvent?.getRelation()?.rel_type; const hasARelation = !!relationType && relationType !== RelationType.Thread; - const threadsEnabled = SettingsStore.getValue("feature_threadstable"); + const threadsEnabled = SettingsStore.getValue("feature_threadenabled"); if (!threadsEnabled && !Thread.hasServerSideSupport) { // hide the prompt if the user would only have degraded mode @@ -216,7 +216,7 @@ const ReplyInThreadButton = ({ mxEvent }: IReplyInThreadButton) => { e.preventDefault(); e.stopPropagation(); - if (!SettingsStore.getValue("feature_threadstable")) { + if (!SettingsStore.getValue("feature_threadenabled")) { dis.dispatch({ action: Action.ViewUserSettings, initialTabId: UserTab.Labs, @@ -252,7 +252,7 @@ const ReplyInThreadButton = ({ mxEvent }: IReplyInThreadButton) => { {!hasARelation && (
- {SettingsStore.getValue("feature_threadstable") + {SettingsStore.getValue("feature_threadenabled") ? _t("Beta feature") : _t("Beta feature. Click to learn more.")}
@@ -548,7 +548,7 @@ export default class MessageActionBar extends React.PureComponent { ); rightPanelPhaseButtons.set( RightPanelPhases.ThreadPanel, - SettingsStore.getValue("feature_threadstable") ? ( + SettingsStore.getValue("feature_threadenabled") ? ( } } - if (SettingsStore.getValue("feature_threadstable")) { + if (SettingsStore.getValue("feature_threadenabled")) { this.props.mxEvent.on(ThreadEvent.Update, this.updateThread); if (this.thread && !this.supportsThreadNotifications) { @@ -470,7 +470,7 @@ export class UnwrappedEventTile extends React.Component if (this.props.showReactions) { this.props.mxEvent.removeListener(MatrixEventEvent.RelationsCreated, this.onReactionsCreated); } - if (SettingsStore.getValue("feature_threadstable")) { + if (SettingsStore.getValue("feature_threadenabled")) { this.props.mxEvent.off(ThreadEvent.Update, this.updateThread); } this.threadState?.off(NotificationStateEvents.Update, this.onThreadStateUpdate); @@ -501,7 +501,7 @@ export class UnwrappedEventTile extends React.Component }; private get thread(): Thread | null { - if (!SettingsStore.getValue("feature_threadstable")) { + if (!SettingsStore.getValue("feature_threadenabled")) { return null; } diff --git a/src/components/views/rooms/SearchResultTile.tsx b/src/components/views/rooms/SearchResultTile.tsx index 269a35d8a2b..f88e71e02bc 100644 --- a/src/components/views/rooms/SearchResultTile.tsx +++ b/src/components/views/rooms/SearchResultTile.tsx @@ -68,7 +68,7 @@ export default class SearchResultTile extends React.Component { const layout = SettingsStore.getValue("layout"); const isTwelveHour = SettingsStore.getValue("showTwelveHourTimestamps"); const alwaysShowTimestamps = SettingsStore.getValue("alwaysShowTimestamps"); - const threadsEnabled = SettingsStore.getValue("feature_threadstable"); + const threadsEnabled = SettingsStore.getValue("feature_threadenabled"); for (let j = 0; j < timeline.length; j++) { const mxEv = timeline[j]; diff --git a/src/components/views/rooms/SendMessageComposer.tsx b/src/components/views/rooms/SendMessageComposer.tsx index 692591fb0b9..60ce5d09b4a 100644 --- a/src/components/views/rooms/SendMessageComposer.tsx +++ b/src/components/views/rooms/SendMessageComposer.tsx @@ -436,7 +436,7 @@ export class SendMessageComposer extends React.Component ( diff --git a/src/stores/TypingStore.ts b/src/stores/TypingStore.ts index 4a572e74d9c..8296ebfe5f3 100644 --- a/src/stores/TypingStore.ts +++ b/src/stores/TypingStore.ts @@ -65,7 +65,7 @@ export default class TypingStore { if (SettingsStore.getValue("lowBandwidth")) return; // Disable typing notification for threads for the initial launch // before we figure out a better user experience for them - if (SettingsStore.getValue("feature_threadstable") && threadId) return; + if (SettingsStore.getValue("feature_threadenabled") && threadId) return; let currentTyping = this.typingStates[roomId]; if ((!isTyping && !currentTyping) || (currentTyping && currentTyping.isTyping === isTyping)) { diff --git a/src/stores/right-panel/RightPanelStore.ts b/src/stores/right-panel/RightPanelStore.ts index b9e218b3692..3aea9a4746b 100644 --- a/src/stores/right-panel/RightPanelStore.ts +++ b/src/stores/right-panel/RightPanelStore.ts @@ -278,10 +278,10 @@ export default class RightPanelStore extends ReadyWatchingStore { // (A nicer fix could be to indicate, that the right panel is loading if there is missing state data and re-emit if the data is available) switch (card.phase) { case RightPanelPhases.ThreadPanel: - if (!SettingsStore.getValue("feature_threadstable")) return false; + if (!SettingsStore.getValue("feature_threadenabled")) return false; break; case RightPanelPhases.ThreadView: - if (!SettingsStore.getValue("feature_threadstable")) return false; + if (!SettingsStore.getValue("feature_threadenabled")) return false; if (!card.state.threadHeadEvent) { logger.warn("removed card from right panel because of missing threadHeadEvent in card state"); } diff --git a/src/stores/widgets/StopGapWidgetDriver.ts b/src/stores/widgets/StopGapWidgetDriver.ts index 42fdf0dea47..3caac0fbca8 100644 --- a/src/stores/widgets/StopGapWidgetDriver.ts +++ b/src/stores/widgets/StopGapWidgetDriver.ts @@ -236,7 +236,7 @@ export class StopGapWidgetDriver extends WidgetDriver { // For initial threads launch, chat effects are disabled // see #19731 const isNotThread = content["m.relates_to"].rel_type !== THREAD_RELATION_TYPE.name; - if (!SettingsStore.getValue("feature_threadstable") || isNotThread) { + if (!SettingsStore.getValue("feature_threadenabled") || isNotThread) { dis.dispatch({ action: `effects.${effect.command}` }); } } diff --git a/src/utils/Reply.ts b/src/utils/Reply.ts index b6ee476bf64..7bafd9f66ad 100644 --- a/src/utils/Reply.ts +++ b/src/utils/Reply.ts @@ -176,7 +176,7 @@ export function makeReplyMixIn(ev?: MatrixEvent): IEventRelation { }; if (ev.threadRootId) { - if (SettingsStore.getValue("feature_threadstable")) { + if (SettingsStore.getValue("feature_threadenabled")) { mixin.is_falling_back = false; } else { // Clients that do not offer a threading UI should behave as follows when replying, for best interaction @@ -203,7 +203,7 @@ export function shouldDisplayReply(event: MatrixEvent): boolean { const relation = event.getRelation(); if ( - SettingsStore.getValue("feature_threadstable") && + SettingsStore.getValue("feature_threadenabled") && relation?.rel_type === THREAD_RELATION_TYPE.name && relation?.is_falling_back ) { diff --git a/src/utils/exportUtils/HtmlExport.tsx b/src/utils/exportUtils/HtmlExport.tsx index 95a2fdbd60e..57eb54ce8f5 100644 --- a/src/utils/exportUtils/HtmlExport.tsx +++ b/src/utils/exportUtils/HtmlExport.tsx @@ -62,7 +62,7 @@ export default class HTMLExporter extends Exporter { this.mediaOmitText = !this.exportOptions.attachmentsIncluded ? _t("Media omitted") : _t("Media omitted - file size limit exceeded"); - this.threadsEnabled = SettingsStore.getValue("feature_threadstable"); + this.threadsEnabled = SettingsStore.getValue("feature_threadenabled"); } protected async getRoomAvatar() { diff --git a/test/components/structures/TimelinePanel-test.tsx b/test/components/structures/TimelinePanel-test.tsx index 95847bb8c5e..e66a015a5c5 100644 --- a/test/components/structures/TimelinePanel-test.tsx +++ b/test/components/structures/TimelinePanel-test.tsx @@ -174,7 +174,7 @@ describe("TimelinePanel", () => { const getValueCopy = SettingsStore.getValue; SettingsStore.getValue = jest.fn().mockImplementation((name: string) => { if (name === "sendReadReceipts") return true; - if (name === "feature_threadstable") return false; + if (name === "feature_threadenabled") return false; return getValueCopy(name); }); @@ -188,7 +188,7 @@ describe("TimelinePanel", () => { const getValueCopy = SettingsStore.getValue; SettingsStore.getValue = jest.fn().mockImplementation((name: string) => { if (name === "sendReadReceipts") return false; - if (name === "feature_threadstable") return false; + if (name === "feature_threadenabled") return false; return getValueCopy(name); }); @@ -365,7 +365,7 @@ describe("TimelinePanel", () => { client.supportsExperimentalThreads = () => true; const getValueCopy = SettingsStore.getValue; SettingsStore.getValue = jest.fn().mockImplementation((name: string) => { - if (name === "feature_threadstable") return true; + if (name === "feature_threadenabled") return true; return getValueCopy(name); }); @@ -520,7 +520,7 @@ describe("TimelinePanel", () => { }); it("renders when the last message is an undecryptable thread root", async () => { - jest.spyOn(SettingsStore, "getValue").mockImplementation((name) => name === "feature_threadstable"); + jest.spyOn(SettingsStore, "getValue").mockImplementation((name) => name === "feature_threadenabled"); const client = MatrixClientPeg.get(); client.isRoomEncrypted = () => true; diff --git a/test/components/views/messages/MessageActionBar-test.tsx b/test/components/views/messages/MessageActionBar-test.tsx index 8b64f205f0c..c5f6c03b784 100644 --- a/test/components/views/messages/MessageActionBar-test.tsx +++ b/test/components/views/messages/MessageActionBar-test.tsx @@ -389,7 +389,7 @@ describe("", () => { describe("when threads feature is not enabled", () => { beforeEach(() => { jest.spyOn(SettingsStore, "getValue").mockImplementation( - (setting) => setting !== "feature_threadstable", + (setting) => setting !== "feature_threadenabled", ); }); @@ -435,7 +435,7 @@ describe("", () => { describe("when threads feature is enabled", () => { beforeEach(() => { jest.spyOn(SettingsStore, "getValue").mockImplementation( - (setting) => setting === "feature_threadstable", + (setting) => setting === "feature_threadenabled", ); }); diff --git a/test/components/views/right_panel/RoomHeaderButtons-test.tsx b/test/components/views/right_panel/RoomHeaderButtons-test.tsx index 7d898904d8c..06192ccc232 100644 --- a/test/components/views/right_panel/RoomHeaderButtons-test.tsx +++ b/test/components/views/right_panel/RoomHeaderButtons-test.tsx @@ -44,7 +44,7 @@ describe("RoomHeaderButtons-test.tsx", function () { }); jest.spyOn(SettingsStore, "getValue").mockImplementation((name: string) => { - if (name === "feature_threadstable") return true; + if (name === "feature_threadenabled") return true; }); }); diff --git a/test/components/views/rooms/EventTile-test.tsx b/test/components/views/rooms/EventTile-test.tsx index 7c46f6aa3a5..c3c0b55ab5b 100644 --- a/test/components/views/rooms/EventTile-test.tsx +++ b/test/components/views/rooms/EventTile-test.tsx @@ -80,7 +80,7 @@ describe("EventTile", () => { jest.spyOn(client, "getRoom").mockReturnValue(room); jest.spyOn(client, "decryptEventIfNeeded").mockResolvedValue(); - jest.spyOn(SettingsStore, "getValue").mockImplementation((name) => name === "feature_threadstable"); + jest.spyOn(SettingsStore, "getValue").mockImplementation((name) => name === "feature_threadenabled"); mxEvent = mkMessage({ room: room.roomId,