[APP-690] better handling of post languages language filtering (#893)

* add SelectLangBtn

* memoized objects that are created to reduce re-creation on re-render

* add langs when uploading post

* only send the top 3 languages otherwise backend will throw error

* mv ContentLanguagesSettings to folder

* add post languages settings modal and state

* fix typos

* modify feed manip to also check langs label on post

* Fix tests

* Remove log

* Update feed-manip.ts

* Fix syntax errors

* UI tuneups

* Show the currently selected languages in the composer

* fix linting

* Use a bcp-47 matching function

* Fix a duplicate language issue

* Fix web

* Dont include lang in prompt

* Make select language btn an observer

* Keep device languages on top of language selection UIs

* Fix android build settings

* Enforce a max of 3 languages in posts

* Fix tests

* Fix types

---------

Co-authored-by: Paul Frazee <pfrazee@gmail.com>
This commit is contained in:
Ansh 2023-06-23 10:48:52 -07:00 committed by GitHub
parent 9b19a95e63
commit 08804f265e
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
19 changed files with 525 additions and 176 deletions

View file

@ -1,5 +1,4 @@
import {makeAutoObservable, runInAction} from 'mobx'
import {getLocales} from 'expo-localization'
import AwaitLock from 'await-lock'
import isEqual from 'lodash.isequal'
import {isObj, hasProp} from 'lib/type-guards'
@ -14,9 +13,8 @@ import {
ALWAYS_WARN_LABEL_GROUP,
} from 'lib/labeling/const'
import {DEFAULT_FEEDS} from 'lib/constants'
import {isIOS} from 'platform/detection'
const deviceLocales = getLocales()
import {isIOS, deviceLocales} from 'platform/detection'
import {LANGUAGES} from '../../../locale/languages'
export type LabelPreference = 'show' | 'warn' | 'hide'
const LABEL_GROUPS = [
@ -46,8 +44,8 @@ export class LabelPreferencesModel {
export class PreferencesModel {
adultContentEnabled = !isIOS
contentLanguages: string[] =
deviceLocales?.map?.(locale => locale.languageCode) || []
contentLanguages: string[] = deviceLocales || []
postLanguages: string[] = deviceLocales || []
contentLabels = new LabelPreferencesModel()
savedFeeds: string[] = []
pinnedFeeds: string[] = []
@ -66,6 +64,7 @@ export class PreferencesModel {
serialize() {
return {
contentLanguages: this.contentLanguages,
postLanguages: this.postLanguages,
contentLabels: this.contentLabels,
savedFeeds: this.savedFeeds,
pinnedFeeds: this.pinnedFeeds,
@ -83,19 +82,33 @@ export class PreferencesModel {
*/
hydrate(v: unknown) {
if (isObj(v)) {
// check if content languages in preferences exist, otherwise default to device languages
if (
hasProp(v, 'contentLanguages') &&
Array.isArray(v.contentLanguages) &&
typeof v.contentLanguages.every(item => typeof item === 'string')
) {
this.contentLanguages = v.contentLanguages
}
if (hasProp(v, 'contentLabels') && typeof v.contentLabels === 'object') {
Object.assign(this.contentLabels, v.contentLabels)
} else {
// default to the device languages
this.contentLanguages = deviceLocales.map(locale => locale.languageCode)
this.contentLanguages = deviceLocales
}
// check if post languages in preferences exist, otherwise default to device languages
if (
hasProp(v, 'postLanguages') &&
Array.isArray(v.postLanguages) &&
typeof v.postLanguages.every(item => typeof item === 'string')
) {
this.postLanguages = v.postLanguages
} else {
// default to the device languages
this.postLanguages = deviceLocales
}
// check if content labels in preferences exist, then hydrate
if (hasProp(v, 'contentLabels') && typeof v.contentLabels === 'object') {
Object.assign(this.contentLabels, v.contentLabels)
}
// check if saved feeds in preferences, then hydrate
if (
hasProp(v, 'savedFeeds') &&
Array.isArray(v.savedFeeds) &&
@ -103,6 +116,7 @@ export class PreferencesModel {
) {
this.savedFeeds = v.savedFeeds
}
// check if pinned feeds in preferences exist, then hydrate
if (
hasProp(v, 'pinnedFeeds') &&
Array.isArray(v.pinnedFeeds) &&
@ -110,24 +124,28 @@ export class PreferencesModel {
) {
this.pinnedFeeds = v.pinnedFeeds
}
// check if home feed replies are enabled in preferences, then hydrate
if (
hasProp(v, 'homeFeedRepliesEnabled') &&
typeof v.homeFeedRepliesEnabled === 'boolean'
) {
this.homeFeedRepliesEnabled = v.homeFeedRepliesEnabled
}
// check if home feed replies threshold is enabled in preferences, then hydrate
if (
hasProp(v, 'homeFeedRepliesThreshold') &&
typeof v.homeFeedRepliesThreshold === 'number'
) {
this.homeFeedRepliesThreshold = v.homeFeedRepliesThreshold
}
// check if home feed reposts are enabled in preferences, then hydrate
if (
hasProp(v, 'homeFeedRepostsEnabled') &&
typeof v.homeFeedRepostsEnabled === 'boolean'
) {
this.homeFeedRepostsEnabled = v.homeFeedRepostsEnabled
}
// check if home feed quote posts are enabled in preferences, then hydrate
if (
hasProp(v, 'homeFeedQuotePostsEnabled') &&
typeof v.homeFeedQuotePostsEnabled === 'boolean'
@ -245,7 +263,8 @@ export class PreferencesModel {
try {
runInAction(() => {
this.contentLabels = new LabelPreferencesModel()
this.contentLanguages = deviceLocales.map(locale => locale.languageCode)
this.contentLanguages = deviceLocales
this.postLanguages = deviceLocales
this.savedFeeds = []
this.pinnedFeeds = []
})
@ -271,6 +290,26 @@ export class PreferencesModel {
}
}
hasPostLanguage(code2: string) {
return this.postLanguages.includes(code2)
}
togglePostLanguage(code2: string) {
if (this.hasPostLanguage(code2)) {
this.postLanguages = this.postLanguages.filter(lang => lang !== code2)
} else {
this.postLanguages = this.postLanguages.concat([code2])
}
}
getReadablePostLanguages() {
const all = this.postLanguages.map(code2 => {
const lang = LANGUAGES.find(l => l.code2 === code2)
return lang ? lang.name : code2
})
return all.join(', ')
}
async setContentLabelPref(
key: keyof LabelPreferencesModel,
value: LabelPreference,

View file

@ -111,6 +111,10 @@ export interface ContentLanguagesSettingsModal {
name: 'content-languages-settings'
}
export interface PostLanguagesSettingsModal {
name: 'post-languages-settings'
}
export interface PreferencesHomeFeed {
name: 'preferences-home-feed'
}
@ -125,6 +129,7 @@ export type Modal =
// Curation
| ContentFilteringSettingsModal
| ContentLanguagesSettingsModal
| PostLanguagesSettingsModal
| PreferencesHomeFeed
// Moderation