Skip to content
This repository has been archived by the owner on Sep 11, 2024. It is now read-only.

Commit

Permalink
Delabs threads
Browse files Browse the repository at this point in the history
  • Loading branch information
germain-gg committed Dec 12, 2022
1 parent dec72c7 commit 35cd43e
Show file tree
Hide file tree
Showing 31 changed files with 51 additions and 202 deletions.
1 change: 0 additions & 1 deletion cypress/e2e/polls/polls.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,6 @@ describe("Polls", () => {
};

beforeEach(() => {
cy.enableLabsFeature("feature_thread");
cy.window().then(win => {
win.localStorage.setItem("mx_lhs_size", "0"); // Collapse left panel for these tests
});
Expand Down
2 changes: 0 additions & 2 deletions cypress/e2e/threads/threads.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,6 @@ describe("Threads", () => {
let synapse: SynapseInstance;

beforeEach(() => {
// Default threads to ON for this spec
cy.enableLabsFeature("feature_thread");
cy.window().then(win => {
win.localStorage.setItem("mx_lhs_size", "0"); // Collapse left panel for these tests
});
Expand Down
8 changes: 0 additions & 8 deletions res/css/views/messages/_MessageActionBar.pcss
Original file line number Diff line number Diff line change
Expand Up @@ -114,14 +114,6 @@ limitations under the License.
color: $primary-content;
}

&.mx_MessageActionBar_threadButton {

.mx_Indicator {
background: $links;
animation-iteration-count: infinite;
}
}

&.mx_MessageActionBar_favouriteButton_fillstar {
color: var(--MessageActionBar-star-button-color);
}
Expand Down
Binary file removed res/img/betas/threads.png
Binary file not shown.
2 changes: 1 addition & 1 deletion src/MatrixClientPeg.ts
Original file line number Diff line number Diff line change
Expand Up @@ -236,7 +236,7 @@ class MatrixClientPegClass implements IMatrixClientPeg {
opts.pendingEventOrdering = PendingEventOrdering.Detached;
opts.lazyLoadMembers = true;
opts.clientWellKnownPollPeriod = 2 * 60 * 60; // 2 hours
opts.experimentalThreadSupport = SettingsStore.getValue("feature_thread");
opts.experimentalThreadSupport = true;

if (SettingsStore.getValue("feature_sliding_sync")) {
const proxyUrl = SettingsStore.getValue("feature_sliding_sync_proxy_url");
Expand Down
2 changes: 1 addition & 1 deletion src/Unread.ts
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ export function doesRoomHaveUnreadMessages(room: Room): boolean {
// despite the name of the method :((
const readUpToId = room.getEventReadUpTo(myUserId);

if (!SettingsStore.getValue("feature_thread")) {
if (!SettingsStore.getValue("feature_threadstable")) {
// as we don't send RRs for our own messages, make sure we special case that
// if *we* sent the last message into the room, we consider it not unread!
// Should fix: https://github.com/vector-im/element-web/issues/3263
Expand Down
2 changes: 1 addition & 1 deletion src/components/structures/MessagePanel.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -280,7 +280,7 @@ export default class MessagePanel extends React.Component<IProps, IState> {
// 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_thread");
this.threadsEnabled = SettingsStore.getValue("feature_threadstable");

this.showTypingNotificationsWatcherRef =
SettingsStore.watchSetting("showTypingNotifications", null, this.onShowTypingNotificationsChange);
Expand Down
10 changes: 3 additions & 7 deletions src/components/structures/RoomSearchView.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ import ResizeNotifier from "../../utils/ResizeNotifier";
import MatrixClientContext from "../../contexts/MatrixClientContext";
import { RoomPermalinkCreator } from "../../utils/permalinks/Permalinks";
import RoomContext from "../../contexts/RoomContext";
import SettingsStore from '../../settings/SettingsStore';

const DEBUG = false;
let debuglog = function(msg: string) {};
Expand Down Expand Up @@ -100,7 +101,7 @@ export const RoomSearchView = forwardRef<ScrollPanel, Props>(({
return b.length - a.length;
});

if (client.supportsExperimentalThreads()) {
if (SettingsStore.getValue("feature_threadstable")) {
// 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) {
Expand All @@ -109,12 +110,7 @@ export const RoomSearchView = forwardRef<ScrollPanel, Props>(({
.getServerAggregatedRelation<IThreadBundledRelationship>(THREAD_RELATION_TYPE.name);
if (!bundledRelationship || event.getThread()) continue;
const room = client.getRoom(event.getRoomId());
const thread = room.findThreadForEvent(event);
if (thread) {
event.setThread(thread);
} else {
room.createThread(event.getId(), event, [], true);
}
room.createThread(event.getId(), event, [], true);
}
}
}
Expand Down
2 changes: 1 addition & 1 deletion src/components/structures/RoomView.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -1162,7 +1162,7 @@ export class RoomView extends React.Component<IRoomProps, IRoomState> {
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_thread") || !ev.isRelation(THREAD_RELATION_TYPE.name)) {
if (!SettingsStore.getValue("feature_threadstable") || !ev.isRelation(THREAD_RELATION_TYPE.name)) {
dis.dispatch({ action: `effects.${effect.command}` });
}
}
Expand Down
2 changes: 1 addition & 1 deletion src/components/structures/ThreadPanel.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -224,7 +224,7 @@ const ThreadPanel: React.FC<IProps> = ({

const openFeedback = shouldShowFeedback() ? () => {
Modal.createDialog(BetaFeedbackDialog, {
featureId: "feature_thread",
featureId: "feature_threadstable",
});
} : null;

Expand Down
2 changes: 1 addition & 1 deletion src/components/structures/TimelinePanel.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -1638,7 +1638,7 @@ class TimelinePanel extends React.Component<IProps, IState> {
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_thread") && isThreadTimeline) {
if (SettingsStore.getValue("feature_threadstable") && isThreadTimeline) {
return 0;
}
const index = this.state.events.findIndex(ev => ev.getId() === evId);
Expand Down
8 changes: 4 additions & 4 deletions src/components/views/context_menus/MessageContextMenu.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -76,11 +76,11 @@ const ReplyInThreadButton = ({ mxEvent, closeMenu }: IReplyInThreadButton) => {
if (Boolean(relationType) && relationType !== RelationType.Thread) return null;

const onClick = (): void => {
if (!localStorage.getItem("mx_seen_feature_thread")) {
localStorage.setItem("mx_seen_feature_thread", "true");
if (!localStorage.getItem("mx_seen_feature_threadstable")) {
localStorage.setItem("mx_seen_feature_threadstable", "true");
}

if (!SettingsStore.getValue("feature_thread")) {
if (!SettingsStore.getValue("feature_threadstable")) {
dis.dispatch({
action: Action.ViewUserSettings,
initialTabId: UserTab.Labs,
Expand Down Expand Up @@ -647,7 +647,7 @@ export default class MessageContextMenu extends React.Component<IProps, IState>
rightClick &&
contentActionable &&
canSendMessages &&
SettingsStore.getValue("feature_thread") &&
SettingsStore.getValue("feature_threadstable") &&
Thread.hasServerSideSupport &&
timelineRenderingType !== TimelineRenderingType.Thread
) {
Expand Down
31 changes: 5 additions & 26 deletions src/components/views/messages/MessageActionBar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -190,8 +190,7 @@ const ReplyInThreadButton = ({ mxEvent }: IReplyInThreadButton) => {

const relationType = mxEvent?.getRelation()?.rel_type;
const hasARelation = !!relationType && relationType !== RelationType.Thread;
const firstTimeSeeingThreads = !localStorage.getItem("mx_seen_feature_thread");
const threadsEnabled = SettingsStore.getValue("feature_thread");
const threadsEnabled = SettingsStore.getValue("feature_threadstable");

if (!threadsEnabled && !Thread.hasServerSideSupport) {
// hide the prompt if the user would only have degraded mode
Expand All @@ -203,11 +202,7 @@ const ReplyInThreadButton = ({ mxEvent }: IReplyInThreadButton) => {
e.preventDefault();
e.stopPropagation();

if (firstTimeSeeingThreads) {
localStorage.setItem("mx_seen_feature_thread", "true");
}

if (!SettingsStore.getValue("feature_thread")) {
if (!SettingsStore.getValue("feature_threadstable")) {
dis.dispatch({
action: Action.ViewUserSettings,
initialTabId: UserTab.Labs,
Expand Down Expand Up @@ -241,7 +236,7 @@ const ReplyInThreadButton = ({ mxEvent }: IReplyInThreadButton) => {
</div>
{ !hasARelation && (
<div className="mx_Tooltip_sub">
{ SettingsStore.getValue("feature_thread")
{ SettingsStore.getValue("feature_threadstable")
? _t("Beta feature")
: _t("Beta feature. Click to learn more.")
}
Expand All @@ -257,9 +252,6 @@ const ReplyInThreadButton = ({ mxEvent }: IReplyInThreadButton) => {
onContextMenu={onClick}
>
<ThreadIcon />
{ firstTimeSeeingThreads && !threadsEnabled && (
<div className="mx_Indicator" />
) }
</RovingAccessibleTooltipButton>;
};

Expand Down Expand Up @@ -375,20 +367,6 @@ export default class MessageActionBar extends React.PureComponent<IMessageAction
];

private get showReplyInThreadAction(): boolean {
if (!SettingsStore.getValue("feature_thread") && !Thread.hasServerSideSupport) {
// hide the prompt if the user would only have degraded mode
return null;
}

if (!SettingsStore.getBetaInfo("feature_thread") &&
!SettingsStore.getValue("feature_thread") &&
!SdkConfig.get("show_labs_settings")
) {
// Hide the beta prompt if there is no UI to enable it,
// e.g if config.json disables it and doesn't enable show labs flags
return false;
}

const inNotThreadTimeline = this.context.timelineRenderingType !== TimelineRenderingType.Thread;

const isAllowedMessageType = (
Expand All @@ -398,6 +376,7 @@ export default class MessageActionBar extends React.PureComponent<IMessageAction
* until cross-platform support
* (PSF-1041)
*/

!M_BEACON_INFO.matches(this.props.mxEvent.getType())
);

Expand Down Expand Up @@ -534,7 +513,7 @@ export default class MessageActionBar extends React.PureComponent<IMessageAction
key="download"
/>);
}
} else if (SettingsStore.getValue("feature_thread") &&
} else if (SettingsStore.getValue("feature_threadstable") &&
// Show thread icon even for deleted messages, but only within main timeline
this.context.timelineRenderingType === TimelineRenderingType.Room &&
this.props.mxEvent.getThread()
Expand Down
2 changes: 1 addition & 1 deletion src/components/views/right_panel/RoomHeaderButtons.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -292,7 +292,7 @@ export default class RoomHeaderButtons extends HeaderButtons<IProps> {
onClick={this.onTimelineCardClicked} />,
);
rightPanelPhaseButtons.set(RightPanelPhases.ThreadPanel,
SettingsStore.getValue("feature_thread")
SettingsStore.getValue("feature_threadstable")
? <HeaderButton
key={RightPanelPhases.ThreadPanel}
name="threadsButton"
Expand Down
19 changes: 4 additions & 15 deletions src/components/views/rooms/EventTile.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -391,7 +391,7 @@ export class UnwrappedEventTile extends React.Component<EventTileProps, IState>
}
}

if (SettingsStore.getValue("feature_thread")) {
if (SettingsStore.getValue("feature_threadstable")) {
this.props.mxEvent.on(ThreadEvent.Update, this.updateThread);

if (this.thread && !this.supportsThreadNotifications) {
Expand Down Expand Up @@ -473,7 +473,7 @@ export class UnwrappedEventTile extends React.Component<EventTileProps, IState>
if (this.props.showReactions) {
this.props.mxEvent.removeListener(MatrixEventEvent.RelationsCreated, this.onReactionsCreated);
}
if (SettingsStore.getValue("feature_thread")) {
if (SettingsStore.getValue("feature_threadstable")) {
this.props.mxEvent.off(ThreadEvent.Update, this.updateThread);
}
this.threadState?.off(NotificationStateEvents.Update, this.onThreadStateUpdate);
Expand All @@ -500,22 +500,11 @@ export class UnwrappedEventTile extends React.Component<EventTileProps, IState>
};

private get thread(): Thread | null {
if (!SettingsStore.getValue("feature_thread")) {
if (!SettingsStore.getValue("feature_threadstable")) {
return null;
}

let thread = this.props.mxEvent.getThread();
/**
* Accessing the threads value through the room due to a race condition
* that will be solved when there are proper backend support for threads
* We currently have no reliable way to discover than an event is a thread
* when we are at the sync stage
*/
if (!thread) {
const room = MatrixClientPeg.get().getRoom(this.props.mxEvent.getRoomId());
thread = room?.findThreadForEvent(this.props.mxEvent);
}
return thread ?? null;
return this.props.mxEvent.getThread() ?? null;
}

private renderThreadPanelSummary(): JSX.Element | null {
Expand Down
2 changes: 1 addition & 1 deletion src/components/views/rooms/SearchResultTile.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ export default class SearchResultTile extends React.Component<IProps> {
const layout = SettingsStore.getValue("layout");
const isTwelveHour = SettingsStore.getValue("showTwelveHourTimestamps");
const alwaysShowTimestamps = SettingsStore.getValue("alwaysShowTimestamps");
const threadsEnabled = SettingsStore.getValue("feature_thread");
const threadsEnabled = SettingsStore.getValue("feature_threadstable");

const timeline = result.context.getTimeline();
for (let j = 0; j < timeline.length; j++) {
Expand Down
2 changes: 1 addition & 1 deletion src/components/views/rooms/SendMessageComposer.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -432,7 +432,7 @@ export class SendMessageComposer extends React.Component<ISendMessageComposerPro
// For initial threads launch, chat effects are disabled
// see #19731
const isNotThread = this.props.relation?.rel_type !== THREAD_RELATION_TYPE.name;
if (!SettingsStore.getValue("feature_thread") || isNotThread) {
if (!SettingsStore.getValue("feature_threadstable") || isNotThread) {
dis.dispatch({ action: `effects.${effect.command}` });
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -118,7 +118,7 @@ export function sendMessage(
// For initial threads launch, chat effects are disabled
// see #19731
const isNotThread = relation?.rel_type !== THREAD_RELATION_TYPE.name;
if (!SettingsStore.getValue("feature_thread") || isNotThread) {
if (!SettingsStore.getValue("feature_threadstable") || isNotThread) {
dis.dispatch({ action: `effects.${effect.command}` });
}
}
Expand Down
12 changes: 3 additions & 9 deletions src/i18n/strings/en_EN.json
Original file line number Diff line number Diff line change
Expand Up @@ -913,15 +913,7 @@
"In rooms that support moderation, the “Report” button will let you report abuse to room moderators.": "In rooms that support moderation, the “Report” button will let you report abuse to room moderators.",
"Render LaTeX maths in messages": "Render LaTeX maths in messages",
"Message Pinning": "Message Pinning",
"Threaded messaging": "Threaded messaging",
"Keep discussions organised with threads.": "Keep discussions organised with threads.",
"Threads help keep conversations on-topic and easy to track. <a>Learn more</a>.": "Threads help keep conversations on-topic and easy to track. <a>Learn more</a>.",
"How can I start a thread?": "How can I start a thread?",
"Use “%(replyInThread)s” when hovering over a message.": "Use “%(replyInThread)s” when hovering over a message.",
"Reply in thread": "Reply in thread",
"How can I leave the beta?": "How can I leave the beta?",
"To leave, return to this page and use the “%(leaveTheBeta)s” button.": "To leave, return to this page and use the “%(leaveTheBeta)s” button.",
"Leave the beta": "Leave the beta",
"Threaded messages": "Threaded messages",
"Rich text editor": "Rich text editor",
"Use rich text instead of Markdown in the message composer. Plain text mode coming soon.": "Use rich text instead of Markdown in the message composer. Plain text mode coming soon.",
"Render simple counters in room header": "Render simple counters in room header",
Expand Down Expand Up @@ -2320,6 +2312,7 @@
"Error processing audio message": "Error processing audio message",
"View live location": "View live location",
"React": "React",
"Reply in thread": "Reply in thread",
"Can't create a thread from an event with an existing relation": "Can't create a thread from an event with an existing relation",
"Beta feature": "Beta feature",
"Beta feature. Click to learn more.": "Beta feature. Click to learn more.",
Expand Down Expand Up @@ -3196,6 +3189,7 @@
"Beta": "Beta",
"Leaving the beta will reload %(brand)s.": "Leaving the beta will reload %(brand)s.",
"Joining the beta will reload %(brand)s.": "Joining the beta will reload %(brand)s.",
"Leave the beta": "Leave the beta",
"Join the beta": "Join the beta",
"Updated %(humanizedUpdateTime)s": "Updated %(humanizedUpdateTime)s",
"Live until %(expiryTime)s": "Live until %(expiryTime)s",
Expand Down
38 changes: 3 additions & 35 deletions src/settings/Settings.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -270,45 +270,13 @@ export const SETTINGS: {[setting: string]: ISetting} = {
supportedLevels: LEVELS_FEATURE,
default: false,
},
"feature_thread": {
"feature_threadstable": {
isFeature: true,
labsGroup: LabGroup.Messaging,
controller: new ThreadBetaController(),
displayName: _td("Threaded messaging"),
displayName: _td("Threaded messages"),
supportedLevels: LEVELS_FEATURE,
default: false,
betaInfo: {
title: _td("Threads"),
caption: () => <>
<p>{ _t("Keep discussions organised with threads.") }</p>
<p>{ _t("Threads help keep conversations on-topic and easy to track. <a>Learn more</a>.", {}, {
a: (sub) => <a href="https://element.io/help#threads" rel="noreferrer noopener" target="_blank">
{ sub }
</a>,
}) }</p>
</>,
faq: () =>
SdkConfig.get().bug_report_endpoint_url && <>
<h4>{ _t("How can I start a thread?") }</h4>
<p>
{ _t("Use “%(replyInThread)s” when hovering over a message.", {
replyInThread: _t("Reply in thread"),
}) }
</p>
<h4>{ _t("How can I leave the beta?") }</h4>
<p>
{ _t("To leave, return to this page and use the “%(leaveTheBeta)s” button.", {
leaveTheBeta: _t("Leave the beta"),
}) }
</p>
</>,
feedbackLabel: "thread-feedback",
feedbackSubheading: _td("Thank you for trying the beta, " +
"please go into as much detail as you can so we can improve it."),
image: require("../../res/img/betas/threads.png"),
requiresRefresh: true,
},

default: true,
},
"feature_wysiwyg_composer": {
isFeature: true,
Expand Down
2 changes: 1 addition & 1 deletion src/stores/TypingStore.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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_thread") && threadId) return;
if (SettingsStore.getValue("feature_threadstable") && threadId) return;

let currentTyping = this.typingStates[roomId];
if ((!isTyping && !currentTyping) || (currentTyping && currentTyping.isTyping === isTyping)) {
Expand Down
Loading

0 comments on commit 35cd43e

Please sign in to comment.