Refactor lightbox model to plain object (#5999)

* Refactor lightbox model to plain object

* Rename name to type
This commit is contained in:
dan
2024-10-29 20:58:38 +00:00
committed by GitHub
parent 1cfcffd79e
commit 339f45ccbb
6 changed files with 48 additions and 49 deletions
+5 -2
View File
@@ -11,7 +11,7 @@ import {useWebMediaQueries} from '#/lib/hooks/useWebMediaQueries'
import {NavigationProp} from '#/lib/routes/types' import {NavigationProp} from '#/lib/routes/types'
import {isIOS} from '#/platform/detection' import {isIOS} from '#/platform/detection'
import {Shadow} from '#/state/cache/types' import {Shadow} from '#/state/cache/types'
import {ProfileImageLightbox, useLightboxControls} from '#/state/lightbox' import {useLightboxControls} from '#/state/lightbox'
import {useSession} from '#/state/session' import {useSession} from '#/state/session'
import {LoadingPlaceholder} from '#/view/com/util/LoadingPlaceholder' import {LoadingPlaceholder} from '#/view/com/util/LoadingPlaceholder'
import {UserAvatar} from '#/view/com/util/UserAvatar' import {UserAvatar} from '#/view/com/util/UserAvatar'
@@ -54,7 +54,10 @@ let ProfileHeaderShell = ({
const onPressAvi = React.useCallback(() => { const onPressAvi = React.useCallback(() => {
const modui = moderation.ui('avatar') const modui = moderation.ui('avatar')
if (profile.avatar && !(modui.blur && modui.noOverride)) { if (profile.avatar && !(modui.blur && modui.noOverride)) {
openLightbox(new ProfileImageLightbox(profile)) openLightbox({
type: 'profile-image',
profile: profile,
})
} }
}, [openLightbox, profile, moderation]) }, [openLightbox, profile, moderation])
+11 -14
View File
@@ -1,29 +1,26 @@
import React from 'react' import React from 'react'
import {AppBskyActorDefs} from '@atproto/api' import {AppBskyActorDefs} from '@atproto/api'
import {useNonReactiveCallback} from '#/lib/hooks/useNonReactiveCallback' import {useNonReactiveCallback} from '#/lib/hooks/useNonReactiveCallback'
interface Lightbox { type ProfileImageLightbox = {
name: string type: 'profile-image'
profile: AppBskyActorDefs.ProfileViewDetailed
} }
export class ProfileImageLightbox implements Lightbox { type ImagesLightboxItem = {
name = 'profile-image'
constructor(public profile: AppBskyActorDefs.ProfileViewDetailed) {}
}
interface ImagesLightboxItem {
uri: string uri: string
alt?: string alt?: string
} }
export class ImagesLightbox implements Lightbox { type ImagesLightbox = {
name = 'images' type: 'images'
constructor(public images: ImagesLightboxItem[], public index: number) {} images: ImagesLightboxItem[]
setIndex(index: number) { index: number
this.index = index
}
} }
type Lightbox = ProfileImageLightbox | ImagesLightbox
const LightboxContext = React.createContext<{ const LightboxContext = React.createContext<{
activeLightbox: Lightbox | null activeLightbox: Lightbox | null
}>({ }>({
+9 -14
View File
@@ -9,12 +9,7 @@ import {useLingui} from '@lingui/react'
import {saveImageToMediaLibrary, shareImageModal} from '#/lib/media/manip' import {saveImageToMediaLibrary, shareImageModal} from '#/lib/media/manip'
import {colors, s} from '#/lib/styles' import {colors, s} from '#/lib/styles'
import {isIOS} from '#/platform/detection' import {isIOS} from '#/platform/detection'
import { import {useLightbox, useLightboxControls} from '#/state/lightbox'
ImagesLightbox,
ProfileImageLightbox,
useLightbox,
useLightboxControls,
} from '#/state/lightbox'
import {ScrollView} from '#/view/com/util/Views' import {ScrollView} from '#/view/com/util/Views'
import {Button} from '../util/forms/Button' import {Button} from '../util/forms/Button'
import {Text} from '../util/text/Text' import {Text} from '../util/text/Text'
@@ -32,8 +27,8 @@ export function Lightbox() {
if (!activeLightbox) { if (!activeLightbox) {
return null return null
} else if (activeLightbox.name === 'profile-image') { } else if (activeLightbox.type === 'profile-image') {
const opts = activeLightbox as ProfileImageLightbox const opts = activeLightbox
return ( return (
<ImageView <ImageView
images={[{uri: opts.profile.avatar || ''}]} images={[{uri: opts.profile.avatar || ''}]}
@@ -43,8 +38,8 @@ export function Lightbox() {
FooterComponent={LightboxFooter} FooterComponent={LightboxFooter}
/> />
) )
} else if (activeLightbox.name === 'images') { } else if (activeLightbox.type === 'images') {
const opts = activeLightbox as ImagesLightbox const opts = activeLightbox
return ( return (
<ImageView <ImageView
images={opts.images.map(img => ({...img}))} images={opts.images.map(img => ({...img}))}
@@ -107,12 +102,12 @@ function LightboxFooter({imageIndex}: {imageIndex: number}) {
let altText = '' let altText = ''
let uri = '' let uri = ''
if (lightbox.name === 'images') { if (lightbox.type === 'images') {
const opts = lightbox as ImagesLightbox const opts = lightbox
uri = opts.images[imageIndex].uri uri = opts.images[imageIndex].uri
altText = opts.images[imageIndex].alt || '' altText = opts.images[imageIndex].alt || ''
} else if (lightbox.name === 'profile-image') { } else if (lightbox.type === 'profile-image') {
const opts = lightbox as ProfileImageLightbox const opts = lightbox
uri = opts.profile.avatar || '' uri = opts.profile.avatar || ''
} }
+11 -15
View File
@@ -2,30 +2,26 @@ import React, {useCallback, useEffect, useState} from 'react'
import { import {
Image, Image,
ImageStyle, ImageStyle,
Pressable,
StyleSheet,
TouchableOpacity, TouchableOpacity,
TouchableWithoutFeedback, TouchableWithoutFeedback,
StyleSheet,
View, View,
Pressable,
ViewStyle, ViewStyle,
} from 'react-native' } from 'react-native'
import { import {
FontAwesomeIcon, FontAwesomeIcon,
FontAwesomeIconStyle, FontAwesomeIconStyle,
} from '@fortawesome/react-native-fontawesome' } from '@fortawesome/react-native-fontawesome'
import {colors, s} from 'lib/styles'
import ImageDefaultHeader from './ImageViewing/components/ImageDefaultHeader'
import {Text} from '../util/text/Text'
import {useLingui} from '@lingui/react'
import {msg} from '@lingui/macro' import {msg} from '@lingui/macro'
import { import {useLingui} from '@lingui/react'
useLightbox,
useLightboxControls,
ImagesLightbox,
ProfileImageLightbox,
} from '#/state/lightbox'
import {useWebBodyScrollLock} from '#/lib/hooks/useWebBodyScrollLock' import {useWebBodyScrollLock} from '#/lib/hooks/useWebBodyScrollLock'
import {useWebMediaQueries} from '#/lib/hooks/useWebMediaQueries' import {useWebMediaQueries} from '#/lib/hooks/useWebMediaQueries'
import {colors, s} from '#/lib/styles'
import {useLightbox, useLightboxControls} from '#/state/lightbox'
import {Text} from '../util/text/Text'
import ImageDefaultHeader from './ImageViewing/components/ImageDefaultHeader'
interface Img { interface Img {
uri: string uri: string
@@ -43,15 +39,15 @@ export function Lightbox() {
} }
const initialIndex = const initialIndex =
activeLightbox instanceof ImagesLightbox ? activeLightbox.index : 0 activeLightbox.type === 'images' ? activeLightbox.index : 0
let imgs: Img[] | undefined let imgs: Img[] | undefined
if (activeLightbox instanceof ProfileImageLightbox) { if (activeLightbox.type === 'profile-image') {
const opts = activeLightbox const opts = activeLightbox
if (opts.profile.avatar) { if (opts.profile.avatar) {
imgs = [{uri: opts.profile.avatar}] imgs = [{uri: opts.profile.avatar}]
} }
} else if (activeLightbox instanceof ImagesLightbox) { } else if (activeLightbox.type === 'images') {
const opts = activeLightbox const opts = activeLightbox
imgs = opts.images imgs = opts.images
} }
@@ -13,7 +13,7 @@ import {NavigationProp} from '#/lib/routes/types'
import {sanitizeHandle} from '#/lib/strings/handles' import {sanitizeHandle} from '#/lib/strings/handles'
import {isNative} from '#/platform/detection' import {isNative} from '#/platform/detection'
import {emitSoftReset} from '#/state/events' import {emitSoftReset} from '#/state/events'
import {ImagesLightbox, useLightboxControls} from '#/state/lightbox' import {useLightboxControls} from '#/state/lightbox'
import {useSetDrawerOpen} from '#/state/shell' import {useSetDrawerOpen} from '#/state/shell'
import {Menu_Stroke2_Corner0_Rounded as Menu} from '#/components/icons/Menu' import {Menu_Stroke2_Corner0_Rounded as Menu} from '#/components/icons/Menu'
import {StarterPack} from '#/components/icons/StarterPack' import {StarterPack} from '#/components/icons/StarterPack'
@@ -70,7 +70,11 @@ export function ProfileSubpageHeader({
if ( if (
avatar // TODO && !(view.moderation.avatar.blur && view.moderation.avatar.noOverride) avatar // TODO && !(view.moderation.avatar.blur && view.moderation.avatar.noOverride)
) { ) {
openLightbox(new ImagesLightbox([{uri: avatar}], 0)) openLightbox({
type: 'images',
images: [{uri: avatar}],
index: 0,
})
} }
}, [openLightbox, avatar]) }, [openLightbox, avatar])
+6 -2
View File
@@ -21,7 +21,7 @@ import {
} from '@atproto/api' } from '@atproto/api'
import {usePalette} from '#/lib/hooks/usePalette' import {usePalette} from '#/lib/hooks/usePalette'
import {ImagesLightbox, useLightboxControls} from '#/state/lightbox' import {useLightboxControls} from '#/state/lightbox'
import {useModerationOpts} from '#/state/preferences/moderation-opts' import {useModerationOpts} from '#/state/preferences/moderation-opts'
import {FeedSourceCard} from '#/view/com/feeds/FeedSourceCard' import {FeedSourceCard} from '#/view/com/feeds/FeedSourceCard'
import {atoms as a, useTheme} from '#/alf' import {atoms as a, useTheme} from '#/alf'
@@ -138,7 +138,11 @@ export function PostEmbeds({
aspectRatio: img.aspectRatio, aspectRatio: img.aspectRatio,
})) }))
const _openLightbox = (index: number) => { const _openLightbox = (index: number) => {
openLightbox(new ImagesLightbox(items, index)) openLightbox({
type: 'images',
images: items,
index,
})
} }
const onPressIn = (_: number) => { const onPressIn = (_: number) => {
InteractionManager.runAfterInteractions(() => { InteractionManager.runAfterInteractions(() => {