GYU: Account Notification Settings (#11008)

* Implement new notification settings UI

* Sort new keywords at the front

* Make ts-strict happier

* Make ts-strict happier

* chore: fixed lint issues

* update beta card

* Fix issue with the user settings test

* chore: fixed lint issues

* Add tests for notification settings

* chore: fixed lint issues

* fix: spurious text failures

* improve tests further

* make ts-strict happier

* improve tests further

* Reduce uncovered conditions

* Correct snapshot

* even more test coverage

* Fix an issue with inverted rules

* Update res/css/views/settings/tabs/_SettingsIndent.pcss

Co-authored-by: Šimon Brandner <simon.bra.ag@gmail.com>

* Fix license headers

* Improve i18n

* make linters happier

* Improve beta labels

* improve i18n

* chore: fixed lint issues

* fix: more lint issues

* Update snapshots to match changed text

* Update text as requested

* Remove labs image

* Update snapshots

* Correct an issue with one of the tests

* fix: keyword reconcilation code

* Determine mute status more accurately

* Address review comments

* Prevent duplicate updates

* Fix missing license header

* slight change to avoid ts-strict complaining

* fix test issue caused by previous merge

---------

Co-authored-by: Šimon Brandner <simon.bra.ag@gmail.com>
This commit is contained in:
Janne Mareike Koschinski
2023-06-29 17:46:31 +02:00
committed by GitHub
parent 95283d21bb
commit f62fe2626c
25 changed files with 3797 additions and 33 deletions

View File

@@ -196,6 +196,11 @@ export function reconcileNotificationSettings(
}
}
const mentionActions = NotificationUtils.encodeActions({
notify: true,
sound: model.sound.mentions,
highlight: true,
});
const contentRules = pushRules.global.content?.filter((rule) => !rule.rule_id.startsWith(".")) ?? [];
const newKeywords = new Set(model.keywords);
for (const rule of contentRules) {
@@ -204,12 +209,27 @@ export function reconcileNotificationSettings(
rule_id: rule.rule_id,
kind: PushRuleKind.ContentSpecific,
});
} else if (rule.enabled !== model.mentions.keywords) {
changes.updated.push({
rule_id: rule.rule_id,
kind: PushRuleKind.ContentSpecific,
enabled: model.mentions.keywords,
});
} else {
let changed = false;
if (rule.enabled !== model.mentions.keywords) {
changed = true;
} else if (rule.actions !== undefined) {
const originalActions = NotificationUtils.decodeActions(rule.actions);
const actions = NotificationUtils.decodeActions(mentionActions);
if (originalActions === null || actions === null) {
changed = true;
} else if (!deepCompare(actions, originalActions)) {
changed = true;
}
}
if (changed) {
changes.updated.push({
rule_id: rule.rule_id,
kind: PushRuleKind.ContentSpecific,
enabled: model.mentions.keywords,
actions: mentionActions,
});
}
}
newKeywords.delete(rule.pattern!);
}
@@ -220,7 +240,7 @@ export function reconcileNotificationSettings(
default: false,
enabled: model.mentions.keywords,
pattern: keyword,
actions: StandardActions.ACTION_NOTIFY,
actions: mentionActions,
});
}

View File

@@ -37,6 +37,22 @@ function shouldNotify(rules: (IPushRule | null | undefined | false)[]): boolean
return false;
}
function isMuted(rules: (IPushRule | null | undefined | false)[]): boolean {
if (rules.length === 0) {
return false;
}
for (const rule of rules) {
if (rule === null || rule === undefined || rule === false || !rule.enabled) {
continue;
}
const actions = NotificationUtils.decodeActions(rule.actions);
if (actions !== null && !actions.notify && actions.highlight !== true && actions.sound === undefined) {
return true;
}
}
return false;
}
function determineSound(rules: (IPushRule | null | undefined | false)[]): string | undefined {
for (const rule of rules) {
if (rule === null || rule === undefined || rule === false || !rule.enabled) {
@@ -74,7 +90,7 @@ export function toNotificationSettings(
people: determineSound(dmRules),
},
activity: {
bot_notices: shouldNotify([standardRules.get(RuleId.SuppressNotices)]),
bot_notices: !isMuted([standardRules.get(RuleId.SuppressNotices)]),
invite: shouldNotify([standardRules.get(RuleId.InviteToSelf)]),
status_event: shouldNotify([standardRules.get(RuleId.MemberEvent), standardRules.get(RuleId.Tombstone)]),
},