Keep scroll when navigating from page to page in the asset store (#5092)

This commit is contained in:
AlexandreS
2023-03-10 17:39:48 +01:00
committed by GitHub
parent b0c8bf9625
commit 47f15f6881
3 changed files with 48 additions and 38 deletions

View File

@@ -112,8 +112,8 @@ export const AssetStoreContext = React.createContext<AssetStoreState>({
},
navigationState: {
getCurrentPage: () => assetStoreHomePageState,
backToPreviousPage: () => {},
openHome: () => {},
backToPreviousPage: () => assetStoreHomePageState,
openHome: () => assetStoreHomePageState,
clearHistory: () => {},
openSearchResultPage: () => {},
openTagPage: tag => {},

View File

@@ -20,8 +20,8 @@ export type AssetStorePageState = {|
export type NavigationState = {|
getCurrentPage: () => AssetStorePageState,
backToPreviousPage: () => void,
openHome: () => void,
backToPreviousPage: () => AssetStorePageState,
openHome: () => AssetStorePageState,
clearHistory: () => void,
openSearchResultPage: () => void,
openTagPage: string => void,
@@ -91,13 +91,21 @@ export const useNavigation = (): NavigationState => {
getCurrentPage: () => previousPages[previousPages.length - 1],
backToPreviousPage: () => {
if (previousPages.length > 1) {
const newPreviousPages = previousPages.slice(
0,
previousPages.length - 1
);
const newCurrentPage = newPreviousPages[newPreviousPages.length - 1];
setHistory({
previousPages: previousPages.slice(0, previousPages.length - 1),
previousPages: newPreviousPages,
});
return newCurrentPage;
}
return previousPages[0];
},
openHome: () => {
setHistory({ previousPages: [assetStoreHomePageState] });
return assetStoreHomePageState;
},
clearHistory: () => {
setHistory(previousHistory => {

View File

@@ -49,7 +49,11 @@ import AlertMessage from '../UI/AlertMessage';
import AuthenticatedUserContext from '../Profile/AuthenticatedUserContext';
import PrivateAssetPackPurchaseDialog from './PrivateAssets/PrivateAssetPackPurchaseDialog';
import { LineStackLayout } from '../UI/Layout';
import { isHomePage, isSearchResultPage } from './AssetStoreNavigator';
import {
isHomePage,
isSearchResultPage,
type AssetStorePageState,
} from './AssetStoreNavigator';
import RaisedButton from '../UI/RaisedButton';
import { ResponsivePaperOrDrawer } from '../UI/ResponsivePaperOrDrawer';
import PrivateAssetsAuthorizationContext from './PrivateAssets/PrivateAssetsAuthorizationContext';
@@ -104,17 +108,16 @@ export const AssetStore = React.forwardRef<Props, AssetStoreInterface>(
assetFiltersState,
assetPackRandomOrdering,
} = React.useContext(AssetStoreContext);
const currentPage = navigationState.getCurrentPage();
const {
openedAssetPack,
openedAssetShortHeader,
openedAssetCategory,
openedPrivateAssetPackListingData,
filtersState,
} = navigationState.getCurrentPage();
const isOnHomePage = isHomePage(navigationState.getCurrentPage());
const isOnSearchResultPage = isSearchResultPage(
navigationState.getCurrentPage()
);
} = currentPage;
const isOnHomePage = isHomePage(currentPage);
const isOnSearchResultPage = isSearchResultPage(currentPage);
const searchBar = React.useRef<?SearchBarInterface>(null);
const shouldAutofocusSearchbar = useShouldAutofocusInput();
@@ -157,12 +160,11 @@ export const AssetStore = React.forwardRef<Props, AssetStoreInterface>(
openedAssetShortHeader != null
);
const setScrollUpdateIsNeeded = React.useCallback(
() => {
(page: AssetStorePageState) => {
hasAppliedSavedScrollPosition.current = false;
isAssetDetailLoading.current =
navigationState.getCurrentPage().openedAssetShortHeader != null;
isAssetDetailLoading.current = page.openedAssetShortHeader !== null;
},
[navigationState]
[]
);
const canShowFiltersPanel =
@@ -188,9 +190,9 @@ export const AssetStore = React.forwardRef<Props, AssetStoreInterface>(
if (!scrollView) {
return;
}
navigationState.getCurrentPage().scrollPosition = scrollView.getScrollPosition();
currentPage.scrollPosition = scrollView.getScrollPosition();
},
[getScrollView, navigationState]
[getScrollView, currentPage]
);
// This is also called when the asset detail page has loaded.
const applyBackScrollPosition = React.useCallback(
@@ -202,7 +204,7 @@ export const AssetStore = React.forwardRef<Props, AssetStoreInterface>(
if (!scrollView) {
return;
}
const scrollPosition = navigationState.getCurrentPage().scrollPosition;
const scrollPosition = currentPage.scrollPosition;
if (scrollPosition) scrollView.scrollToPosition(scrollPosition);
// If no saved scroll position, force scroll to 0 in case the displayed component
// is the same as the previous page so the scroll is naturally kept between pages
@@ -210,22 +212,13 @@ export const AssetStore = React.forwardRef<Props, AssetStoreInterface>(
else scrollView.scrollToPosition(0);
hasAppliedSavedScrollPosition.current = true;
},
[getScrollView, navigationState]
[getScrollView, currentPage]
);
React.useImperativeHandle(ref, () => ({
onClose: saveScrollPosition,
}));
React.useLayoutEffect(
() => {
if (!isAssetDetailLoading.current) {
applyBackScrollPosition();
}
},
[applyBackScrollPosition]
);
const onOpenDetails = React.useCallback(
(assetShortHeader: AssetShortHeader) => {
const assetPackName = openedAssetPack ? openedAssetPack.name : null;
@@ -304,6 +297,7 @@ export const AssetStore = React.forwardRef<Props, AssetStoreInterface>(
});
setSearchText('');
saveScrollPosition();
navigationState.openPrivateAssetPackInformationPage(
assetPackListingData
);
@@ -346,7 +340,6 @@ export const AssetStore = React.forwardRef<Props, AssetStoreInterface>(
() => {
if (!purchasingPrivateAssetPackListingData) return;
// Ensure the user is not already on the pack page, to trigger the effect only once.
const currentPage = navigationState.getCurrentPage();
const isOnPrivatePackPage =
currentPage.openedAssetPack &&
currentPage.openedAssetPack.id &&
@@ -369,6 +362,7 @@ export const AssetStore = React.forwardRef<Props, AssetStoreInterface>(
receivedAssetPacks,
purchasingPrivateAssetPackListingData,
navigationState,
currentPage,
saveScrollPosition,
setSearchText,
openFiltersPanelIfAppropriate,
@@ -456,14 +450,22 @@ export const AssetStore = React.forwardRef<Props, AssetStoreInterface>(
React.useLayoutEffect(
() => {
if (isOnHomePage) {
clearAllFilters(assetFiltersState);
setIsFiltersPanelOpen(false);
}
// When going back to the homepage from a page where the asset filters
// were open, we must first close the panel and then apply the scroll position.
const applyEffect = async () => {
if (isOnHomePage) {
clearAllFilters(assetFiltersState);
await setIsFiltersPanelOpen(false);
}
if (!isAssetDetailLoading.current) {
applyBackScrollPosition();
}
};
applyEffect();
},
// assetFiltersState is not stable, so don't list it.
// eslint-disable-next-line react-hooks/exhaustive-deps
[isOnHomePage]
[isOnHomePage, applyBackScrollPosition]
);
const privateAssetPackFromSameCreator: ?Array<PrivateAssetPackListingData> = React.useMemo(
@@ -496,8 +498,8 @@ export const AssetStore = React.forwardRef<Props, AssetStoreInterface>(
tooltip={t`Back to discover`}
onClick={() => {
setSearchText('');
navigationState.openHome();
setScrollUpdateIsNeeded();
const page = navigationState.openHome();
setScrollUpdateIsNeeded(page);
clearAllFilters(assetFiltersState);
setIsFiltersPanelOpen(false);
}}
@@ -551,8 +553,8 @@ export const AssetStore = React.forwardRef<Props, AssetStoreInterface>(
label={<Trans>Back</Trans>}
primary={false}
onClick={() => {
navigationState.backToPreviousPage();
setScrollUpdateIsNeeded();
const page = navigationState.backToPreviousPage();
setScrollUpdateIsNeeded(page);
}}
/>
</Column>