Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add option to stop sending read receipts (delabs MSC2285: private read receipts) #9128

Closed
wants to merge 31 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
31 commits
Select commit Hold shift + click to select a range
7110ced
Add tooltip
SimonBrandner May 17, 2022
a244da7
Add disabled tooltip
SimonBrandner May 17, 2022
bbf3a60
Delabs MSC2285: Private read receipts
SimonBrandner May 17, 2022
53c50ea
i18n
SimonBrandner May 17, 2022
dea9866
Update snaps
SimonBrandner May 17, 2022
1d9916b
Use a turnary operator
SimonBrandner May 18, 2022
c77d2f6
Fix typo
SimonBrandner May 19, 2022
3c04bc4
`disabledTooltip` -> `disabledTooltipText`
SimonBrandner May 19, 2022
c1f4370
Improve test utils
SimonBrandner May 21, 2022
10c14f6
Allow `=`
SimonBrandner May 21, 2022
1984bae
Add `TimelinePanel-tests`
SimonBrandner May 21, 2022
e8d1069
Improve formatting
SimonBrandner May 25, 2022
18aad85
Merge remote-tracking branch 'upstream/develop' into SimonBrandner/fe…
SimonBrandner May 25, 2022
e62a8f2
Merge remote-tracking branch 'upstream/develop' into SimonBrandner/fe…
SimonBrandner Jun 10, 2022
7c61400
Move `Presence` settings to the `Preferences` tab
SimonBrandner Jun 13, 2022
0abf5ef
Merge remote-tracking branch 'upstream/develop' into SimonBrandner/fe…
SimonBrandner Jun 13, 2022
c46607f
Revert "Add tooltip"
SimonBrandner Jun 14, 2022
fdd7065
Move disabled tooltip to microcopy
SimonBrandner Jun 14, 2022
31fa423
Update copy
SimonBrandner Jun 14, 2022
2a3c15d
Fix tests
SimonBrandner Jun 14, 2022
9926bc0
Make categories private
SimonBrandner Jun 15, 2022
356eba9
Add `sendReadReceipts` as a comment
SimonBrandner Jun 15, 2022
4ac6156
Merge remote-tracking branch 'upstream/develop' into SimonBrandner/fe…
SimonBrandner Jun 15, 2022
eeb2e77
Merge remote-tracking branch 'upstream/develop' into SimonBrandner/fe…
SimonBrandner Jun 24, 2022
b7bc7fc
Merge remote-tracking branch 'upstream/develop' into SimonBrandner/fe…
SimonBrandner Jul 14, 2022
fded4fa
Switch to stable prefixes for MSC2285
SimonBrandner Jul 14, 2022
5c3f27e
Merge remote-tracking branch 'upstream/develop' into SimonBrandner/fe…
SimonBrandner Jul 30, 2022
578d24c
Make sure `inNodeView()` works in tests
SimonBrandner Aug 3, 2022
db69f9e
Switch to stable `msc2285`
SimonBrandner Aug 3, 2022
db72558
Write tests
SimonBrandner Aug 3, 2022
769b14d
Merge branch 'SimonBrandner/feat/disable-rr' into SimonBrandner/feat/…
SimonBrandner Aug 3, 2022
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 14 additions & 11 deletions src/components/structures/TimelinePanel.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -965,25 +965,26 @@ class TimelinePanel extends React.Component<IProps, IState> {
this.lastRMSentEventId = this.state.readMarkerEventId;

const roomId = this.props.timelineSet.room.roomId;
const hiddenRR = SettingsStore.getValue("feature_hidden_read_receipts", roomId);
const sendRRs = SettingsStore.getValue("sendReadReceipts", roomId);

debuglog(
`Sending Read Markers for ${this.props.timelineSet.room.roomId}: `,
`rm=${this.state.readMarkerEventId} `,
`rr=${sendRRs ? lastReadEvent?.getId() : null} `,
`prr=${lastReadEvent?.getId()}`,

debuglog('Sending Read Markers for ',
this.props.timelineSet.room.roomId,
'rm', this.state.readMarkerEventId,
lastReadEvent ? 'rr ' + lastReadEvent.getId() : '',
' hidden:' + hiddenRR,
);
MatrixClientPeg.get().setRoomReadMarkers(
roomId,
this.state.readMarkerEventId,
hiddenRR ? null : lastReadEvent, // Could be null, in which case no RR is sent
lastReadEvent, // Could be null, in which case no private RR is sent
sendRRs ? lastReadEvent : null, // Public read receipt (could be null)
lastReadEvent, // Private read receipt (could be null)
).catch((e) => {
// /read_markers API is not implemented on this HS, fallback to just RR
if (e.errcode === 'M_UNRECOGNIZED' && lastReadEvent) {
return MatrixClientPeg.get().sendReadReceipt(
lastReadEvent,
hiddenRR ? ReceiptType.ReadPrivate : ReceiptType.Read,
sendRRs ? ReceiptType.Read : ReceiptType.ReadPrivate,
).catch((e) => {
logger.error(e);
this.lastRRSentEventId = undefined;
Expand Down Expand Up @@ -1575,8 +1576,10 @@ class TimelinePanel extends React.Component<IProps, IState> {
const isNodeInView = (node) => {
if (node) {
const boundingRect = node.getBoundingClientRect();
if ((allowPartial && boundingRect.top < wrapperRect.bottom) ||
(!allowPartial && boundingRect.bottom < wrapperRect.bottom)) {
if (
(allowPartial && boundingRect.top <= wrapperRect.bottom) ||
(!allowPartial && boundingRect.bottom <= wrapperRect.bottom)
) {
return true;
}
}
Expand Down
9 changes: 9 additions & 0 deletions src/components/views/elements/SettingsFlag.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ interface IProps {
// XXX: once design replaces all toggles make this the default
useCheckbox?: boolean;
disabled?: boolean;
disabledDescription?: string;
hideIfCannotSet?: boolean;
onChange?(checked: boolean): void;
}
Expand Down Expand Up @@ -84,6 +85,13 @@ export default class SettingsFlag extends React.Component<IProps, IState> {
: SettingsStore.getDisplayName(this.props.name, this.props.level);
const description = SettingsStore.getDescription(this.props.name);

let disabledDescription: JSX.Element;
if (this.props.disabled && this.props.disabledDescription) {
disabledDescription = <div className="mx_SettingsFlag_microcopy">
{ this.props.disabledDescription }
</div>;
}

if (this.props.useCheckbox) {
return <StyledCheckbox
checked={this.state.value}
Expand All @@ -100,6 +108,7 @@ export default class SettingsFlag extends React.Component<IProps, IState> {
{ description && <div className="mx_SettingsFlag_microcopy">
{ description }
</div> }
{ disabledDescription }
</label>
<ToggleSwitch
checked={this.state.value}
Expand Down
16 changes: 0 additions & 16 deletions src/components/views/settings/tabs/user/LabsUserSettingsTab.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,6 @@ export class LabsSettingToggle extends React.Component<ILabsSettingToggleProps>
}

interface IState {
showHiddenReadReceipts: boolean;
showJumpToDate: boolean;
showExploringPublicSpaces: boolean;
}
Expand All @@ -58,10 +57,6 @@ export default class LabsUserSettingsTab extends React.Component<{}, IState> {

const cli = MatrixClientPeg.get();

cli.doesServerSupportUnstableFeature("org.matrix.msc2285").then((showHiddenReadReceipts) => {
this.setState({ showHiddenReadReceipts });
});

cli.doesServerSupportUnstableFeature("org.matrix.msc3030").then((showJumpToDate) => {
this.setState({ showJumpToDate });
});
Expand All @@ -71,7 +66,6 @@ export default class LabsUserSettingsTab extends React.Component<{}, IState> {
});

this.state = {
showHiddenReadReceipts: false,
showJumpToDate: false,
showExploringPublicSpaces: false,
};
Expand Down Expand Up @@ -121,16 +115,6 @@ export default class LabsUserSettingsTab extends React.Component<{}, IState> {
/>,
);

if (this.state.showHiddenReadReceipts) {
groups.getOrCreate(LabGroup.Messaging, []).push(
<SettingsFlag
key="feature_hidden_read_receipts"
name="feature_hidden_read_receipts"
level={SettingLevel.DEVICE}
/>,
);
}

if (this.state.showJumpToDate) {
groups.getOrCreate(LabGroup.Messaging, []).push(
<SettingsFlag
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,58 +29,67 @@ import { UserTab } from "../../../dialogs/UserTab";
import { OpenToTabPayload } from "../../../../../dispatcher/payloads/OpenToTabPayload";
import { Action } from "../../../../../dispatcher/actions";
import SdkConfig from "../../../../../SdkConfig";
import { MatrixClientPeg } from "../../../../../MatrixClientPeg";
import { showUserOnboardingPage } from "../../../user-onboarding/UserOnboardingPage";

interface IProps {
closeSettingsFn(success: boolean): void;
}

interface IState {
disablingReadReceiptsSupported: boolean;
autocompleteDelay: string;
readMarkerInViewThresholdMs: string;
readMarkerOutOfViewThresholdMs: string;
}

export default class PreferencesUserSettingsTab extends React.Component<IProps, IState> {
static ROOM_LIST_SETTINGS = [
private static ROOM_LIST_SETTINGS = [
'breadcrumbs',
];

static SPACES_SETTINGS = [
private static SPACES_SETTINGS = [
"Spaces.allRoomsInHome",
];

static KEYBINDINGS_SETTINGS = [
private static KEYBINDINGS_SETTINGS = [
'ctrlFForSearch',
];

static COMPOSER_SETTINGS = [
private static PRESENCE_SETTINGS = [
"sendTypingNotifications",
// sendReadReceipts
];

private static COMPOSER_SETTINGS = [
'MessageComposerInput.autoReplaceEmoji',
'MessageComposerInput.useMarkdown',
'MessageComposerInput.suggestEmoji',
'sendTypingNotifications',
'MessageComposerInput.ctrlEnterToSend',
'MessageComposerInput.surroundWith',
'MessageComposerInput.showStickersButton',
'MessageComposerInput.insertTrailingColon',
];

static TIME_SETTINGS = [
private static TIME_SETTINGS = [
'showTwelveHourTimestamps',
'alwaysShowTimestamps',
];
static CODE_BLOCKS_SETTINGS = [

private static CODE_BLOCKS_SETTINGS = [
'enableSyntaxHighlightLanguageDetection',
'expandCodeByDefault',
'showCodeLineNumbers',
];
static IMAGES_AND_VIDEOS_SETTINGS = [

private static IMAGES_AND_VIDEOS_SETTINGS = [
'urlPreviewsEnabled',
'autoplayGifs',
'autoplayVideo',
'showImages',
];
static TIMELINE_SETTINGS = [

private static TIMELINE_SETTINGS = [
'showTypingNotifications',
'showRedactions',
'showReadReceipts',
Expand All @@ -93,7 +102,8 @@ export default class PreferencesUserSettingsTab extends React.Component<IProps,
'scrollToBottomOnMessageSent',
'useOnlyCurrentProfiles',
];
static GENERAL_SETTINGS = [

private static GENERAL_SETTINGS = [
'promptBeforeInviteUnknownUsers',
// Start automatically after startup (electron-only)
// Autocomplete delay (niche text box)
Expand All @@ -103,6 +113,7 @@ export default class PreferencesUserSettingsTab extends React.Component<IProps,
super(props);

this.state = {
disablingReadReceiptsSupported: false,
autocompleteDelay:
SettingsStore.getValueAt(SettingLevel.DEVICE, 'autocompleteDelay').toString(10),
readMarkerInViewThresholdMs:
Expand All @@ -112,6 +123,14 @@ export default class PreferencesUserSettingsTab extends React.Component<IProps,
};
}

public async componentDidMount(): Promise<void> {
this.setState({
disablingReadReceiptsSupported: (
await MatrixClientPeg.get().doesServerSupportUnstableFeature("org.matrix.msc2285.stable")
),
});
}

private onAutocompleteDelayChange = (e: React.ChangeEvent<HTMLInputElement>) => {
this.setState({ autocompleteDelay: e.target.value });
SettingsStore.setValue("autocompleteDelay", null, SettingLevel.DEVICE, e.target.value);
Expand Down Expand Up @@ -185,6 +204,20 @@ export default class PreferencesUserSettingsTab extends React.Component<IProps,
{ this.renderGroup(PreferencesUserSettingsTab.TIME_SETTINGS) }
</div>

<div className="mx_SettingsTab_section">
<span className="mx_SettingsTab_subheading">{ _t("Presence") }</span>
<span className="mx_SettingsTab_subsectionText">
{ _t("Choose what others can see from your presence.") }
</span>
<SettingsFlag
disabled={!this.state.disablingReadReceiptsSupported}
disabledDescription={_t("Your server doesn't support disabling sending read receipts.")}
name="sendReadReceipts"
level={SettingLevel.ACCOUNT}
/>
{ this.renderGroup(PreferencesUserSettingsTab.PRESENCE_SETTINGS) }
</div>

<div className="mx_SettingsTab_section">
<span className="mx_SettingsTab_subheading">{ _t("Composer") }</span>
{ this.renderGroup(PreferencesUserSettingsTab.COMPOSER_SETTINGS) }
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -304,7 +304,7 @@ export default class SecurityUserSettingsTab extends React.Component<IProps, ISt
<div className="mx_SettingsTab_subsectionText">
<p>
{ _t("Share anonymous data to help us identify issues. Nothing personal. " +
"No third parties.") }
"No third parties.") }
</p>
<AccessibleButton
kind="link"
Expand Down
5 changes: 4 additions & 1 deletion src/i18n/strings/en_EN.json
Original file line number Diff line number Diff line change
Expand Up @@ -898,7 +898,7 @@
"Use new room breadcrumbs": "Use new room breadcrumbs",
"Right panel stays open (defaults to room member list)": "Right panel stays open (defaults to room member list)",
"Jump to date (adds /jumptodate and jump to date headers)": "Jump to date (adds /jumptodate and jump to date headers)",
"Don't send read receipts": "Don't send read receipts",
"Send read receipts": "Send read receipts",
"Right-click message context menu": "Right-click message context menu",
"Location sharing - pin drop": "Location sharing - pin drop",
"Live Location Sharing (temporary implementation: locations persist in room history)": "Live Location Sharing (temporary implementation: locations persist in room history)",
Expand Down Expand Up @@ -1538,6 +1538,9 @@
"Keyboard shortcuts": "Keyboard shortcuts",
"To view all keyboard shortcuts, <a>click here</a>.": "To view all keyboard shortcuts, <a>click here</a>.",
"Displaying time": "Displaying time",
"Presence": "Presence",
"Choose what others can see from your presence.": "Choose what others can see from your presence.",
"Your server doesn't support disabling sending read receipts.": "Your server doesn't support disabling sending read receipts.",
"Composer": "Composer",
"Code blocks": "Code blocks",
"Images, GIFs and videos": "Images, GIFs and videos",
Expand Down
8 changes: 4 additions & 4 deletions src/settings/Settings.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -401,10 +401,10 @@ export const SETTINGS: {[setting: string]: ISetting} = {
supportedLevels: LEVELS_ACCOUNT_SETTINGS,
default: null,
},
"feature_hidden_read_receipts": {
supportedLevels: LEVELS_FEATURE,
displayName: _td("Don't send read receipts"),
default: false,
"sendReadReceipts": {
supportedLevels: LEVELS_ACCOUNT_SETTINGS,
displayName: _td("Send read receipts"),
default: true,
},
"feature_message_right_click_context_menu": {
isFeature: true,
Expand Down
Loading