seperate pools context from rest of app

This commit is contained in:
Blake Kaufman
2026-05-15 21:05:18 -04:00
parent 031aa3a982
commit 7b57a0bb1c
12 changed files with 118 additions and 63 deletions
+13 -15
View File
@@ -121,7 +121,6 @@ import { GlobalServerTimeProvider } from './context-store/serverTime';
import { AuthStatusProvider } from './context-store/authContext';
import { ActiveCustodyAccountProvider } from './context-store/activeAccount';
import { GiftProvider } from './context-store/giftContext';
import { PoolProvider } from './context-store/poolContext';
import { UserBalanceProvider } from './context-store/userBalanceContext';
import { FlashnetProvider } from './context-store/flashnetContext';
import { SavingsProvider } from './context-store/savingsContext';
@@ -170,19 +169,17 @@ function App(): JSX.Element {
<ImageCacheProvider>
<GlobalServerTimeProvider>
<GiftProvider>
<PoolProvider>
<FlashnetProvider>
<UserBalanceProvider>
<SavingsProvider>
<AnalyticsProvider>
{/* <Suspense
<FlashnetProvider>
<UserBalanceProvider>
<SavingsProvider>
<AnalyticsProvider>
{/* <Suspense
fallback={<FullLoadingScreen text={'Loading Page'} />}> */}
<ResetStack />
</AnalyticsProvider>
</SavingsProvider>
</UserBalanceProvider>
</FlashnetProvider>
</PoolProvider>
<ResetStack />
</AnalyticsProvider>
</SavingsProvider>
</UserBalanceProvider>
</FlashnetProvider>
</GiftProvider>
{/* </Suspense> */}
</GlobalServerTimeProvider>
@@ -389,8 +386,9 @@ function ResetStack(): JSX.Element | null {
} else if (POOL_DEEPLINK_REGEX.test(url)) {
const poolIdMatch = url.match(/pools\/([0-9a-f-]{36})/i);
if (poolIdMatch) {
navigationRef.current.navigate('PoolDetailScreen', {
poolId: poolIdMatch[1],
navigationRef.current.navigate('PoolsStack', {
screen: 'PoolDetailScreen',
params: {poolId: poolIdMatch[1]},
});
}
} else if (GIFT_DEEPLINK_REGEX.test(url)) {
@@ -6,8 +6,8 @@ import { useTranslation } from 'react-i18next';
import { INSET_WINDOW_WIDTH } from '../../../../constants/theme';
import { useNavigation } from '@react-navigation/native';
import { useKeysContext } from '../../../../../context-store/keys';
import { usePools } from '../../../../../context-store/poolContext';
import { useActiveCustodyAccount } from '../../../../../context-store/activeAccount';
import { updatePoolLocal } from '../../../../functions/pools/poolsStorage';
import { derivePoolWallet } from '../../../../functions/pools/derivePoolWallet';
import {
getSparkBalance,
@@ -31,7 +31,6 @@ export default function ClosePoolConfirmation({
const { accountMnemoinc } = useKeysContext();
const { currentWalletMnemoinc } = useActiveCustodyAccount();
const { sparkInformation } = useSparkWallet();
const { updatePool } = usePools();
const isMounted = useRef(true);
const { t } = useTranslation();
@@ -135,7 +134,7 @@ export default function ClosePoolConfirmation({
};
await updatePoolInDatabase(closedPool);
await updatePool(closedPool);
await updatePoolLocal(closedPool.poolId, closedPool);
setIsLoading(false);
@@ -188,7 +187,7 @@ export default function ClosePoolConfirmation({
}
await updatePoolInDatabase(closedPool);
await updatePool(closedPool);
await updatePoolLocal(closedPool.poolId, closedPool);
let tx = {
id: transferTxId,
@@ -231,7 +230,6 @@ export default function ClosePoolConfirmation({
pool,
accountMnemoinc,
currentWalletMnemoinc,
updatePool,
navigate,
getBalanceWithRetry,
sparkInformation,
@@ -109,10 +109,9 @@ export default function PoolDescriptionInput({
if (handleBackPressFunction) {
// For CustomHalfModal context (settings path)
handleBackPressFunction(() => {
navigate.replace('PoolDetailScreen', {
poolId,
pool: poolDocument,
shouldSave: true,
navigate.replace('PoolsStack', {
screen: 'PoolDetailScreen',
params: {poolId, pool: poolDocument, shouldSave: true},
});
});
} else {
@@ -124,10 +123,9 @@ export default function PoolDescriptionInput({
});
// Navigate to PoolDetailScreen after closing overlay
navigate.replace('PoolDetailScreen', {
poolId,
pool: poolDocument,
shouldSave: true,
navigate.replace('PoolsStack', {
screen: 'PoolDetailScreen',
params: {poolId, pool: poolDocument, shouldSave: true},
});
}
} catch (err) {
@@ -26,8 +26,8 @@ import { useFlashnet } from '../../../../../context-store/flashnetContext';
import { updateConfirmAnimation } from '../../../../functions/lottieViewColorTransformer';
import LottieView from 'lottie-react-native';
import { useGlobalContactsInfo } from '../../../../../context-store/globalContacts';
import { usePools } from '../../../../../context-store/poolContext';
import { Timestamp } from '@react-native-firebase/firestore';
import { saveContributionLocal } from '../../../../functions/pools/poolsStorage';
import useHandleBackPressNew from '../../../../hooks/useHandleBackPressNew';
import { useUserBalanceContext } from '../../../../../context-store/userBalanceContext';
import { useWebView } from '../../../../../context-store/webViewContext';
@@ -60,7 +60,6 @@ export default function ContributeToPoolHalfModal({
const { sparkInformation } = useSparkWallet();
const { currentWalletMnemoinc } = useActiveCustodyAccount();
const { poolInfoRef, swapUSDPriceDollars, swapLimits } = useFlashnet();
const { addContributionToCache } = usePools();
const { theme, darkModeType } = useGlobalThemeContext();
const { backgroundOffset, backgroundColor } = GetThemeColors();
const { t } = useTranslation();
@@ -320,7 +319,7 @@ export default function ContributeToPoolHalfModal({
paymentAmountSats,
);
await addContributionToCache(contribution);
await saveContributionLocal(contribution);
setStep([...step, 'success']);
} catch (err) {
@@ -60,6 +60,7 @@ export default function PoolDetailScreen(props) {
savePoolToCloud,
syncPool,
loadContributionsForPool,
updatePoolList,
} = usePools();
const { theme, darkModeType } = useGlobalThemeContext();
const { backgroundOffset, backgroundColor } = GetThemeColors();
@@ -164,8 +165,12 @@ export default function PoolDetailScreen(props) {
useFocusEffect(
useCallback(() => {
refreshPoolDetails(true);
}, [refreshPoolDetails]),
async function refreshData() {
await updatePoolList();
refreshPoolDetails(true);
}
refreshData();
}, [refreshPoolDetails, updatePoolList]),
);
const handleShare = useCallback(async () => {
@@ -1,6 +1,9 @@
import { useCallback, useState } from 'react';
import { FlatList, StyleSheet, View } from 'react-native';
import { ThemeText } from '../../../../functions/CustomElements';
import {
GlobalThemeView,
ThemeText,
} from '../../../../functions/CustomElements';
import { CENTER, CONTENT_KEYBOARD_OFFSET, SIZES } from '../../../../constants';
import { INSET_WINDOW_WIDTH, WINDOWWIDTH } from '../../../../constants/theme';
import { useFocusEffect, useNavigation } from '@react-navigation/native';
@@ -11,6 +14,7 @@ import FullLoadingScreen from '../../../../functions/CustomElements/loadingScree
import { useTranslation } from 'react-i18next';
import PoolsInfoCard from './poolsInfoCard';
import NoContentSceen from '../../../../functions/CustomElements/noContentScreen';
import CustomSettingsTopBar from '../../../../functions/CustomElements/settingsTopBar';
export default function PoolManagementScreen() {
const navigate = useNavigation();
@@ -18,7 +22,7 @@ export default function PoolManagementScreen() {
activePoolsArray,
closedPoolsArray,
syncActivePoolsFromServer,
poolsArray,
updatePoolList,
} = usePools();
const { t } = useTranslation();
@@ -62,11 +66,12 @@ export default function PoolManagementScreen() {
useFocusEffect(
useCallback(() => {
async function loadPools() {
await syncActivePoolsFromServer(poolsArray);
const pools = await updatePoolList();
await syncActivePoolsFromServer(pools);
setIsRefreshing(false);
}
loadPools();
}, []),
}, [updatePoolList, syncActivePoolsFromServer]),
);
const renderEmptyState = () => (
@@ -123,11 +128,18 @@ export default function PoolManagementScreen() {
const pools = buildPoolsData();
if (isRefreshing) {
return <FullLoadingScreen />;
return (
<GlobalThemeView useStandardWidth={true}>
<FullLoadingScreen />
</GlobalThemeView>
);
}
return (
<View style={{ flex: 1 }}>
<GlobalThemeView useStandardWidth={true}>
<CustomSettingsTopBar
label={t(`screens.inAccount.settingsContent.pools`)}
/>
<FlatList
data={pools}
renderItem={renderPoolItem}
@@ -143,7 +155,7 @@ export default function PoolManagementScreen() {
textContent={t('wallet.pools.createPool')}
actionFunction={handleCreatePool}
/>
</View>
</GlobalThemeView>
);
}
-4
View File
@@ -28,7 +28,6 @@ import ExploreUsers from './explorePage';
import NostrHome from '../../components/admin/homeComponents/settingsContent/nostrHome';
import { useTranslation } from 'react-i18next';
import ChooseLangugae from '../../components/admin/homeComponents/settingsContent/langugae';
import PoolManagementScreen from '../../components/admin/homeComponents/pools/poolManagementScreen';
export default function SettingsContentIndex(props) {
const navigate = useNavigation();
@@ -84,9 +83,6 @@ export default function SettingsContentIndex(props) {
{selectedPage?.toLowerCase() === 'display options' && (
<DisplayOptions theme={theme} />
)}
{selectedPage?.toLowerCase() === 'pools' && (
<PoolManagementScreen theme={theme} />
)}
{/* {selectedPage?.toLowerCase() === 'support our work' && (
<SupportWorkPage />
)} */}
+22 -5
View File
@@ -1,6 +1,6 @@
import { useCallback } from 'react';
import { useCallback, useState } from 'react';
import { FlatList, StyleSheet, TouchableOpacity, View } from 'react-native';
import { useNavigation } from '@react-navigation/native';
import { useFocusEffect, useNavigation } from '@react-navigation/native';
import { GlobalThemeView, ThemeText } from '../../../functions/CustomElements';
import ThemeIcon from '../../../functions/CustomElements/themeIcon';
import { useTranslation } from 'react-i18next';
@@ -11,8 +11,8 @@ import { useGlobalContextProvider } from '../../../../context-store/context';
import { useGlobalContactsInfo } from '../../../../context-store/globalContacts';
import { useImageCache } from '../../../../context-store/imageCache';
import { useAppStatus } from '../../../../context-store/appStatus';
import { usePools } from '../../../../context-store/poolContext';
import { useToast } from '../../../../context-store/toastManager';
import { getAllLocalPools } from '../../../functions/pools/poolsStorage';
import { useGlobalInsets } from '../../../../context-store/insetsProvider';
import useAccountSwitcher from '../../../hooks/useAccountSwitcher';
import { copyToClipboard } from '../../../functions';
@@ -69,9 +69,10 @@ export default function SettingsHub(props) {
const { globalContactsInformation } = useGlobalContactsInfo();
const { cache } = useImageCache();
const { isConnectedToTheInternet } = useAppStatus();
const { activePoolsArray, poolsArray } = usePools();
const { theme, darkModeType } = useGlobalThemeContext();
const { bottomPadding } = useGlobalInsets();
const [poolsArray, setPoolsArray] = useState([]);
const [activePoolsArray, setActivePoolsArray] = useState([]);
const {
isSwitchingAccount,
@@ -80,6 +81,22 @@ export default function SettingsHub(props) {
selectedAltAccount,
} = useAccountSwitcher();
useFocusEffect(
useCallback(() => {
(async () => {
const allPools = await getAllLocalPools();
const uuid = masterInfoObject?.uuid;
const owned = allPools.filter(p => p.creatorUUID === uuid);
setPoolsArray(owned.sort((a, b) => b.createdAt - a.createdAt));
setActivePoolsArray(
owned
.filter(p => p.status === 'active')
.sort((a, b) => b.createdAt - a.createdAt),
);
})();
}, [masterInfoObject?.uuid]),
);
const isDoomsday = props?.route?.params?.isDoomsday;
const myProfileImage = cache[masterInfoObject?.uuid];
const myContact = globalContactsInformation?.myProfile;
@@ -183,7 +200,7 @@ export default function SettingsHub(props) {
}, [navigate]);
const handleViewAllPools = useCallback(() => {
navigate.navigate('SettingsContentHome', { for: 'pools' });
navigate.navigate('PoolsStack');
}, [navigate]);
const handlePOS = useCallback(() => {
+15 -7
View File
@@ -126,11 +126,11 @@ export function PoolProvider({ children }) {
const poolUpdateTracker = useRef({});
userUuidRef.current = masterInfoObject?.uuid;
const updatePoolList = async () => {
const updatePoolList = useCallback(async () => {
const updatedList = await getAllLocalPools();
dispatch({ type: 'LOAD_LOCAL_POOLS', payload: updatedList });
return updatedList;
};
}, []);
const savePoolToCloud = async poolObj => {
try {
@@ -179,7 +179,7 @@ export function PoolProvider({ children }) {
};
// Sync active pools from Firestore for latest aggregates
const syncActivePoolsFromServer = async localPools => {
const syncActivePoolsFromServer = useCallback(async localPools => {
try {
const activePools = localPools.filter(p => p.status === 'active');
if (!activePools.length) {
@@ -205,10 +205,10 @@ export function PoolProvider({ children }) {
} catch (err) {
console.log('error syncing active pools from server', err);
}
};
}, []);
// Restore pools from Firestore on new device / reinstall
const handlePoolRestore = async localPools => {
const handlePoolRestore = async (localPools, isActive = () => true) => {
try {
if (isRestoring.current) return;
isRestoring.current = true;
@@ -253,6 +253,7 @@ export function PoolProvider({ children }) {
});
}
if (!isActive()) return;
dispatch({ type: 'BULK_ADD_POOLS', payload: serverPools });
await setLocalStorageItem(
'checkForOutstandingPools',
@@ -337,10 +338,17 @@ export function PoolProvider({ children }) {
useEffect(() => {
if (!didGetToHomepage) return;
let active = true;
(async () => {
const poolList = await updatePoolList();
await handlePoolRestore(poolList);
const allPools = await getAllLocalPools();
if (!active) return;
dispatch({ type: 'LOAD_LOCAL_POOLS', payload: allPools });
if (!active) return;
await handlePoolRestore(allPools, () => active);
})();
return () => {
active = false;
};
}, [didGetToHomepage]);
const { poolsArray, activePoolsArray, closedPoolsArray } = useMemo(() => {
+25
View File
@@ -0,0 +1,25 @@
import {createNativeStackNavigator} from '@react-navigation/native-stack';
import {PoolProvider} from '../context-store/poolContext';
import PoolManagementScreen from '../app/components/admin/homeComponents/pools/poolManagementScreen';
import PoolDetailScreen from '../app/components/admin/homeComponents/pools/poolDetailScreen';
const Stack = createNativeStackNavigator();
export default function PoolsStack() {
return (
<PoolProvider>
<Stack.Navigator screenOptions={{headerShown: false}}>
<Stack.Screen
name="PoolManagementScreen"
component={PoolManagementScreen}
options={{animation: 'none'}}
/>
<Stack.Screen
name="PoolDetailScreen"
component={PoolDetailScreen}
options={{animation: 'slide_from_right'}}
/>
</Stack.Navigator>
</PoolProvider>
);
}
+4 -3
View File
@@ -12,12 +12,13 @@ type RootStackParamList = {
sliderHight: number;
claimType: string;
};
PoolDetailScreen: {
poolId: string;
};
PayLinkPaymentScreen: {
payLinkId: string;
};
PoolsStack: {
screen: string;
params: { poolId: string };
};
};
// Correct way to define the navigationRef
+2 -4
View File
@@ -70,9 +70,8 @@ import CreateGiftDescription from '../app/components/admin/homeComponents/gifts/
import CreateGiftDuration from '../app/components/admin/homeComponents/gifts/createGiftDuration';
import GiftConfirmation from '../app/components/admin/homeComponents/gifts/giftConfirmationScreen';
import AdvancedGiftClaim from '../app/components/admin/homeComponents/gifts/advancedClaimMode';
import PoolManagementScreen from '../app/components/admin/homeComponents/pools/poolManagementScreen';
import PoolDetailScreen from '../app/components/admin/homeComponents/pools/poolDetailScreen';
import ViewContibutors from '../app/components/admin/homeComponents/pools/viewContributors';
import PoolsStack from './PoolsStack';
import SavingsHome from '../app/components/admin/homeComponents/savings/SavingsHome';
import SavingsGoalEmoji from '../app/components/admin/homeComponents/savings/SavingsGoalEmoji';
import SavingsGoalDescribe from '../app/components/admin/homeComponents/savings/SavingsGoalDescribe';
@@ -214,8 +213,7 @@ const SLIDE_FROM_RIGHT_SCREENS = [
{ name: 'CreateGiftDuration', component: CreateGiftDuration },
{ name: 'GiftConfirmation', component: GiftConfirmation },
{ name: 'AdvancedGiftClaim', component: AdvancedGiftClaim },
{ name: 'PoolManagementScreen', component: PoolManagementScreen },
{ name: 'PoolDetailScreen', component: PoolDetailScreen },
{ name: 'PoolsStack', component: PoolsStack },
{ name: 'SavingsHome', component: SavingsHome },
{ name: 'SavingsGoalEmoji', component: SavingsGoalEmoji },
{ name: 'SavingsGoalDescribe', component: SavingsGoalDescribe },