diff options
author | Eric Bailey <git@esb.lol> | 2023-08-23 15:40:15 -0500 |
---|---|---|
committer | GitHub <noreply@github.com> | 2023-08-23 13:40:15 -0700 |
commit | b6317d4ce7a6c27787b625fdde6e387e4368d5d6 (patch) | |
tree | 0aa2b6aa2a63897081d4623986e86ae595e291b0 /src/state/models/ui/preferences.ts | |
parent | acad8cb4555760ca858830a4b916d2bf80c1b7b4 (diff) | |
download | voidsky-b6317d4ce7a6c27787b625fdde6e387e4368d5d6.tar.zst |
Improve handling of unselecting languanges in composer language menu (#1093)
* allow toggling off/on multiple from main composer lang menu * fix dropdown styles for long labels * udpate model to use new string field * update language UI * save langs to history on submit * remove edit * clean up use new fields * default to deviceLocales * fix default valu * feedback * use radio icon
Diffstat (limited to 'src/state/models/ui/preferences.ts')
-rw-r--r-- | src/state/models/ui/preferences.ts | 75 |
1 files changed, 61 insertions, 14 deletions
diff --git a/src/state/models/ui/preferences.ts b/src/state/models/ui/preferences.ts index 23668a3dc..e9ffe28c2 100644 --- a/src/state/models/ui/preferences.ts +++ b/src/state/models/ui/preferences.ts @@ -33,6 +33,9 @@ const LABEL_GROUPS = [ 'impersonation', ] const VISIBILITY_VALUES = ['show', 'warn', 'hide'] +const DEFAULT_LANG_CODES = (deviceLocales || []) + .concat(['en', 'ja', 'pt', 'de']) + .slice(0, 6) export class LabelPreferencesModel { nsfw: LabelPreference = 'hide' @@ -51,7 +54,8 @@ export class LabelPreferencesModel { export class PreferencesModel { adultContentEnabled = !isIOS contentLanguages: string[] = deviceLocales || [] - postLanguages: string[] = deviceLocales || [] + postLanguage: string = deviceLocales[0] || 'en' + postLanguageHistory: string[] = DEFAULT_LANG_CODES contentLabels = new LabelPreferencesModel() savedFeeds: string[] = [] pinnedFeeds: string[] = [] @@ -71,7 +75,8 @@ export class PreferencesModel { serialize() { return { contentLanguages: this.contentLanguages, - postLanguages: this.postLanguages, + postLanguage: this.postLanguage, + postLanguageHistory: this.postLanguageHistory, contentLabels: this.contentLabels, savedFeeds: this.savedFeeds, pinnedFeeds: this.pinnedFeeds, @@ -101,16 +106,23 @@ export class PreferencesModel { // default to the device languages this.contentLanguages = deviceLocales } - // check if post languages in preferences exist, otherwise default to device languages + if (hasProp(v, 'postLanguage') && typeof v.postLanguage === 'string') { + this.postLanguage = v.postLanguage + } else { + // default to the device languages + this.postLanguage = deviceLocales[0] || 'en' + } if ( - hasProp(v, 'postLanguages') && - Array.isArray(v.postLanguages) && - typeof v.postLanguages.every(item => typeof item === 'string') + hasProp(v, 'postLanguageHistory') && + Array.isArray(v.postLanguageHistory) && + typeof v.postLanguageHistory.every(item => typeof item === 'string') ) { - this.postLanguages = v.postLanguages + this.postLanguageHistory = v.postLanguageHistory + .concat(DEFAULT_LANG_CODES) + .slice(0, 6) } else { - // default to the device languages - this.postLanguages = deviceLocales + // default to a starter set + this.postLanguageHistory = DEFAULT_LANG_CODES } // check if content labels in preferences exist, then hydrate if (hasProp(v, 'contentLabels') && typeof v.contentLabels === 'object') { @@ -279,7 +291,8 @@ export class PreferencesModel { runInAction(() => { this.contentLabels = new LabelPreferencesModel() this.contentLanguages = deviceLocales - this.postLanguages = deviceLocales + this.postLanguage = deviceLocales ? deviceLocales.join(',') : 'en' + this.postLanguageHistory = DEFAULT_LANG_CODES this.savedFeeds = [] this.pinnedFeeds = [] }) @@ -305,20 +318,54 @@ export class PreferencesModel { } } + /** + * A getter that splits `this.postLanguage` into an array of strings. + * + * This was previously the main field on this model, but now we're + * concatenating lang codes to make multi-selection a little better. + */ + get postLanguages() { + // filter out empty strings if exist + return this.postLanguage.split(',').filter(Boolean) + } + hasPostLanguage(code2: string) { return this.postLanguages.includes(code2) } togglePostLanguage(code2: string) { if (this.hasPostLanguage(code2)) { - this.postLanguages = this.postLanguages.filter(lang => lang !== code2) + this.postLanguage = this.postLanguages + .filter(lang => lang !== code2) + .join(',') } else { - this.postLanguages = this.postLanguages.concat([code2]) + // sort alphabetically for deterministic comparison in context menu + this.postLanguage = this.postLanguages + .concat([code2]) + .sort((a, b) => a.localeCompare(b)) + .join(',') } } - setPostLanguage(code2: string) { - this.postLanguages = [code2] + setPostLanguage(commaSeparatedLangCodes: string) { + this.postLanguage = commaSeparatedLangCodes + } + + /** + * Saves whatever language codes are currently selected into a history array, + * which is then used to populate the language selector menu. + */ + savePostLanguageToHistory() { + // filter out duplicate `this.postLanguage` if exists, and prepend + // value to start of array + this.postLanguageHistory = [this.postLanguage] + .concat( + this.postLanguageHistory.filter( + commaSeparatedLangCodes => + commaSeparatedLangCodes !== this.postLanguage, + ), + ) + .slice(0, 6) } getReadablePostLanguages() { |