Make clear notifications work with threads (#9575)

This commit is contained in:
Germain 2022-11-15 10:27:13 +00:00 committed by GitHub
parent e66027cd0c
commit c10339ad68
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
5 changed files with 241 additions and 237 deletions

View file

@ -42,7 +42,7 @@ import AccessibleButton from "../elements/AccessibleButton";
import TagComposer from "../elements/TagComposer";
import { objectClone } from "../../../utils/objects";
import { arrayDiff } from "../../../utils/arrays";
import { getLocalNotificationAccountDataEventType } from "../../../utils/notifications";
import { clearAllNotifications, getLocalNotificationAccountDataEventType } from "../../../utils/notifications";
// TODO: this "view" component still has far too much application logic in it,
// which should be factored out to other files.
@ -112,6 +112,8 @@ interface IState {
desktopNotifications: boolean;
desktopShowBody: boolean;
audioNotifications: boolean;
clearingNotifications: boolean;
}
export default class Notifications extends React.PureComponent<IProps, IState> {
@ -126,6 +128,7 @@ export default class Notifications extends React.PureComponent<IProps, IState> {
desktopNotifications: SettingsStore.getValue("notificationsEnabled"),
desktopShowBody: SettingsStore.getValue("notificationBodyEnabled"),
audioNotifications: SettingsStore.getValue("audioNotificationsEnabled"),
clearingNotifications: false,
};
this.settingWatchers = [
@ -177,8 +180,12 @@ export default class Notifications extends React.PureComponent<IProps, IState> {
])).reduce((p, c) => Object.assign(c, p), {});
this.setState<keyof Omit<IState,
"deviceNotificationsEnabled" | "desktopNotifications" | "desktopShowBody" | "audioNotifications">
>({
"deviceNotificationsEnabled" |
"desktopNotifications" |
"desktopShowBody" |
"audioNotifications" |
"clearingNotifications"
>>({
...newState,
phase: Phase.Ready,
});
@ -433,17 +440,14 @@ export default class Notifications extends React.PureComponent<IProps, IState> {
}
};
private onClearNotificationsClicked = () => {
const client = MatrixClientPeg.get();
client.getRooms().forEach(r => {
if (r.getUnreadNotificationCount() > 0) {
const events = r.getLiveTimeline().getEvents();
if (events.length) {
// noinspection JSIgnoredPromiseFromCall
client.sendReadReceipt(events[events.length - 1]);
}
}
});
private onClearNotificationsClicked = async (): Promise<void> => {
try {
this.setState({ clearingNotifications: true });
const client = MatrixClientPeg.get();
await clearAllNotifications(client);
} finally {
this.setState({ clearingNotifications: false });
}
};
private async setKeywords(keywords: string[], originalRules: IAnnotatedPushRule[]) {
@ -531,7 +535,7 @@ export default class Notifications extends React.PureComponent<IProps, IState> {
private renderTopSection() {
const masterSwitch = <LabelledToggleSwitch
data-test-id='notif-master-switch'
data-testid='notif-master-switch'
value={!this.isInhibited}
label={_t("Enable notifications for this account")}
caption={_t("Turn off to disable notifications on all your devices and sessions")}
@ -546,7 +550,7 @@ export default class Notifications extends React.PureComponent<IProps, IState> {
const emailSwitches = (this.state.threepids || []).filter(t => t.medium === ThreepidMedium.Email)
.map(e => <LabelledToggleSwitch
data-test-id='notif-email-switch'
data-testid='notif-email-switch'
key={e.address}
value={this.state.pushers.some(p => p.kind === "email" && p.pushkey === e.address)}
label={_t("Enable email notifications for %(email)s", { email: e.address })}
@ -558,7 +562,7 @@ export default class Notifications extends React.PureComponent<IProps, IState> {
{ masterSwitch }
<LabelledToggleSwitch
data-test-id='notif-device-switch'
data-testid='notif-device-switch'
value={this.state.deviceNotificationsEnabled}
label={_t("Enable notifications for this device")}
onChange={checked => this.updateDeviceNotifications(checked)}
@ -567,21 +571,21 @@ export default class Notifications extends React.PureComponent<IProps, IState> {
{ this.state.deviceNotificationsEnabled && (<>
<LabelledToggleSwitch
data-test-id='notif-setting-notificationsEnabled'
data-testid='notif-setting-notificationsEnabled'
value={this.state.desktopNotifications}
onChange={this.onDesktopNotificationsChanged}
label={_t('Enable desktop notifications for this session')}
disabled={this.state.phase === Phase.Persisting}
/>
<LabelledToggleSwitch
data-test-id='notif-setting-notificationBodyEnabled'
data-testid='notif-setting-notificationBodyEnabled'
value={this.state.desktopShowBody}
onChange={this.onDesktopShowBodyChanged}
label={_t('Show message in desktop notification')}
disabled={this.state.phase === Phase.Persisting}
/>
<LabelledToggleSwitch
data-test-id='notif-setting-audioNotificationsEnabled'
data-testid='notif-setting-audioNotificationsEnabled'
value={this.state.audioNotifications}
onChange={this.onAudioNotificationsChanged}
label={_t('Enable audible notifications for this session')}
@ -605,8 +609,10 @@ export default class Notifications extends React.PureComponent<IProps, IState> {
) {
clearNotifsButton = <AccessibleButton
onClick={this.onClearNotificationsClicked}
disabled={this.state.clearingNotifications}
kind='danger'
className='mx_UserNotifSettings_clearNotifsButton'
data-testid="clear-notifications"
>{ _t("Clear notifications") }</AccessibleButton>;
}
@ -653,7 +659,7 @@ export default class Notifications extends React.PureComponent<IProps, IState> {
const fieldsetRows = this.state.vectorPushRules[category].map(r =>
<fieldset
key={category + r.ruleId}
data-test-id={category + r.ruleId}
data-testid={category + r.ruleId}
className='mx_UserNotifSettings_gridRowContainer'
>
<legend className='mx_UserNotifSettings_gridRowLabel'>{ r.description }</legend>
@ -678,7 +684,7 @@ export default class Notifications extends React.PureComponent<IProps, IState> {
}
return <>
<div data-test-id={`notif-section-${category}`} className='mx_UserNotifSettings_grid'>
<div data-testid={`notif-section-${category}`} className='mx_UserNotifSettings_grid'>
<span className='mx_UserNotifSettings_gridRowLabel mx_UserNotifSettings_gridRowHeading'>{ sectionName }</span>
<span className='mx_UserNotifSettings_gridColumnLabel'>{ VectorStateToLabel[VectorState.Off] }</span>
<span className='mx_UserNotifSettings_gridColumnLabel'>{ VectorStateToLabel[VectorState.On] }</span>
@ -715,7 +721,7 @@ export default class Notifications extends React.PureComponent<IProps, IState> {
// Ends up default centered
return <Spinner />;
} else if (this.state.phase === Phase.Error) {
return <p data-test-id='error-message'>{ _t("There was an error loading your notification settings.") }</p>;
return <p data-testid='error-message'>{ _t("There was an error loading your notification settings.") }</p>;
}
return <div className='mx_UserNotifSettings'>