From 96280d5f1a24620fd12aa178027a12d81c052a34 Mon Sep 17 00:00:00 2001 From: Paul Frazee Date: Thu, 3 Aug 2023 10:25:17 -0700 Subject: [PATCH] Improve the profile preview with "swipe up to view" and local cache optimization (#1096) * Update the ProfilePreview to use a swipe-up to navigate * Use the profile cache to optimize load performance * Hack to align the header in the profile preview against the screen view * Fix profiles cache logic to ensure cache is used * Fix dark mode on profile preview --- package.json | 2 + src/Navigation.tsx | 5 +- src/state/models/cache/profiles-view.ts | 4 +- src/state/models/content/profile.ts | 26 ++++++- src/view/com/modals/Modal.tsx | 22 +++++- src/view/com/modals/ProfilePreview.tsx | 91 +++++++++++-------------- yarn.lock | 9 ++- 7 files changed, 98 insertions(+), 61 deletions(-) diff --git a/package.json b/package.json index fa5347b29d..05b08b3da1 100644 --- a/package.json +++ b/package.json @@ -96,6 +96,7 @@ "lodash.debounce": "^4.0.8", "lodash.isequal": "^4.5.0", "lodash.omit": "^4.5.0", + "lodash.once": "^4.1.1", "lodash.samplesize": "^4.2.0", "lodash.set": "^4.3.2", "lodash.shuffle": "^4.2.0", @@ -161,6 +162,7 @@ "@types/lodash.debounce": "^4.0.7", "@types/lodash.isequal": "^4.5.6", "@types/lodash.omit": "^4.5.7", + "@types/lodash.once": "^4.1.7", "@types/lodash.samplesize": "^4.2.7", "@types/lodash.set": "^4.3.7", "@types/lodash.shuffle": "^4.2.7", diff --git a/src/Navigation.tsx b/src/Navigation.tsx index 06cce0f00e..48bab182d8 100644 --- a/src/Navigation.tsx +++ b/src/Navigation.tsx @@ -125,7 +125,10 @@ function commonScreens(Stack: typeof HomeTab, unreadCountLabel?: string) { ({title: title(`@${route.params.name}`)})} + options={({route}) => ({ + title: title(`@${route.params.name}`), + animation: 'none', + })} /> (null) const pal = usePalette('default') + + const activeModal = + store.shell.activeModals[store.shell.activeModals.length - 1] + + const navigateOnce = once(navigate) + + const onBottomSheetAnimate = (fromIndex: number, toIndex: number) => { + if (activeModal?.name === 'profile-preview' && toIndex === 1) { + // begin loading the profile screen behind the scenes + navigateOnce('Profile', {name: activeModal.did}) + } + } const onBottomSheetChange = (snapPoint: number) => { if (snapPoint === -1) { store.shell.closeModal() + } else if (activeModal?.name === 'profile-preview' && snapPoint === 1) { + // ensure we navigate to Profile and close the modal + navigateOnce('Profile', {name: activeModal.did}) + store.shell.closeModal() } } const onClose = () => { @@ -45,9 +63,6 @@ export const ModalsContainer = observer(function ModalsContainer() { store.shell.closeModal() } - const activeModal = - store.shell.activeModals[store.shell.activeModals.length - 1] - useEffect(() => { if (store.shell.isModalActive) { bottomSheetRef.current?.expand() @@ -146,6 +161,7 @@ export const ModalsContainer = observer(function ModalsContainer() { } handleIndicatorStyle={{backgroundColor: pal.text.color}} handleStyle={[styles.handle, pal.view]} + onAnimate={onBottomSheetAnimate} onChange={onBottomSheetChange}> {element} diff --git a/src/view/com/modals/ProfilePreview.tsx b/src/view/com/modals/ProfilePreview.tsx index d3267644b6..4efe812259 100644 --- a/src/view/com/modals/ProfilePreview.tsx +++ b/src/view/com/modals/ProfilePreview.tsx @@ -1,63 +1,56 @@ -import React, {useState, useEffect, useCallback} from 'react' -import {StyleSheet, View} from 'react-native' +import React, {useState, useEffect} from 'react' +import {ActivityIndicator, StyleSheet, View} from 'react-native' import {observer} from 'mobx-react-lite' -import {useNavigation, StackActions} from '@react-navigation/native' -import {Text} from '../util/text/Text' +import {ThemedText} from '../util/text/ThemedText' import {useStores} from 'state/index' import {ProfileModel} from 'state/models/content/profile' import {usePalette} from 'lib/hooks/usePalette' import {useAnalytics} from 'lib/analytics/analytics' import {ProfileHeader} from '../profile/ProfileHeader' -import {Button} from '../util/forms/Button' -import {NavigationProp} from 'lib/routes/types' +import {InfoCircleIcon} from 'lib/icons' +import {useNavigationState} from '@react-navigation/native' +import {isIOS} from 'platform/detection' +import {s} from 'lib/styles' -export const snapPoints = [560] +export const snapPoints = [520, '100%'] export const Component = observer(({did}: {did: string}) => { const store = useStores() const pal = usePalette('default') - const palInverted = usePalette('inverted') - const navigation = useNavigation() const [model] = useState(new ProfileModel(store, {actor: did})) const {screen} = useAnalytics() + // track the navigator state to detect if a page-load occurred + const navState = useNavigationState(s => s) + const [initNavState] = useState(navState) + const isLoading = initNavState !== navState + useEffect(() => { screen('Profile:Preview') model.setup() }, [model, screen]) - const onPressViewProfile = useCallback(() => { - navigation.dispatch(StackActions.push('Profile', {name: model.handle})) - store.shell.closeModal() - }, [navigation, store, model]) - return ( - - + + {}} /> - - - - + + + {isLoading ? ( + + ) : ( + <> + + + Swipe up to see more + + + )} @@ -68,22 +61,18 @@ const styles = StyleSheet.create({ headerWrapper: { height: 440, }, - buttonsContainer: { - height: 120, + headerPositionAdjust: { + // HACK align the header for the profilescreen transition -prf + paddingTop: 23, }, - buttons: { - flexDirection: 'row', - gap: 8, - paddingHorizontal: 14, - paddingTop: 16, + hintWrapper: { + height: 80, }, - button: { - flex: 2, + hint: { flexDirection: 'row', justifyContent: 'center', - paddingVertical: 12, - }, - buttonWide: { - flex: 3, + gap: 8, + paddingHorizontal: 14, + borderRadius: 6, }, }) diff --git a/yarn.lock b/yarn.lock index 3f4a534e1e..ea1c1e966b 100644 --- a/yarn.lock +++ b/yarn.lock @@ -6343,6 +6343,13 @@ dependencies: "@types/lodash" "*" +"@types/lodash.once@^4.1.7": + version "4.1.7" + resolved "https://registry.yarnpkg.com/@types/lodash.once/-/lodash.once-4.1.7.tgz#84bc1f711725f6cd6d8be04365623141e09bc007" + integrity sha512-XWhnXzWkxoleOoXKmzUtep8vT+wiiQQgmPD+wzG0yO0bdlszmnqHRb2WiY5hK/8V0DTet1+z9DJj9cnbdAhWng== + dependencies: + "@types/lodash" "*" + "@types/lodash.samplesize@^4.2.7": version "4.2.7" resolved "https://registry.yarnpkg.com/@types/lodash.samplesize/-/lodash.samplesize-4.2.7.tgz#15784dd9e54aa1bf043552bdb533b83fcf50b82f" @@ -13912,7 +13919,7 @@ lodash.omit@^4.5.0: resolved "https://registry.yarnpkg.com/lodash.omit/-/lodash.omit-4.5.0.tgz#6eb19ae5a1ee1dd9df0b969e66ce0b7fa30b5e60" integrity sha512-XeqSp49hNGmlkj2EJlfrQFIzQ6lXdNro9sddtQzcJY8QaoC2GO0DT7xaIokHeyM+mIT0mPMlPvkYzg2xCuHdZg== -lodash.once@^4.0.0: +lodash.once@^4.0.0, lodash.once@^4.1.1: version "4.1.1" resolved "https://registry.yarnpkg.com/lodash.once/-/lodash.once-4.1.1.tgz#0dd3971213c7c56df880977d504c88fb471a97ac" integrity sha512-Sb487aTOCr9drQVL8pIxOzVhafOjZN9UU54hiN8PU3uAiSV7lx1yYNpbNmex2PK6dSJoNTSJUUswT651yww3Mg==