diff options
Diffstat (limited to 'src/state/models/ui')
-rw-r--r-- | src/state/models/ui/shell.ts | 207 |
1 files changed, 207 insertions, 0 deletions
diff --git a/src/state/models/ui/shell.ts b/src/state/models/ui/shell.ts new file mode 100644 index 000000000..db6ae2eac --- /dev/null +++ b/src/state/models/ui/shell.ts @@ -0,0 +1,207 @@ +import {RootStoreModel} from '../root-store' +import {makeAutoObservable} from 'mobx' +import {ProfileViewModel} from '../profile-view' +import {isObj, hasProp} from 'lib/type-guards' +import {PickedMedia} from 'lib/media/types' + +export interface ConfirmModal { + name: 'confirm' + title: string + message: string | (() => JSX.Element) + onPressConfirm: () => void | Promise<void> +} + +export interface EditProfileModal { + name: 'edit-profile' + profileView: ProfileViewModel + onUpdate?: () => void +} + +export interface ServerInputModal { + name: 'server-input' + initialService: string + onSelect: (url: string) => void +} + +export interface ReportPostModal { + name: 'report-post' + postUri: string + postCid: string +} + +export interface ReportAccountModal { + name: 'report-account' + did: string +} + +export interface CropImageModal { + name: 'crop-image' + uri: string + onSelect: (img?: PickedMedia) => void +} + +export interface DeleteAccountModal { + name: 'delete-account' +} + +export interface RepostModal { + name: 'repost' + onRepost: () => void + onQuote: () => void + isReposted: boolean +} + +export interface ChangeHandleModal { + name: 'change-handle' + onChanged: () => void +} + +export type Modal = + | ConfirmModal + | EditProfileModal + | ServerInputModal + | ReportPostModal + | ReportAccountModal + | CropImageModal + | DeleteAccountModal + | RepostModal + | ChangeHandleModal + +interface LightboxModel {} + +export class ProfileImageLightbox implements LightboxModel { + name = 'profile-image' + constructor(public profileView: ProfileViewModel) { + makeAutoObservable(this) + } +} + +export class ImagesLightbox implements LightboxModel { + name = 'images' + constructor(public uris: string[], public index: number) { + makeAutoObservable(this) + } + setIndex(index: number) { + this.index = index + } +} + +export interface ComposerOptsPostRef { + uri: string + cid: string + text: string + author: { + handle: string + displayName?: string + avatar?: string + } +} +export interface ComposerOptsQuote { + uri: string + cid: string + text: string + indexedAt: string + author: { + handle: string + displayName?: string + avatar?: string + } +} +export interface ComposerOpts { + replyTo?: ComposerOptsPostRef + onPost?: () => void + quote?: ComposerOptsQuote +} + +export class ShellUiModel { + darkMode = false + minimalShellMode = false + isDrawerOpen = false + isModalActive = false + activeModals: Modal[] = [] + isLightboxActive = false + activeLightbox: ProfileImageLightbox | ImagesLightbox | undefined + isComposerActive = false + composerOpts: ComposerOpts | undefined + isOnboarding = false + + constructor(public rootStore: RootStoreModel) { + makeAutoObservable(this, { + serialize: false, + rootStore: false, + hydrate: false, + }) + } + + serialize(): unknown { + return { + darkMode: this.darkMode, + } + } + + hydrate(v: unknown) { + if (isObj(v)) { + if (hasProp(v, 'darkMode') && typeof v.darkMode === 'boolean') { + this.darkMode = v.darkMode + } + } + } + + setDarkMode(v: boolean) { + this.darkMode = v + } + + setMinimalShellMode(v: boolean) { + this.minimalShellMode = v + } + + openDrawer() { + this.isDrawerOpen = true + } + + closeDrawer() { + this.isDrawerOpen = false + } + + openModal(modal: Modal) { + this.rootStore.emitNavigation() + this.isModalActive = true + this.activeModals.push(modal) + } + + closeModal() { + this.activeModals.pop() + this.isModalActive = this.activeModals.length > 0 + } + + openLightbox(lightbox: ProfileImageLightbox | ImagesLightbox) { + this.rootStore.emitNavigation() + this.isLightboxActive = true + this.activeLightbox = lightbox + } + + closeLightbox() { + this.isLightboxActive = false + this.activeLightbox = undefined + } + + openComposer(opts: ComposerOpts) { + this.rootStore.emitNavigation() + this.isComposerActive = true + this.composerOpts = opts + } + + closeComposer() { + this.isComposerActive = false + this.composerOpts = undefined + } + + setOnboarding(v: boolean) { + this.isOnboarding = v + if (this.isOnboarding) { + this.rootStore.me.mainFeed.switchFeedType('suggested') + } else { + this.rootStore.me.mainFeed.switchFeedType('home') + } + } +} |