@@ -42,7 +42,7 @@ import AccessibleButton from "../elements/AccessibleButton";
42
42
import TagComposer from "../elements/TagComposer" ;
43
43
import { objectClone } from "../../../utils/objects" ;
44
44
import { arrayDiff } from "../../../utils/arrays" ;
45
- import { getLocalNotificationAccountDataEventType } from "../../../utils/notifications" ;
45
+ import { clearAllNotifications , getLocalNotificationAccountDataEventType } from "../../../utils/notifications" ;
46
46
47
47
// TODO: this "view" component still has far too much application logic in it,
48
48
// which should be factored out to other files.
@@ -112,6 +112,8 @@ interface IState {
112
112
desktopNotifications : boolean ;
113
113
desktopShowBody : boolean ;
114
114
audioNotifications : boolean ;
115
+
116
+ clearingNotifications : boolean ;
115
117
}
116
118
117
119
export default class Notifications extends React . PureComponent < IProps , IState > {
@@ -126,6 +128,7 @@ export default class Notifications extends React.PureComponent<IProps, IState> {
126
128
desktopNotifications : SettingsStore . getValue ( "notificationsEnabled" ) ,
127
129
desktopShowBody : SettingsStore . getValue ( "notificationBodyEnabled" ) ,
128
130
audioNotifications : SettingsStore . getValue ( "audioNotificationsEnabled" ) ,
131
+ clearingNotifications : false ,
129
132
} ;
130
133
131
134
this . settingWatchers = [
@@ -177,8 +180,12 @@ export default class Notifications extends React.PureComponent<IProps, IState> {
177
180
] ) ) . reduce ( ( p , c ) => Object . assign ( c , p ) , { } ) ;
178
181
179
182
this . setState < keyof Omit < IState ,
180
- "deviceNotificationsEnabled" | "desktopNotifications" | "desktopShowBody" | "audioNotifications" >
181
- > ( {
183
+ "deviceNotificationsEnabled" |
184
+ "desktopNotifications" |
185
+ "desktopShowBody" |
186
+ "audioNotifications" |
187
+ "clearingNotifications"
188
+ > > ( {
182
189
...newState ,
183
190
phase : Phase . Ready ,
184
191
} ) ;
@@ -433,17 +440,14 @@ export default class Notifications extends React.PureComponent<IProps, IState> {
433
440
}
434
441
} ;
435
442
436
- private onClearNotificationsClicked = ( ) => {
437
- const client = MatrixClientPeg . get ( ) ;
438
- client . getRooms ( ) . forEach ( r => {
439
- if ( r . getUnreadNotificationCount ( ) > 0 ) {
440
- const events = r . getLiveTimeline ( ) . getEvents ( ) ;
441
- if ( events . length ) {
442
- // noinspection JSIgnoredPromiseFromCall
443
- client . sendReadReceipt ( events [ events . length - 1 ] ) ;
444
- }
445
- }
446
- } ) ;
443
+ private onClearNotificationsClicked = async ( ) : Promise < void > => {
444
+ try {
445
+ this . setState ( { clearingNotifications : true } ) ;
446
+ const client = MatrixClientPeg . get ( ) ;
447
+ await clearAllNotifications ( client ) ;
448
+ } finally {
449
+ this . setState ( { clearingNotifications : false } ) ;
450
+ }
447
451
} ;
448
452
449
453
private async setKeywords ( keywords : string [ ] , originalRules : IAnnotatedPushRule [ ] ) {
@@ -531,7 +535,7 @@ export default class Notifications extends React.PureComponent<IProps, IState> {
531
535
532
536
private renderTopSection ( ) {
533
537
const masterSwitch = < LabelledToggleSwitch
534
- data-test-id = 'notif-master-switch'
538
+ data-testid = 'notif-master-switch'
535
539
value = { ! this . isInhibited }
536
540
label = { _t ( "Enable notifications for this account" ) }
537
541
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> {
546
550
547
551
const emailSwitches = ( this . state . threepids || [ ] ) . filter ( t => t . medium === ThreepidMedium . Email )
548
552
. map ( e => < LabelledToggleSwitch
549
- data-test-id = 'notif-email-switch'
553
+ data-testid = 'notif-email-switch'
550
554
key = { e . address }
551
555
value = { this . state . pushers . some ( p => p . kind === "email" && p . pushkey === e . address ) }
552
556
label = { _t ( "Enable email notifications for %(email)s" , { email : e . address } ) }
@@ -558,7 +562,7 @@ export default class Notifications extends React.PureComponent<IProps, IState> {
558
562
{ masterSwitch }
559
563
560
564
< LabelledToggleSwitch
561
- data-test-id = 'notif-device-switch'
565
+ data-testid = 'notif-device-switch'
562
566
value = { this . state . deviceNotificationsEnabled }
563
567
label = { _t ( "Enable notifications for this device" ) }
564
568
onChange = { checked => this . updateDeviceNotifications ( checked ) }
@@ -567,21 +571,21 @@ export default class Notifications extends React.PureComponent<IProps, IState> {
567
571
568
572
{ this . state . deviceNotificationsEnabled && ( < >
569
573
< LabelledToggleSwitch
570
- data-test-id = 'notif-setting-notificationsEnabled'
574
+ data-testid = 'notif-setting-notificationsEnabled'
571
575
value = { this . state . desktopNotifications }
572
576
onChange = { this . onDesktopNotificationsChanged }
573
577
label = { _t ( 'Enable desktop notifications for this session' ) }
574
578
disabled = { this . state . phase === Phase . Persisting }
575
579
/>
576
580
< LabelledToggleSwitch
577
- data-test-id = 'notif-setting-notificationBodyEnabled'
581
+ data-testid = 'notif-setting-notificationBodyEnabled'
578
582
value = { this . state . desktopShowBody }
579
583
onChange = { this . onDesktopShowBodyChanged }
580
584
label = { _t ( 'Show message in desktop notification' ) }
581
585
disabled = { this . state . phase === Phase . Persisting }
582
586
/>
583
587
< LabelledToggleSwitch
584
- data-test-id = 'notif-setting-audioNotificationsEnabled'
588
+ data-testid = 'notif-setting-audioNotificationsEnabled'
585
589
value = { this . state . audioNotifications }
586
590
onChange = { this . onAudioNotificationsChanged }
587
591
label = { _t ( 'Enable audible notifications for this session' ) }
@@ -605,8 +609,10 @@ export default class Notifications extends React.PureComponent<IProps, IState> {
605
609
) {
606
610
clearNotifsButton = < AccessibleButton
607
611
onClick = { this . onClearNotificationsClicked }
612
+ disabled = { this . state . clearingNotifications }
608
613
kind = 'danger'
609
614
className = 'mx_UserNotifSettings_clearNotifsButton'
615
+ data-testid = "clear-notifications"
610
616
> { _t ( "Clear notifications" ) } </ AccessibleButton > ;
611
617
}
612
618
@@ -653,7 +659,7 @@ export default class Notifications extends React.PureComponent<IProps, IState> {
653
659
const fieldsetRows = this . state . vectorPushRules [ category ] . map ( r =>
654
660
< fieldset
655
661
key = { category + r . ruleId }
656
- data-test-id = { category + r . ruleId }
662
+ data-testid = { category + r . ruleId }
657
663
className = 'mx_UserNotifSettings_gridRowContainer'
658
664
>
659
665
< legend className = 'mx_UserNotifSettings_gridRowLabel' > { r . description } </ legend >
@@ -678,7 +684,7 @@ export default class Notifications extends React.PureComponent<IProps, IState> {
678
684
}
679
685
680
686
return < >
681
- < div data-test-id = { `notif-section-${ category } ` } className = 'mx_UserNotifSettings_grid' >
687
+ < div data-testid = { `notif-section-${ category } ` } className = 'mx_UserNotifSettings_grid' >
682
688
< span className = 'mx_UserNotifSettings_gridRowLabel mx_UserNotifSettings_gridRowHeading' > { sectionName } </ span >
683
689
< span className = 'mx_UserNotifSettings_gridColumnLabel' > { VectorStateToLabel [ VectorState . Off ] } </ span >
684
690
< span className = 'mx_UserNotifSettings_gridColumnLabel' > { VectorStateToLabel [ VectorState . On ] } </ span >
@@ -715,7 +721,7 @@ export default class Notifications extends React.PureComponent<IProps, IState> {
715
721
// Ends up default centered
716
722
return < Spinner /> ;
717
723
} else if ( this . state . phase === Phase . Error ) {
718
- return < p data-test-id = 'error-message' > { _t ( "There was an error loading your notification settings." ) } </ p > ;
724
+ return < p data-testid = 'error-message' > { _t ( "There was an error loading your notification settings." ) } </ p > ;
719
725
}
720
726
721
727
return < div className = 'mx_UserNotifSettings' >
0 commit comments