Skip to content

Commit

Permalink
testing app icon surfacing + greying them out
Browse files Browse the repository at this point in the history
  • Loading branch information
BrodyHughes committed Dec 23, 2024
1 parent 0f4f232 commit 74e702c
Show file tree
Hide file tree
Showing 2 changed files with 97 additions and 49 deletions.
12 changes: 12 additions & 0 deletions src/components/toasts/appIconToast.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
// UnlockToast.tsx
import React from 'react';
import Toast from './Toast';
import { magicMemo } from '@/utils';

const UnlockToast = () => {
const isVisible = true;

return <Toast isVisible={isVisible} icon="close" text="Icon not unlocked" testID="icon-not-unlocked-toast" />;
};

export default magicMemo(UnlockToast, []);
134 changes: 85 additions & 49 deletions src/screens/SettingsSheet/components/AppIconSection.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import React, { useCallback, useMemo } from 'react';
import React, { useCallback, useMemo, useState } from 'react';
import { Source } from 'react-native-fast-image';
import Menu from './Menu';
import MenuContainer from './MenuContainer';
Expand All @@ -11,74 +11,110 @@ import { logger } from '@/logger';
import { analytics } from '@/analytics';
import { AppIcon, AppIconKey, UnlockableAppIcon, UnlockableAppIconKey, freeAppIcons, unlockableAppIcons } from '@/appIcons/appIcons';
import { unlockableAppIconStorage } from '@/featuresToUnlock/unlockableAppIconCheck';
import UnlockToast from '@/components/toasts/appIconToast';

type UnlockStatusMap = { [key in AppIconKey | UnlockableAppIconKey]: boolean };

const AppIconSection = () => {
const { appIcon, settingsChangeAppIcon } = useAccountSettings();
const { colors, isDarkMode } = useTheme();

const [showUnlockMessage, setShowUnlockMessage] = useState(false);
const [messageCount, setMessageCount] = useState(0);

const onSelectIcon = useCallback(
(icon: string) => {
(icon: string, isUnlocked: boolean) => {
if (!isUnlocked) {
setShowUnlockMessage(true);
setMessageCount(count => count + 1);
return;
}

logger.debug(`[AppIconSection]: onSelectIcon: ${icon}`);
analytics.track('Set App Icon', { appIcon: icon });
settingsChangeAppIcon(icon);
},
[settingsChangeAppIcon]
);

const unlockedAppIcons: Record<AppIconKey, AppIcon> = useMemo(
// Get mapping of which icons are unlocked
const unlockedStatus: UnlockStatusMap = useMemo(() => {
const freeIconsStatus = Object.keys(freeAppIcons).reduce<Partial<UnlockStatusMap>>(
(acc, key) => ({
...acc,
[key as AppIconKey]: true,
}),
{}
);

const unlockableIconsStatus = (Object.keys(unlockableAppIcons) as UnlockableAppIconKey[]).reduce<Partial<UnlockStatusMap>>(
(acc, appIconKey) => ({
...acc,
[appIconKey]: unlockableAppIconStorage.getBoolean(appIconKey),
}),
{}
);

return {
...freeIconsStatus,
...unlockableIconsStatus,
} as UnlockStatusMap;
}, []);

// Combine all icons into one object
const allAppIcons: Record<AppIconKey | UnlockableAppIconKey, AppIcon | UnlockableAppIcon> = useMemo(
() => ({
...freeAppIcons,
...(Object.keys(unlockableAppIcons) as UnlockableAppIconKey[]).reduce(
(unlockedAppIcons, appIconKey) => {
const appIcon = unlockableAppIcons[appIconKey];
const unlocked = unlockableAppIconStorage.getBoolean(appIconKey);
logger.debug(`[AppIconSection]: checking if unlocked ${appIcon.displayName} ${unlocked} ${appIconKey}`);
if (unlocked) {
logger.debug(`[AppIconSection]: unlocked ${appIcon.displayName}`);
unlockedAppIcons[appIconKey] = appIcon;
}
return unlockedAppIcons;
},
{} as Record<UnlockableAppIconKey, UnlockableAppIcon>
),
...unlockableAppIcons,
}),
[]
);

console.log('showUnlockMessage', showUnlockMessage);
console.log('messageCount', messageCount);

return (
<MenuContainer>
<Menu>
{Object.entries(unlockedAppIcons).map(([key, { displayName, image, accentColor }]) => (
<MenuItem
key={key}
leftComponent={
<Box
style={{
shadowColor: isDarkMode ? colors.shadowBlack : (accentColor && (colors as any)[accentColor]) || colors.shadowBlack,
shadowOffset: { height: 4, width: 0 },
shadowOpacity: 0.3,
shadowRadius: 4,
}}
>
<ImgixImage
source={image as Source}
style={{
height: 36,
width: 36,
borderRadius: 8,
}}
size={30}
/>
</Box>
}
onPress={() => onSelectIcon(key)}
rightComponent={key === appIcon && <MenuItem.StatusIcon status="selected" />}
size={60}
titleComponent={<MenuItem.Title text={displayName} />}
/>
))}
</Menu>
</MenuContainer>
<>
<UnlockToast />
<MenuContainer>
<Menu>
{Object.entries(allAppIcons).map(([key, { displayName, image, accentColor }]) => {
const isUnlocked = unlockedStatus[key as AppIconKey | UnlockableAppIconKey];

return (
<MenuItem
key={key}
leftComponent={
<Box
style={{
shadowColor: isDarkMode ? colors.shadowBlack : (accentColor && (colors as any)[accentColor]) || colors.shadowBlack,
shadowOffset: { height: 4, width: 0 },
shadowOpacity: 0.3,
shadowRadius: 4,
opacity: isUnlocked ? 1 : 0.2,
}}
>
<ImgixImage
source={image as Source}
style={{
height: 36,
width: 36,
borderRadius: 8,
}}
size={30}
/>
</Box>
}
onPress={() => onSelectIcon(key, isUnlocked)}
rightComponent={key === appIcon && isUnlocked && <MenuItem.StatusIcon status="selected" />}
size={60}
titleComponent={<MenuItem.Title text={displayName} />}
/>
);
})}
</Menu>
</MenuContainer>
</>
);
};

Expand Down

0 comments on commit 74e702c

Please sign in to comment.