This repository has been archived by the owner on Sep 11, 2024. It is now read-only.
-
-
Notifications
You must be signed in to change notification settings - Fork 829
Apply strictNullChecks
to src/components/views/settings
#10724
Merged
Merged
Changes from all commits
Commits
Show all changes
26 commits
Select commit
Hold shift + click to select a range
3365fba
VoiceUserSettingsTab
befd834
strictNullChecks in everything except notifications
a55049a
strictNullChecks in Notifications
065aa86
test JoinRuleSettings room upgrade
446b14d
test SecureBackupPanel changes
91a56ab
broken Notifications tests
3dc0766
try killing all modals before test
90a4a43
Merge branch 'develop' into kerry/25230/flaky-securityroomsettingstab…
c12abc4
Merge branch 'develop' into kerry/25217/snc-views-settings
c5df9ba
remove annoying test
7806450
lint
872ebcc
fix code smell
4099965
Revert "remove annoying test"
09ca8ab
Merge branch 'kerry/25230/flaky-securityroomsettingstab-test' into ke…
4af9364
add test for adding and removing keywords from notifications
717b0f2
strict
8f1136a
Merge branch 'develop' into kerry/25217/snc-views-settings
0fb353c
Merge branch 'develop' into kerry/25217/snc-views-settings
e3b67b7
Merge branch 'develop' into kerry/25217/snc-views-settings
e64c996
Merge branch 'develop' into kerry/25217/snc-views-settings
299f71c
tests
6442f61
test setting keywords when disabled
7aaca9b
securebackuppanel test reset
efc33d8
Merge branch 'develop' into kerry/25217/snc-views-settings
4bef48d
strict for SecureBackupPanel-test
d729674
test setting input device in voice settings
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -167,7 +167,7 @@ const maximumVectorState = ( | |
if (!definition.syncedRuleIds?.length) { | ||
return undefined; | ||
} | ||
const vectorState = definition.syncedRuleIds.reduce<VectorState | undefined>((maxVectorState, ruleId) => { | ||
const vectorState = definition.syncedRuleIds.reduce<VectorState>((maxVectorState, ruleId) => { | ||
// already set to maximum | ||
if (maxVectorState === VectorState.Loud) { | ||
return maxVectorState; | ||
|
@@ -177,12 +177,15 @@ const maximumVectorState = ( | |
const syncedRuleVectorState = definition.ruleToVectorState(syncedRule); | ||
// if syncedRule is 'louder' than current maximum | ||
// set maximum to louder vectorState | ||
if (OrderedVectorStates.indexOf(syncedRuleVectorState) > OrderedVectorStates.indexOf(maxVectorState)) { | ||
if ( | ||
syncedRuleVectorState && | ||
OrderedVectorStates.indexOf(syncedRuleVectorState) > OrderedVectorStates.indexOf(maxVectorState) | ||
) { | ||
return syncedRuleVectorState; | ||
} | ||
} | ||
return maxVectorState; | ||
}, definition.ruleToVectorState(rule)); | ||
}, definition.ruleToVectorState(rule)!); | ||
|
||
return vectorState; | ||
}; | ||
|
@@ -281,7 +284,7 @@ export default class Notifications extends React.PureComponent<IProps, IState> { | |
} | ||
|
||
private async refreshRules(): Promise<Partial<IState>> { | ||
const ruleSets = await MatrixClientPeg.get().getPushRules(); | ||
const ruleSets = await MatrixClientPeg.get().getPushRules()!; | ||
const categories: Record<string, RuleClass> = { | ||
[RuleId.Master]: RuleClass.Master, | ||
|
||
|
@@ -316,7 +319,7 @@ export default class Notifications extends React.PureComponent<IProps, IState> { | |
// noinspection JSUnfilteredForInLoop | ||
const kind = k as PushRuleKind; | ||
|
||
for (const r of ruleSets.global[kind]) { | ||
for (const r of ruleSets.global[kind]!) { | ||
const rule: IAnnotatedPushRule = Object.assign(r, { kind }); | ||
const category = categories[rule.rule_id] ?? RuleClass.Other; | ||
|
||
|
@@ -344,7 +347,7 @@ export default class Notifications extends React.PureComponent<IProps, IState> { | |
preparedNewState.vectorPushRules[category] = []; | ||
for (const rule of defaultRules[category]) { | ||
const definition: VectorPushRuleDefinition = VectorPushRulesDefinitions[rule.rule_id]; | ||
const vectorState = definition.ruleToVectorState(rule); | ||
const vectorState = definition.ruleToVectorState(rule)!; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Maybe add an explanation why we are sure that |
||
preparedNewState.vectorPushRules[category]!.push({ | ||
ruleId: rule.rule_id, | ||
rule, | ||
|
@@ -441,8 +444,7 @@ export default class Notifications extends React.PureComponent<IProps, IState> { | |
} else { | ||
const pusher = this.state.pushers?.find((p) => p.kind === "email" && p.pushkey === email); | ||
if (pusher) { | ||
pusher.kind = null; // flag for delete | ||
await MatrixClientPeg.get().setPusher(pusher); | ||
await MatrixClientPeg.get().removePusher(pusher.pushkey, pusher.app_id); | ||
} | ||
} | ||
|
||
|
@@ -539,34 +541,37 @@ export default class Notifications extends React.PureComponent<IProps, IState> { | |
} | ||
}; | ||
|
||
private async setKeywords(keywords: string[], originalRules: IAnnotatedPushRule[]): Promise<void> { | ||
private async setKeywords( | ||
unsafeKeywords: (string | undefined)[], | ||
originalRules: IAnnotatedPushRule[], | ||
): Promise<void> { | ||
try { | ||
// De-duplicate and remove empties | ||
keywords = filterBoolean(Array.from(new Set(keywords))); | ||
const oldKeywords = filterBoolean(Array.from(new Set(originalRules.map((r) => r.pattern)))); | ||
const keywords = filterBoolean<string>(Array.from(new Set(unsafeKeywords))); | ||
const oldKeywords = filterBoolean<string>(Array.from(new Set(originalRules.map((r) => r.pattern)))); | ||
|
||
// Note: Technically because of the UI interaction (at the time of writing), the diff | ||
// will only ever be +/-1 so we don't really have to worry about efficiently handling | ||
// tons of keyword changes. | ||
|
||
const diff = arrayDiff(oldKeywords, keywords); | ||
const diff = arrayDiff<string>(oldKeywords, keywords); | ||
|
||
for (const word of diff.removed) { | ||
for (const rule of originalRules.filter((r) => r.pattern === word)) { | ||
await MatrixClientPeg.get().deletePushRule("global", rule.kind, rule.rule_id); | ||
} | ||
} | ||
|
||
let ruleVectorState = this.state.vectorKeywordRuleInfo?.vectorState; | ||
let ruleVectorState = this.state.vectorKeywordRuleInfo!.vectorState; | ||
if (ruleVectorState === VectorState.Off) { | ||
// When the current global keywords rule is OFF, we need to look at | ||
// the flavor of existing rules to apply the same actions | ||
// when creating the new rule. | ||
if (originalRules.length) { | ||
ruleVectorState = PushRuleVectorState.contentRuleVectorStateKind(originalRules[0]) ?? undefined; | ||
} else { | ||
ruleVectorState = VectorState.On; // default | ||
} | ||
const existingRuleVectorState = originalRules.length | ||
? PushRuleVectorState.contentRuleVectorStateKind(originalRules[0]) | ||
: undefined; | ||
// set to same state as existing rule, or default to On | ||
ruleVectorState = existingRuleVectorState ?? VectorState.On; //default | ||
} | ||
const kind = PushRuleKind.ContentSpecific; | ||
for (const word of diff.added) { | ||
|
@@ -588,6 +593,10 @@ export default class Notifications extends React.PureComponent<IProps, IState> { | |
} | ||
|
||
private onKeywordAdd = (keyword: string): void => { | ||
// should not encounter this | ||
if (!this.state.vectorKeywordRuleInfo) { | ||
throw new Error("Notification data is incomplete."); | ||
} | ||
const originalRules = objectClone(this.state.vectorKeywordRuleInfo.rules); | ||
|
||
// We add the keyword immediately as a sort of local echo effect | ||
|
@@ -606,14 +615,18 @@ export default class Notifications extends React.PureComponent<IProps, IState> { | |
}, | ||
async (): Promise<void> => { | ||
await this.setKeywords( | ||
this.state.vectorKeywordRuleInfo.rules.map((r) => r.pattern), | ||
this.state.vectorKeywordRuleInfo!.rules.map((r) => r.pattern), | ||
originalRules, | ||
); | ||
}, | ||
); | ||
}; | ||
|
||
private onKeywordRemove = (keyword: string): void => { | ||
// should not encounter this | ||
if (!this.state.vectorKeywordRuleInfo) { | ||
throw new Error("Notification data is incomplete."); | ||
} | ||
const originalRules = objectClone(this.state.vectorKeywordRuleInfo.rules); | ||
|
||
// We remove the keyword immediately as a sort of local echo effect | ||
|
@@ -627,7 +640,7 @@ export default class Notifications extends React.PureComponent<IProps, IState> { | |
}, | ||
async (): Promise<void> => { | ||
await this.setKeywords( | ||
this.state.vectorKeywordRuleInfo.rules.map((r) => r.pattern), | ||
this.state.vectorKeywordRuleInfo!.rules.map((r) => r.pattern), | ||
originalRules, | ||
); | ||
}, | ||
|
@@ -749,9 +762,10 @@ export default class Notifications extends React.PureComponent<IProps, IState> { | |
|
||
let keywordComposer: JSX.Element | undefined; | ||
if (category === RuleClass.VectorMentions) { | ||
const tags = filterBoolean<string>(this.state.vectorKeywordRuleInfo?.rules.map((r) => r.pattern) || []); | ||
keywordComposer = ( | ||
<TagComposer | ||
tags={this.state.vectorKeywordRuleInfo?.rules.map((r) => r.pattern)} | ||
tags={tags} | ||
onAdd={this.onKeywordAdd} | ||
onRemove={this.onKeywordRemove} | ||
disabled={this.state.phase === Phase.Persisting} | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe add an explanation why we are sure that
ruleSets.global[kind]
is defined