From c5222db38b4520d495d942ae0b6e57d631b40d7b Mon Sep 17 00:00:00 2001 From: Ansh Date: Mon, 24 Apr 2023 16:45:02 -0700 Subject: [PATCH] memoize things, clean code, and replace deprecated resizeMode with contentFit (#526) --- src/view/com/notifications/FeedItem.tsx | 63 +++++++------ src/view/com/util/UserAvatar.tsx | 114 +++++++++++++----------- 2 files changed, 97 insertions(+), 80 deletions(-) diff --git a/src/view/com/notifications/FeedItem.tsx b/src/view/com/notifications/FeedItem.tsx index 02dea420..a5c0ecba 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(false) - const itemHref = React.useMemo(() => { + const [isAuthorsExpanded, setAuthorsExpanded] = useState(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 @@ -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 ( { + useEffect(() => { Animated.timing(heightInterp, { toValue: visible ? 1 : 0, duration: 200, useNativeDriver: false, }).start() }, [heightInterp, visible]) + return ( { - 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, - }), - ) - }, - }, - { - testID: 'changeAvatarRemoveBtn', - label: 'Remove', - icon: ['far', 'trash-can'] as IconProp, - onPress: async () => { - onSelectNewAvatar?.(null) - }, - }, - ] + multiple: false, + }) - const warning = React.useMemo(() => { + 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) + }, + }, + ], + [ + onSelectNewAvatar, + requestCameraAccessIfNeeded, + requestPhotoAccessIfNeeded, + store, + ], + ) + + const warning = useMemo(() => { if (!hasWarning) { - return <> + return null } return ( @@ -156,7 +164,7 @@ export function UserAvatar({ {warning}