Factor lightbox out into hook/context (#1919)
This commit is contained in:
parent
03b20c70e4
commit
e749f2f3a5
10 changed files with 152 additions and 104 deletions
86
src/state/lightbox.tsx
Normal file
86
src/state/lightbox.tsx
Normal file
|
@ -0,0 +1,86 @@
|
|||
import React from 'react'
|
||||
import {AppBskyActorDefs} from '@atproto/api'
|
||||
|
||||
interface Lightbox {
|
||||
name: string
|
||||
}
|
||||
|
||||
export class ProfileImageLightbox implements Lightbox {
|
||||
name = 'profile-image'
|
||||
constructor(public profile: AppBskyActorDefs.ProfileViewDetailed) {}
|
||||
}
|
||||
|
||||
interface ImagesLightboxItem {
|
||||
uri: string
|
||||
alt?: string
|
||||
}
|
||||
|
||||
export class ImagesLightbox implements Lightbox {
|
||||
name = 'images'
|
||||
constructor(public images: ImagesLightboxItem[], public index: number) {}
|
||||
setIndex(index: number) {
|
||||
this.index = index
|
||||
}
|
||||
}
|
||||
|
||||
const LightboxContext = React.createContext<{
|
||||
activeLightbox: Lightbox | null
|
||||
}>({
|
||||
activeLightbox: null,
|
||||
})
|
||||
|
||||
const LightboxControlContext = React.createContext<{
|
||||
openLightbox: (lightbox: Lightbox) => void
|
||||
closeLightbox: () => void
|
||||
}>({
|
||||
openLightbox: () => {},
|
||||
closeLightbox: () => {},
|
||||
})
|
||||
|
||||
export function Provider({children}: React.PropsWithChildren<{}>) {
|
||||
const [activeLightbox, setActiveLightbox] = React.useState<Lightbox | null>(
|
||||
null,
|
||||
)
|
||||
|
||||
const openLightbox = React.useCallback(
|
||||
(lightbox: Lightbox) => {
|
||||
setActiveLightbox(lightbox)
|
||||
},
|
||||
[setActiveLightbox],
|
||||
)
|
||||
|
||||
const closeLightbox = React.useCallback(() => {
|
||||
setActiveLightbox(null)
|
||||
}, [setActiveLightbox])
|
||||
|
||||
const state = React.useMemo(
|
||||
() => ({
|
||||
activeLightbox,
|
||||
}),
|
||||
[activeLightbox],
|
||||
)
|
||||
|
||||
const methods = React.useMemo(
|
||||
() => ({
|
||||
openLightbox,
|
||||
closeLightbox,
|
||||
}),
|
||||
[openLightbox, closeLightbox],
|
||||
)
|
||||
|
||||
return (
|
||||
<LightboxContext.Provider value={state}>
|
||||
<LightboxControlContext.Provider value={methods}>
|
||||
{children}
|
||||
</LightboxControlContext.Provider>
|
||||
</LightboxContext.Provider>
|
||||
)
|
||||
}
|
||||
|
||||
export function useLightbox() {
|
||||
return React.useContext(LightboxContext)
|
||||
}
|
||||
|
||||
export function useLightboxControls() {
|
||||
return React.useContext(LightboxControlContext)
|
||||
}
|
|
@ -1,6 +1,6 @@
|
|||
import React from 'react'
|
||||
import {AppBskyActorDefs, AppBskyGraphDefs, ModerationUI} from '@atproto/api'
|
||||
import {StyleProp, ViewStyle, DeviceEventEmitter} from 'react-native'
|
||||
import {StyleProp, ViewStyle} from 'react-native'
|
||||
import {Image as RNImage} from 'react-native-image-crop-picker'
|
||||
|
||||
import {ImageModel} from '#/state/models/media/image'
|
||||
|
@ -232,7 +232,6 @@ export function Provider({children}: React.PropsWithChildren<{}>) {
|
|||
|
||||
const openModal = React.useCallback(
|
||||
(modal: Modal) => {
|
||||
DeviceEventEmitter.emit('navigation')
|
||||
setActiveModals(activeModals => [...activeModals, modal])
|
||||
setIsModalActive(true)
|
||||
},
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
import {AppBskyActorDefs} from '@atproto/api'
|
||||
import {RootStoreModel} from '../root-store'
|
||||
import {makeAutoObservable} from 'mobx'
|
||||
import {
|
||||
|
@ -13,34 +12,7 @@ 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
|
||||
|
||||
constructor(public rootStore: RootStoreModel) {
|
||||
makeAutoObservable(this, {
|
||||
rootStore: false,
|
||||
|
@ -54,32 +26,13 @@ export class ShellUiModel {
|
|||
* (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
|
||||
}
|
||||
closeAllActiveElements() {}
|
||||
|
||||
setupLoginModals() {
|
||||
this.rootStore.onSessionReady(() => {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue