Skip to content

Commit

Permalink
ux: Reduce popin on first load of inventory tabs (#2124)
Browse files Browse the repository at this point in the history
  • Loading branch information
NigelBreslaw authored Jul 23, 2024
1 parent 9b8e4a7 commit ed16399
Show file tree
Hide file tree
Showing 2 changed files with 57 additions and 45 deletions.
78 changes: 44 additions & 34 deletions native/app/inventory/pages/InventoryPage.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { useIsFocused } from "@react-navigation/native";
import { FlashList } from "@shopify/flash-list";
import { useEffect, useRef } from "react";
import { useEffect, useRef, useState } from "react";
import { RefreshControl, ScrollView, StyleSheet, View, useWindowDimensions } from "react-native";

import { getFullProfile } from "@/app/bungie/BungieApi.ts";
Expand Down Expand Up @@ -39,14 +39,38 @@ const getItemType = (item: UISections) => item.type;

export default function InventoryPage({ inventoryPageEnum, pageEstimatedFlashListItemSize }: Props) {
"use memo";
const currentListIndex = useGGStore((state) => state.currentListIndex);
const { width } = useWindowDimensions();
const HOME_WIDTH = width;

const listRefs = useRef<(FlashList<UISections> | null)[]>([]);
const pagedScrollRef = useRef<ScrollView>(null);
const isFocused = useIsFocused();

const jumpToCharacterRef = useRef<() => void>(() => {
const currentListIndex = useGGStore.getState().currentListIndex;
const posX = HOME_WIDTH * currentListIndex;
console.log("jump to character", currentListIndex, posX);
pagedScrollRef.current?.scrollTo({ x: posX, y: 0, animated: false });
});

const listMovedRef = useRef<(toY: number, allPages?: boolean) => void>((toY: number, allPages = false) => {
if (lastOffsetY !== toY) {
useGGStore.getState().setPageOffsetY(inventoryPageEnum, toY);
const currentListIndex = useGGStore.getState().currentListIndex;

lastOffsetY = toY;
for (let i = 0; i < listRefs.current.length; i++) {
if (i === currentListIndex && !allPages) {
continue;
}
const lRef = listRefs.current[i];
if (lRef) {
lRef.scrollToOffset({ offset: toY, animated: false });
}
}
}
});

const styles = StyleSheet.create({
container: {},
page: {
Expand All @@ -55,11 +79,6 @@ export default function InventoryPage({ inventoryPageEnum, pageEstimatedFlashLis
},
});

const jumpToCharacter = () => {
const posX = HOME_WIDTH * currentListIndex;
pagedScrollRef.current?.scrollTo({ x: posX, y: 0, animated: false });
};

useEffect(() => {
const unsubscribe = useGGStore.subscribe(
(state) => state.animateToInventoryPage,
Expand All @@ -73,37 +92,28 @@ export default function InventoryPage({ inventoryPageEnum, pageEstimatedFlashLis
return unsubscribe;
}, [isFocused, HOME_WIDTH]);

const initialAccountDataReady = useGGStore((state) => state.initialAccountDataReady);
const [pageReady, setPageReady] = useState(false);

useEffect(() => {
if (pageReady) {
jumpToCharacterRef.current();
}
}, [pageReady]);

// biome-ignore lint/correctness/useExhaustiveDependencies: <explanation>
useEffect(() => {
if (isFocused && initialAccountDataReady) {
if (isFocused && pageReady) {
jumpToCharacterRef.current();
useGGStore.getState().setCurrentInventoryPage(inventoryPageEnum);
jumpToCharacter();
}
}, [isFocused, initialAccountDataReady]);
}, [isFocused, pageReady, inventoryPageEnum]);

let lastOffsetY = 0;

const listMoved = (toY: number) => {
if (lastOffsetY !== toY) {
lastOffsetY = toY;
for (let i = 0; i < listRefs.current.length; i++) {
if (i === currentListIndex) {
continue;
}
const lRef = listRefs.current[i];
if (lRef) {
lRef.scrollToOffset({ offset: toY, animated: false });
}
}
}
};

const debouncedMove = debounce(listMoved, 40);
const debouncedMove = debounce(listMovedRef.current, 40);
const debounceListIndex = debounce(calcCurrentListIndex, 40);

function getData(inventoryPage: InventoryPageEnums): UISections[][] | undefined {
console.log("getData", inventoryPage);
switch (inventoryPage) {
case InventoryPageEnums.Armor:
return useGGStore((state) => state.ggArmor);
Expand All @@ -118,18 +128,13 @@ export default function InventoryPage({ inventoryPageEnum, pageEstimatedFlashLis
const pullRefreshing = useGGStore((state) => state.pullRefreshing);

return (
<View style={rootStyles.root}>
<View style={[rootStyles.root, { opacity: pageReady ? 1 : 0 }]}>
<ScrollView
horizontal
pagingEnabled
scrollEventThrottle={32}
onScroll={(e) => debounceListIndex(e.nativeEvent.contentOffset.x, HOME_WIDTH)}
ref={pagedScrollRef}
onContentSizeChange={(e) => {
if (e > 0) {
useGGStore.getState().setInitialAccountDataReady();
}
}}
>
{mainData.map((_c, index) => {
return (
Expand All @@ -150,6 +155,11 @@ export default function InventoryPage({ inventoryPageEnum, pageEstimatedFlashLis
}}
/>
}
onLoad={() => {
if (index === mainData.length - 1) {
setPageReady(true);
}
}}
data={mainData[index]}
renderItem={UiCellRenderItem}
keyExtractor={keyExtractor}
Expand Down
24 changes: 13 additions & 11 deletions native/app/store/Account/AccountSlice.ts
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,6 @@ export interface AccountSlice {
lastRefreshTime: number;
animateToInventoryPage: { index: number; animate: boolean };
activateInventoryMenu: boolean;
initialAccountDataReady: boolean;

weaponsSortSubmenuOpen: boolean;
armorSortSubmenuOpen: boolean;
Expand Down Expand Up @@ -107,12 +106,12 @@ export interface AccountSlice {
secondaryComponentsMintedTimestamp: Date;

setStateHydrated: () => void;
setInitialAccountDataReady: () => void;
setAppStartupTime: (appStartupTime: number) => void;
setRefreshing: (refreshing: boolean) => void;
setPullRefreshing: (pullRefreshing: boolean) => void;
setCurrentListIndex: (payload: number) => void;
setPageOffsetY: (inventoryPage: InventoryPageEnums, offsetY: number) => void;
getPageOffsetY: (inventoryPage: InventoryPageEnums) => number;
setJumpToIndex: (payload: { index: number; animate: boolean }) => void;
setWeaponsSort: (weaponsSort: WeaponsSort) => void;
setArmorSort: (armorSort: ArmorSort) => void;
Expand Down Expand Up @@ -145,7 +144,6 @@ export const createAccountSlice: StateCreator<IStore, [], [], AccountSlice> = (s
animateToInventoryPage: { index: 0, animate: false },
showingPerks: false,
activateInventoryMenu: false,
initialAccountDataReady: false,

weaponsSortSubmenuOpen: false,
armorSortSubmenuOpen: false,
Expand Down Expand Up @@ -175,14 +173,6 @@ export const createAccountSlice: StateCreator<IStore, [], [], AccountSlice> = (s
rawProfileData: null,

setStateHydrated: () => set({ stateHydrated: true }),
setInitialAccountDataReady: () => {
if (!get().initialAccountDataReady) {
set({ initialAccountDataReady: true });
if (get().itemsDefinitionReady && get().bungieDefinitionsReady) {
set({ appReady: true });
}
}
},
setAppStartupTime: (appStartupTime) => set({ appStartupTime }),
setRefreshing: (refreshing) => set({ refreshing }),
setPullRefreshing: (pullRefreshing) => set({ pullRefreshing }),
Expand All @@ -195,6 +185,18 @@ export const createAccountSlice: StateCreator<IStore, [], [], AccountSlice> = (s
set({ generalPageOffsetY: offsetY });
}
},
getPageOffsetY: (inventoryPage) => {
if (inventoryPage === InventoryPageEnums.Weapons) {
return get().weaponsPageOffsetY;
}
if (inventoryPage === InventoryPageEnums.Armor) {
return get().armorPageOffsetY;
}
if (inventoryPage === InventoryPageEnums.General) {
return get().generalPageOffsetY;
}
return 0;
},
setCurrentListIndex: (currentListIndex) => {
set({ currentListIndex, animateToInventoryPage: { index: currentListIndex, animate: false } });
},
Expand Down

0 comments on commit ed16399

Please sign in to comment.