diff options
Diffstat (limited to 'src/view/com/util')
-rw-r--r-- | src/view/com/util/Link.tsx | 9 | ||||
-rw-r--r-- | src/view/com/util/UserAvatar.tsx | 108 | ||||
-rw-r--r-- | src/view/com/util/images/ImageLayoutGrid.tsx | 8 |
3 files changed, 76 insertions, 49 deletions
diff --git a/src/view/com/util/Link.tsx b/src/view/com/util/Link.tsx index 6915d3e08..35524bcc6 100644 --- a/src/view/com/util/Link.tsx +++ b/src/view/com/util/Link.tsx @@ -1,5 +1,4 @@ -import React, {ComponentProps, useMemo} from 'react' -import {observer} from 'mobx-react-lite' +import React, {ComponentProps, memo, useMemo} from 'react' import { Linking, GestureResponderEvent, @@ -50,7 +49,7 @@ interface Props extends ComponentProps<typeof TouchableOpacity> { anchorNoUnderline?: boolean } -export const Link = observer(function Link({ +export const Link = memo(function Link({ testID, style, href, @@ -136,7 +135,7 @@ export const Link = observer(function Link({ ) }) -export const TextLink = observer(function TextLink({ +export const TextLink = memo(function TextLink({ testID, type = 'md', style, @@ -236,7 +235,7 @@ interface DesktopWebTextLinkProps extends TextProps { accessibilityHint?: string title?: string } -export const DesktopWebTextLink = observer(function DesktopWebTextLink({ +export const DesktopWebTextLink = memo(function DesktopWebTextLink({ testID, type = 'md', style, diff --git a/src/view/com/util/UserAvatar.tsx b/src/view/com/util/UserAvatar.tsx index d24e47499..fbc0b5e11 100644 --- a/src/view/com/util/UserAvatar.tsx +++ b/src/view/com/util/UserAvatar.tsx @@ -23,14 +23,18 @@ interface BaseUserAvatarProps { type?: Type size: number avatar?: string | null - moderation?: ModerationUI } interface UserAvatarProps extends BaseUserAvatarProps { - onSelectNewAvatar?: (img: RNImage | null) => void + moderation?: ModerationUI +} + +interface EditableUserAvatarProps extends BaseUserAvatarProps { + onSelectNewAvatar: (img: RNImage | null) => void } interface PreviewableUserAvatarProps extends BaseUserAvatarProps { + moderation?: ModerationUI did: string handle: string } @@ -106,8 +110,65 @@ export function UserAvatar({ size, avatar, moderation, - onSelectNewAvatar, }: UserAvatarProps) { + const pal = usePalette('default') + + const aviStyle = useMemo(() => { + if (type === 'algo' || type === 'list') { + return { + width: size, + height: size, + borderRadius: size > 32 ? 8 : 3, + } + } + return { + width: size, + height: size, + borderRadius: Math.floor(size / 2), + } + }, [type, size]) + + const alert = useMemo(() => { + if (!moderation?.alert) { + return null + } + return ( + <View style={[styles.alertIconContainer, pal.view]}> + <FontAwesomeIcon + icon="exclamation-circle" + style={styles.alertIcon} + size={Math.floor(size / 3)} + /> + </View> + ) + }, [moderation?.alert, size, pal]) + + return avatar && + !((moderation?.blur && isAndroid) /* android crashes with blur */) ? ( + <View style={{width: size, height: size}}> + <HighPriorityImage + testID="userAvatarImage" + style={aviStyle} + contentFit="cover" + source={{uri: avatar}} + blurRadius={moderation?.blur ? BLUR_AMOUNT : 0} + /> + {alert} + </View> + ) : ( + <View style={{width: size, height: size}}> + <DefaultAvatar type={type} size={size} /> + {alert} + </View> + ) +} + +export function EditableUserAvatar({ + type = 'user', + size, + avatar, + onSelectNewAvatar, +}: EditableUserAvatarProps) { const store = useStores() const pal = usePalette('default') const {requestCameraAccessIfNeeded} = useCameraPermission() @@ -146,7 +207,7 @@ export function UserAvatar({ return } - onSelectNewAvatar?.( + onSelectNewAvatar( await openCamera(store, { width: 1000, height: 1000, @@ -186,7 +247,7 @@ export function UserAvatar({ path: item.path, }) - onSelectNewAvatar?.(croppedImage) + onSelectNewAvatar(croppedImage) }, }, !!avatar && { @@ -203,7 +264,7 @@ export function UserAvatar({ web: 'trash', }, onPress: async () => { - onSelectNewAvatar?.(null) + onSelectNewAvatar(null) }, }, ].filter(Boolean) as DropdownItem[], @@ -216,23 +277,7 @@ export function UserAvatar({ ], ) - const alert = useMemo(() => { - if (!moderation?.alert) { - return null - } - return ( - <View style={[styles.alertIconContainer, pal.view]}> - <FontAwesomeIcon - icon="exclamation-circle" - style={styles.alertIcon} - size={Math.floor(size / 3)} - /> - </View> - ) - }, [moderation?.alert, size, pal]) - - // onSelectNewAvatar is only passed as prop on the EditProfile component - return onSelectNewAvatar ? ( + return ( <NativeDropdown testID="changeAvatarBtn" items={dropdownItems} @@ -256,23 +301,6 @@ export function UserAvatar({ /> </View> </NativeDropdown> - ) : avatar && - !((moderation?.blur && isAndroid) /* android crashes with blur */) ? ( - <View style={{width: size, height: size}}> - <HighPriorityImage - testID="userAvatarImage" - style={aviStyle} - contentFit="cover" - source={{uri: avatar}} - blurRadius={moderation?.blur ? BLUR_AMOUNT : 0} - /> - {alert} - </View> - ) : ( - <View style={{width: size, height: size}}> - <DefaultAvatar type={type} size={size} /> - {alert} - </View> ) } diff --git a/src/view/com/util/images/ImageLayoutGrid.tsx b/src/view/com/util/images/ImageLayoutGrid.tsx index 2e352d086..4aa6f28de 100644 --- a/src/view/com/util/images/ImageLayoutGrid.tsx +++ b/src/view/com/util/images/ImageLayoutGrid.tsx @@ -63,8 +63,8 @@ function ImageLayoutGridInner(props: ImageLayoutGridInnerProps) { case 4: return ( - <View style={styles.flexRow}> - <View style={{flex: 1}}> + <> + <View style={styles.flexRow}> <View style={styles.smallItem}> <GalleryItem {...props} index={0} imageStyle={styles.image} /> </View> @@ -72,7 +72,7 @@ function ImageLayoutGridInner(props: ImageLayoutGridInnerProps) { <GalleryItem {...props} index={2} imageStyle={styles.image} /> </View> </View> - <View style={{flex: 1}}> + <View style={styles.flexRow}> <View style={styles.smallItem}> <GalleryItem {...props} index={1} imageStyle={styles.image} /> </View> @@ -80,7 +80,7 @@ function ImageLayoutGridInner(props: ImageLayoutGridInnerProps) { <GalleryItem {...props} index={3} imageStyle={styles.image} /> </View> </View> - </View> + </> ) default: |