about summary refs log tree commit diff
path: root/src/state/models/ui/shell.ts
blob: 310d4f0f91cae0784b719e1fb015913a672a2248 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
import {AppBskyActorDefs} from '@atproto/api'
import {RootStoreModel} from '../root-store'
import {makeAutoObservable, runInAction} from 'mobx'
import {
  shouldRequestEmailConfirmation,
  setEmailConfirmationRequested,
} from '#/state/shell/reminders'
import {unstable__openModal} from '#/state/modals'

export type ColorMode = 'system' | 'light' | 'dark'

export function isColorMode(v: unknown): v is ColorMode {
  return v === 'system' || v === 'light' || v === 'dark'
}

interface LightboxModel {}

export class ProfileImageLightbox implements LightboxModel {
  name = 'profile-image'
  constructor(public profile: AppBskyActorDefs.ProfileViewDetailed) {
    makeAutoObservable(this)
  }
}

interface ImagesLightboxItem {
  uri: string
  alt?: string
}

export class ImagesLightbox implements LightboxModel {
  name = 'images'
  constructor(public images: ImagesLightboxItem[], public index: number) {
    makeAutoObservable(this)
  }
  setIndex(index: number) {
    this.index = index
  }
}

export class ShellUiModel {
  isLightboxActive = false
  activeLightbox: ProfileImageLightbox | ImagesLightbox | null = null
  tickEveryMinute = Date.now()

  constructor(public rootStore: RootStoreModel) {
    makeAutoObservable(this, {
      rootStore: false,
    })

    this.setupClock()
    this.setupLoginModals()
  }

  /**
   * returns true if something was closed
   * (used by the android hardware back btn)
   */
  closeAnyActiveElement(): boolean {
    if (this.isLightboxActive) {
      this.closeLightbox()
      return true
    }
    return false
  }

  /**
   * used to clear out any modals, eg for a navigation
   */
  closeAllActiveElements() {
    if (this.isLightboxActive) {
      this.closeLightbox()
    }
  }

  openLightbox(lightbox: ProfileImageLightbox | ImagesLightbox) {
    this.rootStore.emitNavigation()
    this.isLightboxActive = true
    this.activeLightbox = lightbox
  }

  closeLightbox() {
    this.isLightboxActive = false
    this.activeLightbox = null
  }

  setupClock() {
    setInterval(() => {
      runInAction(() => {
        this.tickEveryMinute = Date.now()
      })
    }, 60_000)
  }

  setupLoginModals() {
    this.rootStore.onSessionReady(() => {
      if (shouldRequestEmailConfirmation(this.rootStore.session)) {
        unstable__openModal({name: 'verify-email', showReminder: true})
        setEmailConfirmationRequested()
      }
    })
  }
}