diff options
author | Ansh <anshnanda10@gmail.com> | 2023-04-24 16:45:02 -0700 |
---|---|---|
committer | GitHub <noreply@github.com> | 2023-04-24 18:45:02 -0500 |
commit | c5222db38b4520d495d942ae0b6e57d631b40d7b (patch) | |
tree | 45e4c2d09c171efb96abf5118a9de2b92d003657 /src | |
parent | 1b356556c91ed07025927d4cb0be90a269396822 (diff) | |
download | voidsky-c5222db38b4520d495d942ae0b6e57d631b40d7b.tar.zst |
memoize things, clean code, and replace deprecated resizeMode with contentFit (#526)
Diffstat (limited to 'src')
-rw-r--r-- | src/view/com/notifications/FeedItem.tsx | 63 | ||||
-rw-r--r-- | src/view/com/util/UserAvatar.tsx | 110 |
2 files changed, 95 insertions, 78 deletions
diff --git a/src/view/com/notifications/FeedItem.tsx b/src/view/com/notifications/FeedItem.tsx index 02dea4204..a5c0ecba0 100644 --- a/src/view/com/notifications/FeedItem.tsx +++ b/src/view/com/notifications/FeedItem.tsx @@ -1,4 +1,4 @@ -import React from 'react' +import React, {useMemo, useState, useEffect} from 'react' import {observer} from 'mobx-react-lite' import { Animated, @@ -47,8 +47,8 @@ export const FeedItem = observer(function FeedItem({ item: NotificationsFeedItemModel }) { const pal = usePalette('default') - const [isAuthorsExpanded, setAuthorsExpanded] = React.useState<boolean>(false) - const itemHref = React.useMemo(() => { + const [isAuthorsExpanded, setAuthorsExpanded] = useState<boolean>(false) + const itemHref = useMemo(() => { if (item.isLike || item.isRepost) { const urip = new AtUri(item.subjectUri) return `/profile/${urip.host}/post/${urip.rkey}` @@ -60,7 +60,7 @@ export const FeedItem = observer(function FeedItem({ } return '' }, [item]) - const itemTitle = React.useMemo(() => { + const itemTitle = useMemo(() => { if (item.isLike || item.isRepost) { return 'Post' } else if (item.isFollow) { @@ -74,6 +74,35 @@ export const FeedItem = observer(function FeedItem({ setAuthorsExpanded(!isAuthorsExpanded) } + const authors: Author[] = useMemo(() => { + return [ + { + href: `/profile/${item.author.handle}`, + handle: item.author.handle, + displayName: item.author.displayName, + avatar: item.author.avatar, + labels: item.author.labels, + }, + ...(item.additional?.map( + ({author: {avatar, labels, handle, displayName}}) => { + return { + href: `/profile/${handle}`, + handle, + displayName, + avatar, + labels, + } + }, + ) || []), + ] + }, [ + item.additional, + item.author.avatar, + item.author.displayName, + item.author.handle, + item.author.labels, + ]) + if (item.additionalPost?.notFound) { // don't render anything if the target post was deleted or unfindable return <View /> @@ -125,30 +154,9 @@ export const FeedItem = observer(function FeedItem({ icon = 'user-plus' iconStyle = [s.blue3 as FontAwesomeIconStyle] } else { - return <></> + return null } - const authors: Author[] = [ - { - href: `/profile/${item.author.handle}`, - handle: item.author.handle, - displayName: item.author.displayName, - avatar: item.author.avatar, - labels: item.author.labels, - }, - ...(item.additional?.map( - ({author: {avatar, labels, handle, displayName}}) => { - return { - href: `/profile/${handle}`, - handle, - displayName, - avatar, - labels, - } - }, - ) || []), - ] - return ( <Link testID={`feedItem-by-${item.author.handle}`} @@ -301,13 +309,14 @@ function ExpandedAuthorsList({ const heightStyle = { height: Animated.multiply(heightInterp, targetHeight), } - React.useEffect(() => { + useEffect(() => { Animated.timing(heightInterp, { toValue: visible ? 1 : 0, duration: 200, useNativeDriver: false, }).start() }, [heightInterp, visible]) + return ( <Animated.View style={[ diff --git a/src/view/com/util/UserAvatar.tsx b/src/view/com/util/UserAvatar.tsx index e13d49e61..9c0fe9297 100644 --- a/src/view/com/util/UserAvatar.tsx +++ b/src/view/com/util/UserAvatar.tsx @@ -1,4 +1,4 @@ -import React from 'react' +import React, {useMemo} from 'react' import {StyleSheet, View} from 'react-native' import Svg, {Circle, Path} from 'react-native-svg' import {FontAwesomeIcon} from '@fortawesome/react-native-fontawesome' @@ -53,61 +53,69 @@ export function UserAvatar({ const {requestCameraAccessIfNeeded} = useCameraPermission() const {requestPhotoAccessIfNeeded} = usePhotoLibraryPermission() - const dropdownItems = [ - !isWeb && { - testID: 'changeAvatarCameraBtn', - label: 'Camera', - icon: 'camera' as IconProp, - onPress: async () => { - if (!(await requestCameraAccessIfNeeded())) { - return - } - onSelectNewAvatar?.( - await openCamera(store, { - width: 1000, - height: 1000, - cropperCircleOverlay: true, - }), - ) + const dropdownItems = useMemo( + () => [ + !isWeb && { + testID: 'changeAvatarCameraBtn', + label: 'Camera', + icon: 'camera' as IconProp, + onPress: async () => { + if (!(await requestCameraAccessIfNeeded())) { + return + } + onSelectNewAvatar?.( + await openCamera(store, { + width: 1000, + height: 1000, + cropperCircleOverlay: true, + }), + ) + }, }, - }, - { - testID: 'changeAvatarLibraryBtn', - label: 'Library', - icon: 'image' as IconProp, - onPress: async () => { - if (!(await requestPhotoAccessIfNeeded())) { - return - } - const items = await openPicker(store, { - mediaType: 'photo', - multiple: false, - }) - - onSelectNewAvatar?.( - await openCropper(store, { + { + testID: 'changeAvatarLibraryBtn', + label: 'Library', + icon: 'image' as IconProp, + onPress: async () => { + if (!(await requestPhotoAccessIfNeeded())) { + return + } + const items = await openPicker(store, { mediaType: 'photo', - path: items[0].path, - width: 1000, - height: 1000, - cropperCircleOverlay: true, - }), - ) + multiple: false, + }) + + onSelectNewAvatar?.( + await openCropper(store, { + mediaType: 'photo', + path: items[0].path, + width: 1000, + height: 1000, + cropperCircleOverlay: true, + }), + ) + }, }, - }, - { - testID: 'changeAvatarRemoveBtn', - label: 'Remove', - icon: ['far', 'trash-can'] as IconProp, - onPress: async () => { - onSelectNewAvatar?.(null) + { + testID: 'changeAvatarRemoveBtn', + label: 'Remove', + icon: ['far', 'trash-can'] as IconProp, + onPress: async () => { + onSelectNewAvatar?.(null) + }, }, - }, - ] + ], + [ + onSelectNewAvatar, + requestCameraAccessIfNeeded, + requestPhotoAccessIfNeeded, + store, + ], + ) - const warning = React.useMemo(() => { + const warning = useMemo(() => { if (!hasWarning) { - return <></> + return null } return ( <View style={[styles.warningIconContainer, pal.view]}> @@ -156,7 +164,7 @@ export function UserAvatar({ <HighPriorityImage testID="userAvatarImage" style={{width: size, height: size, borderRadius: Math.floor(size / 2)}} - resizeMode="stretch" + contentFit="cover" source={{uri: avatar}} /> {warning} |