diff options
Diffstat (limited to 'src/state/models/ui')
-rw-r--r-- | src/state/models/ui/preferences.ts | 56 | ||||
-rw-r--r-- | src/state/models/ui/profile.ts | 61 | ||||
-rw-r--r-- | src/state/models/ui/shell.ts | 35 |
3 files changed, 122 insertions, 30 deletions
diff --git a/src/state/models/ui/preferences.ts b/src/state/models/ui/preferences.ts index e1c0b1f71..23668a3dc 100644 --- a/src/state/models/ui/preferences.ts +++ b/src/state/models/ui/preferences.ts @@ -1,9 +1,14 @@ import {makeAutoObservable, runInAction} from 'mobx' +import {LabelPreference as APILabelPreference} from '@atproto/api' import AwaitLock from 'await-lock' import isEqual from 'lodash.isequal' import {isObj, hasProp} from 'lib/type-guards' import {RootStoreModel} from '../root-store' -import {ComAtprotoLabelDefs, AppBskyActorDefs} from '@atproto/api' +import { + ComAtprotoLabelDefs, + AppBskyActorDefs, + ModerationOpts, +} from '@atproto/api' import {LabelValGroup} from 'lib/labeling/types' import {getLabelValueGroup} from 'lib/labeling/helpers' import { @@ -16,7 +21,8 @@ import {DEFAULT_FEEDS} from 'lib/constants' import {isIOS, deviceLocales} from 'platform/detection' import {LANGUAGES} from '../../../locale/languages' -export type LabelPreference = 'show' | 'warn' | 'hide' +// TEMP we need to permanently convert 'show' to 'ignore', for now we manually convert -prf +export type LabelPreference = APILabelPreference | 'show' const LABEL_GROUPS = [ 'nsfw', 'nudity', @@ -408,6 +414,44 @@ export class PreferencesModel { return res } + get moderationOpts(): ModerationOpts { + return { + userDid: this.rootStore.session.currentSession?.did || '', + adultContentEnabled: this.adultContentEnabled, + labels: { + // TEMP translate old settings until this UI can be migrated -prf + porn: tempfixLabelPref(this.contentLabels.nsfw), + sexual: tempfixLabelPref(this.contentLabels.suggestive), + nudity: tempfixLabelPref(this.contentLabels.nudity), + nsfl: tempfixLabelPref(this.contentLabels.gore), + corpse: tempfixLabelPref(this.contentLabels.gore), + gore: tempfixLabelPref(this.contentLabels.gore), + torture: tempfixLabelPref(this.contentLabels.gore), + 'self-harm': tempfixLabelPref(this.contentLabels.gore), + 'intolerant-race': tempfixLabelPref(this.contentLabels.hate), + 'intolerant-gender': tempfixLabelPref(this.contentLabels.hate), + 'intolerant-sexual-orientation': tempfixLabelPref( + this.contentLabels.hate, + ), + 'intolerant-religion': tempfixLabelPref(this.contentLabels.hate), + intolerant: tempfixLabelPref(this.contentLabels.hate), + 'icon-intolerant': tempfixLabelPref(this.contentLabels.hate), + spam: tempfixLabelPref(this.contentLabels.spam), + impersonation: tempfixLabelPref(this.contentLabels.impersonation), + scam: 'warn', + }, + labelers: [ + { + labeler: { + did: '', + displayName: 'Bluesky Social', + }, + labels: {}, + }, + ], + } + } + async setSavedFeeds(saved: string[], pinned: string[]) { const oldSaved = this.savedFeeds const oldPinned = this.pinnedFeeds @@ -485,3 +529,11 @@ export class PreferencesModel { this.requireAltTextEnabled = !this.requireAltTextEnabled } } + +// TEMP we need to permanently convert 'show' to 'ignore', for now we manually convert -prf +function tempfixLabelPref(pref: LabelPreference): APILabelPreference { + if (pref === 'show') { + return 'ignore' + } + return pref +} diff --git a/src/state/models/ui/profile.ts b/src/state/models/ui/profile.ts index a0249d768..9dae09ec5 100644 --- a/src/state/models/ui/profile.ts +++ b/src/state/models/ui/profile.ts @@ -6,8 +6,9 @@ import {ActorFeedsModel} from '../lists/actor-feeds' import {ListsListModel} from '../lists/lists-list' export enum Sections { - Posts = 'Posts', + PostsNoReplies = 'Posts', PostsWithReplies = 'Posts & replies', + PostsWithMedia = 'Media', CustomAlgorithms = 'Feeds', Lists = 'Lists', } @@ -46,6 +47,7 @@ export class ProfileUiModel { this.feed = new PostsFeedModel(rootStore, 'author', { actor: params.user, limit: 10, + filter: 'posts_no_replies', }) this.algos = new ActorFeedsModel(rootStore, {actor: params.user}) this.lists = new ListsListModel(rootStore, params.user) @@ -53,8 +55,9 @@ export class ProfileUiModel { get currentView(): PostsFeedModel | ActorFeedsModel | ListsListModel { if ( - this.selectedView === Sections.Posts || - this.selectedView === Sections.PostsWithReplies + this.selectedView === Sections.PostsNoReplies || + this.selectedView === Sections.PostsWithReplies || + this.selectedView === Sections.PostsWithMedia ) { return this.feed } else if (this.selectedView === Sections.Lists) { @@ -76,7 +79,11 @@ export class ProfileUiModel { } get selectorItems() { - const items = [Sections.Posts, Sections.PostsWithReplies] + const items = [ + Sections.PostsNoReplies, + Sections.PostsWithReplies, + Sections.PostsWithMedia, + ] if (this.algos.hasLoaded && !this.algos.isEmpty) { items.push(Sections.CustomAlgorithms) } @@ -90,7 +97,7 @@ export class ProfileUiModel { // If, for whatever reason, the selected view index is not available, default back to posts // This can happen when the user was focused on a view but performed an action that caused // the view to disappear (e.g. deleting the last list in their list of lists https://imgflip.com/i/7txu1y) - return this.selectorItems[this.selectedViewIndex] || Sections.Posts + return this.selectorItems[this.selectedViewIndex] || Sections.PostsNoReplies } get uiItems() { @@ -107,26 +114,25 @@ export class ProfileUiModel { }, ]) } else { - // not loading, no error, show content if ( - this.selectedView === Sections.Posts || + this.selectedView === Sections.PostsNoReplies || this.selectedView === Sections.PostsWithReplies || - this.selectedView === Sections.CustomAlgorithms + this.selectedView === Sections.PostsWithMedia ) { if (this.feed.hasContent) { - if (this.selectedView === Sections.CustomAlgorithms) { - arr = this.algos.feeds - } else if (this.selectedView === Sections.Posts) { - arr = this.feed.nonReplyFeed - } else { - arr = this.feed.slices.slice() - } + arr = this.feed.slices.slice() if (!this.feed.hasMore) { arr = arr.concat([ProfileUiModel.END_ITEM]) } } else if (this.feed.isEmpty) { arr = arr.concat([ProfileUiModel.EMPTY_ITEM]) } + } else if (this.selectedView === Sections.CustomAlgorithms) { + if (this.algos.hasContent) { + arr = this.algos.feeds + } else if (this.algos.isEmpty) { + arr = arr.concat([ProfileUiModel.EMPTY_ITEM]) + } } else if (this.selectedView === Sections.Lists) { if (this.lists.hasContent) { arr = this.lists.lists @@ -143,8 +149,9 @@ export class ProfileUiModel { get showLoadingMoreFooter() { if ( - this.selectedView === Sections.Posts || - this.selectedView === Sections.PostsWithReplies + this.selectedView === Sections.PostsNoReplies || + this.selectedView === Sections.PostsWithReplies || + this.selectedView === Sections.PostsWithMedia ) { return this.feed.hasContent && this.feed.hasMore && this.feed.isLoading } else if (this.selectedView === Sections.Lists) { @@ -157,7 +164,27 @@ export class ProfileUiModel { // = setSelectedViewIndex(index: number) { + // ViewSelector fires onSelectView on mount + if (index === this.selectedViewIndex) return + this.selectedViewIndex = index + + let filter = 'posts_no_replies' + if (this.selectedView === Sections.PostsWithReplies) { + filter = 'posts_with_replies' + } else if (this.selectedView === Sections.PostsWithMedia) { + filter = 'posts_with_media' + } + + this.feed = new PostsFeedModel(this.rootStore, 'author', { + actor: this.params.user, + limit: 10, + filter, + }) + + if (this.currentView instanceof PostsFeedModel) { + this.feed.setup() + } } async setup() { diff --git a/src/state/models/ui/shell.ts b/src/state/models/ui/shell.ts index e33a34acf..92d028c79 100644 --- a/src/state/models/ui/shell.ts +++ b/src/state/models/ui/shell.ts @@ -1,4 +1,4 @@ -import {AppBskyEmbedRecord} from '@atproto/api' +import {AppBskyEmbedRecord, ModerationUI} from '@atproto/api' import {RootStoreModel} from '../root-store' import {makeAutoObservable, runInAction} from 'mobx' import {ProfileModel} from '../content/profile' @@ -42,16 +42,21 @@ export interface ServerInputModal { onSelect: (url: string) => void } -export interface ReportPostModal { - name: 'report-post' - postUri: string - postCid: string +export interface ModerationDetailsModal { + name: 'moderation-details' + context: 'account' | 'content' + moderation: ModerationUI } -export interface ReportAccountModal { - name: 'report-account' - did: string -} +export type ReportModal = { + name: 'report' +} & ( + | { + uri: string + cid: string + } + | {did: string} +) export interface CreateOrEditMuteListModal { name: 'create-or-edit-mute-list' @@ -94,6 +99,13 @@ export interface RepostModal { isReposted: boolean } +export interface SelfLabelModal { + name: 'self-label' + labels: string[] + hasMedia: boolean + onChange: (labels: string[]) => void +} + export interface ChangeHandleModal { name: 'change-handle' onChanged: () => void @@ -146,8 +158,8 @@ export type Modal = | PreferencesHomeFeed // Moderation - | ReportAccountModal - | ReportPostModal + | ModerationDetailsModal + | ReportModal | CreateOrEditMuteListModal | ListAddRemoveUserModal @@ -157,6 +169,7 @@ export type Modal = | EditImageModal | ServerInputModal | RepostModal + | SelfLabelModal // Bluesky access | WaitlistModal |