Refactor lightbox model to plain object (#5999)
* Refactor lightbox model to plain object * Rename name to type
This commit is contained in:
@@ -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
@@ -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,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 || ''
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -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])
|
||||||
|
|
||||||
|
|||||||
@@ -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(() => {
|
||||||
|
|||||||
Reference in New Issue
Block a user