From eeb7b18ffcfdbe7521569278ba741bc19a04af8b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Qu=E1=BB=91c=20Kh=C3=A1nh?= Date: Sat, 21 Sep 2024 23:19:27 +0700 Subject: [PATCH] feat(mobile): refactor burndown chart and add tooltip (#343) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit
🎥 Video uploaded on Graphite:
Resolves https://github.com/get6pm/6pm/issues/324 --- apps/mobile/app/(app)/(tabs)/budgets.tsx | 4 +- .../app/(app)/budget/[budgetId]/index.tsx | 4 +- apps/mobile/app/_layout.tsx | 6 - .../components/budget/burndown-chart.tsx | 227 ------------------ .../burndown-chart/active-value-indicator.tsx | 108 +++++++++ .../common/burndown-chart/burndown-chart.tsx | 204 ++++++++++++++++ .../common/burndown-chart/diff-badge.tsx | 72 ++++++ .../components/common/burndown-chart/index.ts | 1 + apps/mobile/hooks/use-color-palette.tsx | 9 +- apps/mobile/ios/6pm.xcodeproj/project.pbxproj | 128 +++++----- apps/mobile/package.json | 2 +- apps/mobile/tailwind.config.js | 1 - packages/currency/src/formatter.ts | 1 + pnpm-lock.yaml | 20 +- 14 files changed, 472 insertions(+), 315 deletions(-) delete mode 100644 apps/mobile/components/budget/burndown-chart.tsx create mode 100644 apps/mobile/components/common/burndown-chart/active-value-indicator.tsx create mode 100644 apps/mobile/components/common/burndown-chart/burndown-chart.tsx create mode 100644 apps/mobile/components/common/burndown-chart/diff-badge.tsx create mode 100644 apps/mobile/components/common/burndown-chart/index.ts diff --git a/apps/mobile/app/(app)/(tabs)/budgets.tsx b/apps/mobile/app/(app)/(tabs)/budgets.tsx index b32dfbcc..2c954c4f 100644 --- a/apps/mobile/app/(app)/(tabs)/budgets.tsx +++ b/apps/mobile/app/(app)/(tabs)/budgets.tsx @@ -1,6 +1,6 @@ import { BudgetItem } from '@/components/budget/budget-item' import { BudgetStatistic } from '@/components/budget/budget-statistic' -import { BurndownChart } from '@/components/budget/burndown-chart' +import { BurndownChart } from '@/components/common/burndown-chart' import { FooterGradient } from '@/components/common/footer-gradient' import { Button } from '@/components/ui/button' // import { Toolbar } from '@/components/common/toolbar' @@ -200,7 +200,7 @@ export default function BudgetsScreen() { return ( { if (headerHeight.value === ev.nativeEvent.layout.height) { return diff --git a/apps/mobile/app/(app)/budget/[budgetId]/index.tsx b/apps/mobile/app/(app)/budget/[budgetId]/index.tsx index fa699a22..e9f26466 100644 --- a/apps/mobile/app/(app)/budget/[budgetId]/index.tsx +++ b/apps/mobile/app/(app)/budget/[budgetId]/index.tsx @@ -1,7 +1,7 @@ import { BudgetStatistic } from '@/components/budget/budget-statistic' -import { BurndownChart } from '@/components/budget/burndown-chart' import { PeriodControl } from '@/components/budget/period-control' import { AmountFormat } from '@/components/common/amount-format' +import { BurndownChart } from '@/components/common/burndown-chart' import { FooterGradient } from '@/components/common/footer-gradient' import { TransactionItem } from '@/components/transaction/transaction-item' import { Button } from '@/components/ui/button' @@ -205,7 +205,7 @@ export default function BudgetDetailScreen() { onChange={setCurrentPeriodIndex} /> { if (headerHeight.value === ev.nativeEvent.layout.height) { return diff --git a/apps/mobile/app/_layout.tsx b/apps/mobile/app/_layout.tsx index 8081015e..3c011e59 100644 --- a/apps/mobile/app/_layout.tsx +++ b/apps/mobile/app/_layout.tsx @@ -10,10 +10,6 @@ import { isRunningInExpoGo } from 'expo' import { tokenCache } from '@/lib/cache' import { ClerkLoaded, ClerkProvider } from '@clerk/clerk-expo' -import { - SpaceMono_400Regular, - SpaceMono_700Bold, -} from '@expo-google-fonts/space-mono' import { useFonts } from 'expo-font' import * as Notifications from 'expo-notifications' import { SplashScreen, Stack, useNavigationContainerRef } from 'expo-router' @@ -116,8 +112,6 @@ function RootLayout() { useWarmUpBrowser() const { colorScheme } = useColorScheme() const [fontsLoaded] = useFonts({ - SpaceMono_400Regular, - SpaceMono_700Bold, 'Haskoy-Regular': require('../assets/fonts/Haskoy-Regular.ttf'), 'Haskoy-Medium': require('../assets/fonts/Haskoy-Medium.ttf'), 'Haskoy-SemiBold': require('../assets/fonts/Haskoy-SemiBold.ttf'), diff --git a/apps/mobile/components/budget/burndown-chart.tsx b/apps/mobile/components/budget/burndown-chart.tsx deleted file mode 100644 index a7a698a2..00000000 --- a/apps/mobile/components/budget/burndown-chart.tsx +++ /dev/null @@ -1,227 +0,0 @@ -import { useColorPalette } from '@/hooks/use-color-palette' -import { useDefaultCurrency } from '@/stores/user-settings/hooks' -import { nFormatter } from '@6pm/currency' -import { dayjsExtended } from '@6pm/utilities' -import { - SpaceMono_400Regular, - SpaceMono_700Bold, -} from '@expo-google-fonts/space-mono' -import { - DashPathEffect, - Group, - Path, - RoundedRect, - Text as SkiaText, - useFont, -} from '@shopify/react-native-skia' -import { useMemo } from 'react' -import { View } from 'react-native' -import { - CartesianChart, - type PointsArray, - Scatter, - useLinePath, -} from 'victory-native' - -function AverageLine({ points }: { points: PointsArray }) { - const { path } = useLinePath(points, { curveType: 'linear' }) - const { getColor } = useColorPalette() - - return ( - - - - ) -} - -const LETTER_WIDTH = 10 - -function UsageLine({ - points, - diffAmount, -}: { points: PointsArray; diffAmount: number }) { - const { path } = useLinePath(points, { curveType: 'linear' }) - const font = useFont(SpaceMono_700Bold, 16) - const { getColor } = useColorPalette() - - const lastPoint = points.filter((i) => !!i.y).pop() - - const diffText = - diffAmount > 0 - ? `${nFormatter(Math.abs(diffAmount), 0)} less` - : `${nFormatter(Math.abs(diffAmount), 0)} over` - - const badgeWidth = diffText.length * LETTER_WIDTH + 12 - - const lastPointBadgeX = useMemo(() => { - if (!lastPoint) { - return 0 - } - const xValue = Number(lastPoint.xValue) // current day - let offset = 0 - if (xValue > 28) { - offset = badgeWidth - } else if (xValue > 24) { - offset = badgeWidth / 2 - } else if (xValue > 20) { - offset = 16 - } else { - offset = 6 - } - - return lastPoint.x - offset - }, [badgeWidth, lastPoint]) - - const lastPointBadgeY = useMemo(() => { - if (!lastPoint) { - return 0 - } - const xValue = Number(lastPoint.xValue) // current day - let offset = 0 - if (xValue > 15) { - offset = 16 - } else { - offset = -52 - } - - if (lastPoint.y! > 120) { - offset = -52 - } - - return lastPoint.y! + offset - }, [lastPoint]) - - return ( - <> - - {lastPoint && ( - - - 0 ? '#16a34a' : '#ef4444'} - opacity={0.8} - /> - - - )} - - ) -} - -type BurndownChartProps = { - totalBudget: number - averagePerDay: number - data?: { day: number; amount?: number }[] - anchorDay?: number -} - -export function BurndownChart({ - totalBudget, - averagePerDay, - data = [], - anchorDay = new Date().getDate(), -}: BurndownChartProps) { - const font = useFont(SpaceMono_400Regular, 12) - const defaultCurrency = useDefaultCurrency() - const daysInMonth = dayjsExtended(anchorDay).daysInMonth() - const { getColor } = useColorPalette() - - const chartData = Array.from({ length: daysInMonth + 1 }, (_, i) => ({ - day: i, - amount: data.find((d) => d.day === i)?.amount ?? 0, - })).reduce( - (acc, usage, index) => { - const lastDay = acc[acc.length - 1] - return [ - ...acc, - { - ...usage, - amount: - index > anchorDay - ? undefined - : (lastDay?.amount || 0) + (usage.amount ?? 0), - average: averagePerDay * index, - }, - ] - }, - [] as { day: number; amount?: number; average: number }[], - ) - - const todayRecord = chartData.find((i) => i.day === anchorDay) - const diffAmount = Math.round( - (todayRecord?.average || 0) - (todayRecord?.amount || 0), - ) - - const totalText = `${nFormatter(totalBudget, 0)} ${defaultCurrency}` - - return ( - - - {({ points }) => ( - <> - - - - - - )} - - - ) -} diff --git a/apps/mobile/components/common/burndown-chart/active-value-indicator.tsx b/apps/mobile/components/common/burndown-chart/active-value-indicator.tsx new file mode 100644 index 00000000..58232e4f --- /dev/null +++ b/apps/mobile/components/common/burndown-chart/active-value-indicator.tsx @@ -0,0 +1,108 @@ +import { useColorPalette } from '@/hooks/use-color-palette' +import { useDefaultCurrency } from '@/stores/user-settings/hooks' +import { nFormatter } from '@6pm/currency' +import { dayjsExtended } from '@6pm/utilities' +import { useState } from 'react' +import { runOnJS, useDerivedValue } from 'react-native-reanimated' +import type { ChartPressState } from 'victory-native' + +import { + Circle, + Line as SkiaLine, + Text as SkiaText, + useFont, + vec, +} from '@shopify/react-native-skia' +import { DiffBadge } from './diff-badge' + +type ActiveValueIndicatorProps = { + bottom: number + top: number + pressState: ChartPressState<{ + x: number + y: { + average: number + amount: number + accumulated: number + } + }> +} + +export function ActiveValueIndicator({ + bottom, + top, + pressState, +}: ActiveValueIndicatorProps) { + const { getColor } = useColorPalette() + const tooltipFont = useFont( + require('../../../assets/fonts/Haskoy-Medium.ttf'), + 12, + ) + const x = pressState.x.position + const y = pressState.y.accumulated.position + const activeValue = pressState.y.amount.value + const date = pressState.x.value + const start = useDerivedValue(() => vec(x.value, bottom - 12)) + const end = useDerivedValue(() => vec(x.value, top + 1.5 * 12)) + const defaultCurrency = useDefaultCurrency() + const [value, setValue] = useState('') + + function formatDate(value: number, date: number) { + const result = ` + ${nFormatter(value, 0)} ${defaultCurrency} on ${dayjsExtended( + dayjsExtended().set('date', date), + ).format('MMM D')} + ` + setValue(result) + } + const activeValueDisplay = useDerivedValue(() => { + runOnJS(formatDate)(activeValue.value, date.value) + return value! + }) + const activeValueWidth = useDerivedValue( + () => + tooltipFont + ?.getGlyphWidths?.(tooltipFont.getGlyphIDs(activeValueDisplay.value)) + .reduce((sum, value) => sum + value, 0) || 0, + ) + const activeValueX = useDerivedValue(() => { + if (date.value < 5) { + return date.value + } + if (date.value > 26) { + return x.value - activeValueWidth.value + } + return x.value - activeValueWidth.value / 2 + }) + + const diffAmount = Math.round( + (pressState.y.average.value.value || 0) - + (pressState.y.accumulated.value.value || 0), + ) + + return ( + <> + + + + + + + ) +} diff --git a/apps/mobile/components/common/burndown-chart/burndown-chart.tsx b/apps/mobile/components/common/burndown-chart/burndown-chart.tsx new file mode 100644 index 00000000..dbe46779 --- /dev/null +++ b/apps/mobile/components/common/burndown-chart/burndown-chart.tsx @@ -0,0 +1,204 @@ +import { useColorPalette } from '@/hooks/use-color-palette' +import { nFormatter } from '@6pm/currency' +import { dayjsExtended } from '@6pm/utilities' +import { + Circle, + DashPathEffect, + Group, + Path, + useFont, +} from '@shopify/react-native-skia' +import * as Haptics from 'expo-haptics' +import { useEffect } from 'react' +import { View } from 'react-native' +import { + CartesianChart, + type PointsArray, + useAnimatedPath, + useChartPressState, + useLinePath, +} from 'victory-native' +import { ActiveValueIndicator } from './active-value-indicator' +import { DiffBadge } from './diff-badge' + +type BurndownChartProps = { + totalBudget: number + averagePerDay: number + data?: { day: number; amount?: number }[] + anchorDay?: number +} + +export function BurndownChart({ + totalBudget, + averagePerDay, + data = [], + anchorDay = new Date().getDate(), +}: BurndownChartProps) { + const { getColor } = useColorPalette() + const axisFont = useFont( + require('../../../assets/fonts/Haskoy-Medium.ttf'), + 12, + ) + const daysInMonth = dayjsExtended(anchorDay).daysInMonth() + const chartData = Array.from({ length: daysInMonth }, (_, i) => ({ + day: i, + amount: data.find((d) => d.day === i)?.amount ?? 0, + })).reduce( + (acc, usage, index) => { + const lastDay = acc[acc.length - 1] + return [ + ...acc, + { + ...usage, + accumulated: + index > anchorDay + ? undefined + : (lastDay?.accumulated || 0) + (usage.amount ?? 0), + average: averagePerDay * index, + }, + ] + }, + [] as { + day: number + amount?: number + average: number + accumulated?: number + }[], + ) + + const anchorRecord = chartData.find((i) => i.day === anchorDay) + const diffAmount = Math.round( + (anchorRecord?.average || 0) - (anchorRecord?.accumulated || 0), + ) + const { state: firstTouch, isActive: isFirstPressActive } = + useChartPressState({ + x: 0, + y: { + average: 0, + amount: 0, + accumulated: 0, + }, + }) + + useEffect(() => { + if (isFirstPressActive) { + Haptics.selectionAsync().catch(() => null) + } + }, [isFirstPressActive]) + + return ( + + nFormatter(value || 0, 0), + axisSide: 'right', + labelPosition: 'inset', + labelColor: getColor('--foreground', { alpha: 0.5 }), + tickValues: [0, totalBudget / 2, totalBudget], + lineWidth: 0, + }, + ]} + chartPressState={[firstTouch]} + renderOutside={({ chartBounds, points }) => { + const lastPoint = points.accumulated.filter((i) => !!i.y).pop() + return ( + <> + {isFirstPressActive ? ( + + ) : lastPoint ? ( + + + + + + ) : null} + + ) + }} + > + {({ points }) => ( + <> + + + + )} + + + ) +} + +function AverageLine({ points }: { points: PointsArray }) { + const { path } = useLinePath(points, { curveType: 'linear' }) + const { getColor } = useColorPalette() + + return ( + + + + ) +} + +function UsageLine({ points }: { points: PointsArray }) { + const { path } = useLinePath(points, { curveType: 'monotoneX' }) + const animPath = useAnimatedPath(path, { type: 'timing', duration: 1000 }) + const { getColor } = useColorPalette() + + return ( + <> + + + ) +} diff --git a/apps/mobile/components/common/burndown-chart/diff-badge.tsx b/apps/mobile/components/common/burndown-chart/diff-badge.tsx new file mode 100644 index 00000000..b578f4ea --- /dev/null +++ b/apps/mobile/components/common/burndown-chart/diff-badge.tsx @@ -0,0 +1,72 @@ +import { nFormatter } from '@6pm/currency' +import { t } from '@lingui/macro' +import { RoundedRect, Text, useFont } from '@shopify/react-native-skia' +import { useMemo } from 'react' + +const BADGE_OFFSET = 10 + +type DiffBadgeProps = { + anchorDay: number + diffAmount: number + point: { x: number; y: number } +} + +export function DiffBadge({ anchorDay, diffAmount, point }: DiffBadgeProps) { + const badgeFont = useFont( + require('../../../assets/fonts/Haskoy-SemiBold.ttf'), + 16, + ) + + function getDiffText(diffAmount: number) { + if (diffAmount > 0) { + return t`${nFormatter(Math.abs(diffAmount), 0)} less` + } + return t`${nFormatter(Math.abs(diffAmount), 0)} over` + } + + const diffTextWidth = + badgeFont + ?.getGlyphWidths?.(badgeFont.getGlyphIDs(getDiffText(diffAmount))) + .reduce((sum, value) => sum + value, 0) || 0 + + const activeBadgeX = useMemo(() => { + if (anchorDay < 8) { + return anchorDay + } + if (anchorDay > 26) { + return point.x - diffTextWidth + } + return point.x - diffTextWidth / 2 + }, [anchorDay, diffTextWidth, point.x]) + + const activeBadgeY = useMemo(() => { + if (anchorDay < 8) { + return point.y - 40 + } + if (anchorDay > 26) { + return point.y + BADGE_OFFSET + } + return point.y + BADGE_OFFSET + }, [anchorDay, point.y]) + + return ( + <> + 0 ? '#16a34a' : '#ef4444'} + opacity={0.8} + /> + + + ) +} diff --git a/apps/mobile/components/common/burndown-chart/index.ts b/apps/mobile/components/common/burndown-chart/index.ts new file mode 100644 index 00000000..dcc54b79 --- /dev/null +++ b/apps/mobile/components/common/burndown-chart/index.ts @@ -0,0 +1 @@ +export * from './burndown-chart' diff --git a/apps/mobile/hooks/use-color-palette.tsx b/apps/mobile/hooks/use-color-palette.tsx index e0edf189..91691666 100644 --- a/apps/mobile/hooks/use-color-palette.tsx +++ b/apps/mobile/hooks/use-color-palette.tsx @@ -3,6 +3,10 @@ import { useUserSettingsStore } from '@/stores/user-settings/store' // import { FeatureFlag, useFeatureFlag } from './use-feature-flag' import { useColorScheme } from './useColorScheme' +type GetColorOptions = { + alpha?: number +} + /** * Not able to use feature flag in burndown-chart somehow */ @@ -17,8 +21,9 @@ export function useColorPalette() { // isDynamicColorPaletteEnabled ? preferredPalette : Palette.Default themeVariables[preferredPalette][colorScheme ?? 'light'] - const getColor = (colorKey: ColorKey) => { - return `hsl(${colorPalette[colorKey]})` + const getColor = (colorKey: ColorKey, options?: GetColorOptions) => { + const { alpha = 1 } = options ?? {} + return `hsla(${colorPalette[colorKey]?.replaceAll(' ', ', ')}, ${alpha})` } return { diff --git a/apps/mobile/ios/6pm.xcodeproj/project.pbxproj b/apps/mobile/ios/6pm.xcodeproj/project.pbxproj index ebcfdc95..0d8acb2c 100644 --- a/apps/mobile/ios/6pm.xcodeproj/project.pbxproj +++ b/apps/mobile/ios/6pm.xcodeproj/project.pbxproj @@ -17,22 +17,22 @@ BB2F792D24A3F905000567C9 /* Expo.plist in Resources */ = {isa = PBXBuildFile; fileRef = BB2F792C24A3F905000567C9 /* Expo.plist */; }; D7776E943EB34B66A98A6A2C /* noop-file.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7B5A0026D5DB42999CBC28FE /* noop-file.swift */; }; DEE1C0AF3858C12C88E3160B /* PrivacyInfo.xcprivacy in Resources */ = {isa = PBXBuildFile; fileRef = 82965772011B75850F546AE9 /* PrivacyInfo.xcprivacy */; }; - 3BB2EBF26496492E9C5291AE /* dark-Icon-$60x60@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = C224E6DA45F6492D80AFC45D /* dark-Icon-$60x60@2x.png */; }; - 8D1EA12517904B58A4060C92 /* dark-Icon-$60x60@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = 3049E96034E14262990BBE57 /* dark-Icon-$60x60@3x.png */; }; - B4F5C53D92C947538F8F0E3D /* dark-Icon-$60x60@2x~ipad.png in Resources */ = {isa = PBXBuildFile; fileRef = 859709507FC3404FAA16B8AB /* dark-Icon-$60x60@2x~ipad.png */; }; - B8F1DB250ADA4AA4A31AC550 /* dark-Icon-$60x60@3x~ipad.png in Resources */ = {isa = PBXBuildFile; fileRef = C89D4713D16E42759388C089 /* dark-Icon-$60x60@3x~ipad.png */; }; - 254E59C792FC4A75B5C140CA /* light-Icon-$60x60@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = C5235AD8C3BA4189894CB1E2 /* light-Icon-$60x60@2x.png */; }; - 40CD5016A8414B28A587BD3F /* light-Icon-$60x60@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = 1957B3D5E23A48FFA16A7D4A /* light-Icon-$60x60@3x.png */; }; - D209B3B2B07D40F39ACE541A /* light-Icon-$60x60@2x~ipad.png in Resources */ = {isa = PBXBuildFile; fileRef = BCFAED807C1D48358DF93C01 /* light-Icon-$60x60@2x~ipad.png */; }; - DD39B8087D944E3E936B042F /* light-Icon-$60x60@3x~ipad.png in Resources */ = {isa = PBXBuildFile; fileRef = 9BF680DA91684AE6843BCDDE /* light-Icon-$60x60@3x~ipad.png */; }; - 501625193CE44138B9EA1DA0 /* digital-Icon-$60x60@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = E4944EEA3A0347AEBED34BF5 /* digital-Icon-$60x60@2x.png */; }; - 33BC544FAE3D454F818DDD37 /* digital-Icon-$60x60@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = C4E44A340C384096966CA358 /* digital-Icon-$60x60@3x.png */; }; - 93033B72B452407D812C2F3A /* digital-Icon-$60x60@2x~ipad.png in Resources */ = {isa = PBXBuildFile; fileRef = BD4B984B897F455B85208999 /* digital-Icon-$60x60@2x~ipad.png */; }; - 32FF1BC21A14481DBB6C5461 /* digital-Icon-$60x60@3x~ipad.png in Resources */ = {isa = PBXBuildFile; fileRef = 7FAF182A3095411BB6DF1944 /* digital-Icon-$60x60@3x~ipad.png */; }; - CBEA844903474EDFA4DD0F0F /* original-Icon-$60x60@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 08C366D51C3A4B21BCDCB271 /* original-Icon-$60x60@2x.png */; }; - 3D818C37A72642309F5DA6BD /* original-Icon-$60x60@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = B3A32AA9717C4A338798E492 /* original-Icon-$60x60@3x.png */; }; - 1F938078E62244CFA74BA2E8 /* original-Icon-$60x60@2x~ipad.png in Resources */ = {isa = PBXBuildFile; fileRef = B53D1D6A002E41C4A6D1DFE0 /* original-Icon-$60x60@2x~ipad.png */; }; - 24908DA86A11404AA436ABB2 /* original-Icon-$60x60@3x~ipad.png in Resources */ = {isa = PBXBuildFile; fileRef = 76E3F4CC592144D0A17A15D3 /* original-Icon-$60x60@3x~ipad.png */; }; + 9AAE6F7B17474514A4F6A076 /* dark-Icon-$60x60@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 8AE181AAAD0247AA9B1AA6E5 /* dark-Icon-$60x60@2x.png */; }; + 8F887BD4EBDF493CAB9DA7BB /* dark-Icon-$60x60@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = C09DA74A2DFB4364A9D9E36B /* dark-Icon-$60x60@3x.png */; }; + 62A0F5C2C8A64B0B8F03F755 /* dark-Icon-$60x60@2x~ipad.png in Resources */ = {isa = PBXBuildFile; fileRef = 0450EF9B96CE4206A1883DF9 /* dark-Icon-$60x60@2x~ipad.png */; }; + 5639C190B4F34D70B21AF34E /* dark-Icon-$60x60@3x~ipad.png in Resources */ = {isa = PBXBuildFile; fileRef = 95BC66CE48074124A42F38C2 /* dark-Icon-$60x60@3x~ipad.png */; }; + 1F934D5C53694A329D8B42EE /* light-Icon-$60x60@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 6F922BBFF4194EBB99167D28 /* light-Icon-$60x60@2x.png */; }; + 8585711A3D4048239326F927 /* light-Icon-$60x60@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = AA515C41595F4BF8B2D7C852 /* light-Icon-$60x60@3x.png */; }; + A72C8E349C2A43B5AD8E07E2 /* light-Icon-$60x60@2x~ipad.png in Resources */ = {isa = PBXBuildFile; fileRef = 1AE79E9F89CA4B568CDC67B9 /* light-Icon-$60x60@2x~ipad.png */; }; + 048EB12DC4334C6A8FE31AA2 /* light-Icon-$60x60@3x~ipad.png in Resources */ = {isa = PBXBuildFile; fileRef = F09F606E033242C0B2E37E87 /* light-Icon-$60x60@3x~ipad.png */; }; + EAC0082CEAA340A6880EB1DD /* digital-Icon-$60x60@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 1569C49E7D104F6E8D8A69CC /* digital-Icon-$60x60@2x.png */; }; + 9071AE06FF3141A3B7EB371F /* digital-Icon-$60x60@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = 7CE9B83E0934443389DD706D /* digital-Icon-$60x60@3x.png */; }; + 8286A99373C74812B4809C56 /* digital-Icon-$60x60@2x~ipad.png in Resources */ = {isa = PBXBuildFile; fileRef = E80D36216A6541A2B4359422 /* digital-Icon-$60x60@2x~ipad.png */; }; + E3AB74344A33432E9E41E3BC /* digital-Icon-$60x60@3x~ipad.png in Resources */ = {isa = PBXBuildFile; fileRef = 693DEDBEE1E74385B0D5E47F /* digital-Icon-$60x60@3x~ipad.png */; }; + D9784C09B1EF4A45B43C4D76 /* original-Icon-$60x60@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 50830C30CD1049FD86737A95 /* original-Icon-$60x60@2x.png */; }; + 0063D34B83404FE6B734E0F7 /* original-Icon-$60x60@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = E90F9E953896402591338650 /* original-Icon-$60x60@3x.png */; }; + 935DA4111571499A9AA68A56 /* original-Icon-$60x60@2x~ipad.png in Resources */ = {isa = PBXBuildFile; fileRef = 926873AE9619426F9B998533 /* original-Icon-$60x60@2x~ipad.png */; }; + A908A88A8A76484A9C44E02E /* original-Icon-$60x60@3x~ipad.png in Resources */ = {isa = PBXBuildFile; fileRef = 920649AAEE8A4688983D03A4 /* original-Icon-$60x60@3x~ipad.png */; }; /* End PBXBuildFile section */ /* Begin PBXFileReference section */ @@ -53,22 +53,22 @@ BB2F792C24A3F905000567C9 /* Expo.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = Expo.plist; sourceTree = ""; }; ED297162215061F000B7C4FE /* JavaScriptCore.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = JavaScriptCore.framework; path = System/Library/Frameworks/JavaScriptCore.framework; sourceTree = SDKROOT; }; FAC715A2D49A985799AEE119 /* ExpoModulesProvider.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ExpoModulesProvider.swift; path = "Pods/Target Support Files/Pods-6pm/ExpoModulesProvider.swift"; sourceTree = ""; }; - C224E6DA45F6492D80AFC45D /* dark-Icon-$60x60@2x.png */ = {isa = PBXFileReference; name = "dark-Icon-$60x60@2x.png"; path = "6pm/DynamicAppIcons/dark-Icon-$60x60@2x.png"; sourceTree = ""; fileEncoding = undefined; lastKnownFileType = unknown; explicitFileType = undefined; includeInIndex = 0; }; - 3049E96034E14262990BBE57 /* dark-Icon-$60x60@3x.png */ = {isa = PBXFileReference; name = "dark-Icon-$60x60@3x.png"; path = "6pm/DynamicAppIcons/dark-Icon-$60x60@3x.png"; sourceTree = ""; fileEncoding = undefined; lastKnownFileType = unknown; explicitFileType = undefined; includeInIndex = 0; }; - 859709507FC3404FAA16B8AB /* dark-Icon-$60x60@2x~ipad.png */ = {isa = PBXFileReference; name = "dark-Icon-$60x60@2x~ipad.png"; path = "6pm/DynamicAppIcons/dark-Icon-$60x60@2x~ipad.png"; sourceTree = ""; fileEncoding = undefined; lastKnownFileType = unknown; explicitFileType = undefined; includeInIndex = 0; }; - C89D4713D16E42759388C089 /* dark-Icon-$60x60@3x~ipad.png */ = {isa = PBXFileReference; name = "dark-Icon-$60x60@3x~ipad.png"; path = "6pm/DynamicAppIcons/dark-Icon-$60x60@3x~ipad.png"; sourceTree = ""; fileEncoding = undefined; lastKnownFileType = unknown; explicitFileType = undefined; includeInIndex = 0; }; - C5235AD8C3BA4189894CB1E2 /* light-Icon-$60x60@2x.png */ = {isa = PBXFileReference; name = "light-Icon-$60x60@2x.png"; path = "6pm/DynamicAppIcons/light-Icon-$60x60@2x.png"; sourceTree = ""; fileEncoding = undefined; lastKnownFileType = unknown; explicitFileType = undefined; includeInIndex = 0; }; - 1957B3D5E23A48FFA16A7D4A /* light-Icon-$60x60@3x.png */ = {isa = PBXFileReference; name = "light-Icon-$60x60@3x.png"; path = "6pm/DynamicAppIcons/light-Icon-$60x60@3x.png"; sourceTree = ""; fileEncoding = undefined; lastKnownFileType = unknown; explicitFileType = undefined; includeInIndex = 0; }; - BCFAED807C1D48358DF93C01 /* light-Icon-$60x60@2x~ipad.png */ = {isa = PBXFileReference; name = "light-Icon-$60x60@2x~ipad.png"; path = "6pm/DynamicAppIcons/light-Icon-$60x60@2x~ipad.png"; sourceTree = ""; fileEncoding = undefined; lastKnownFileType = unknown; explicitFileType = undefined; includeInIndex = 0; }; - 9BF680DA91684AE6843BCDDE /* light-Icon-$60x60@3x~ipad.png */ = {isa = PBXFileReference; name = "light-Icon-$60x60@3x~ipad.png"; path = "6pm/DynamicAppIcons/light-Icon-$60x60@3x~ipad.png"; sourceTree = ""; fileEncoding = undefined; lastKnownFileType = unknown; explicitFileType = undefined; includeInIndex = 0; }; - E4944EEA3A0347AEBED34BF5 /* digital-Icon-$60x60@2x.png */ = {isa = PBXFileReference; name = "digital-Icon-$60x60@2x.png"; path = "6pm/DynamicAppIcons/digital-Icon-$60x60@2x.png"; sourceTree = ""; fileEncoding = undefined; lastKnownFileType = unknown; explicitFileType = undefined; includeInIndex = 0; }; - C4E44A340C384096966CA358 /* digital-Icon-$60x60@3x.png */ = {isa = PBXFileReference; name = "digital-Icon-$60x60@3x.png"; path = "6pm/DynamicAppIcons/digital-Icon-$60x60@3x.png"; sourceTree = ""; fileEncoding = undefined; lastKnownFileType = unknown; explicitFileType = undefined; includeInIndex = 0; }; - BD4B984B897F455B85208999 /* digital-Icon-$60x60@2x~ipad.png */ = {isa = PBXFileReference; name = "digital-Icon-$60x60@2x~ipad.png"; path = "6pm/DynamicAppIcons/digital-Icon-$60x60@2x~ipad.png"; sourceTree = ""; fileEncoding = undefined; lastKnownFileType = unknown; explicitFileType = undefined; includeInIndex = 0; }; - 7FAF182A3095411BB6DF1944 /* digital-Icon-$60x60@3x~ipad.png */ = {isa = PBXFileReference; name = "digital-Icon-$60x60@3x~ipad.png"; path = "6pm/DynamicAppIcons/digital-Icon-$60x60@3x~ipad.png"; sourceTree = ""; fileEncoding = undefined; lastKnownFileType = unknown; explicitFileType = undefined; includeInIndex = 0; }; - 08C366D51C3A4B21BCDCB271 /* original-Icon-$60x60@2x.png */ = {isa = PBXFileReference; name = "original-Icon-$60x60@2x.png"; path = "6pm/DynamicAppIcons/original-Icon-$60x60@2x.png"; sourceTree = ""; fileEncoding = undefined; lastKnownFileType = unknown; explicitFileType = undefined; includeInIndex = 0; }; - B3A32AA9717C4A338798E492 /* original-Icon-$60x60@3x.png */ = {isa = PBXFileReference; name = "original-Icon-$60x60@3x.png"; path = "6pm/DynamicAppIcons/original-Icon-$60x60@3x.png"; sourceTree = ""; fileEncoding = undefined; lastKnownFileType = unknown; explicitFileType = undefined; includeInIndex = 0; }; - B53D1D6A002E41C4A6D1DFE0 /* original-Icon-$60x60@2x~ipad.png */ = {isa = PBXFileReference; name = "original-Icon-$60x60@2x~ipad.png"; path = "6pm/DynamicAppIcons/original-Icon-$60x60@2x~ipad.png"; sourceTree = ""; fileEncoding = undefined; lastKnownFileType = unknown; explicitFileType = undefined; includeInIndex = 0; }; - 76E3F4CC592144D0A17A15D3 /* original-Icon-$60x60@3x~ipad.png */ = {isa = PBXFileReference; name = "original-Icon-$60x60@3x~ipad.png"; path = "6pm/DynamicAppIcons/original-Icon-$60x60@3x~ipad.png"; sourceTree = ""; fileEncoding = undefined; lastKnownFileType = unknown; explicitFileType = undefined; includeInIndex = 0; }; + 8AE181AAAD0247AA9B1AA6E5 /* dark-Icon-$60x60@2x.png */ = {isa = PBXFileReference; name = "dark-Icon-$60x60@2x.png"; path = "6pm/DynamicAppIcons/dark-Icon-$60x60@2x.png"; sourceTree = ""; fileEncoding = undefined; lastKnownFileType = unknown; explicitFileType = undefined; includeInIndex = 0; }; + C09DA74A2DFB4364A9D9E36B /* dark-Icon-$60x60@3x.png */ = {isa = PBXFileReference; name = "dark-Icon-$60x60@3x.png"; path = "6pm/DynamicAppIcons/dark-Icon-$60x60@3x.png"; sourceTree = ""; fileEncoding = undefined; lastKnownFileType = unknown; explicitFileType = undefined; includeInIndex = 0; }; + 0450EF9B96CE4206A1883DF9 /* dark-Icon-$60x60@2x~ipad.png */ = {isa = PBXFileReference; name = "dark-Icon-$60x60@2x~ipad.png"; path = "6pm/DynamicAppIcons/dark-Icon-$60x60@2x~ipad.png"; sourceTree = ""; fileEncoding = undefined; lastKnownFileType = unknown; explicitFileType = undefined; includeInIndex = 0; }; + 95BC66CE48074124A42F38C2 /* dark-Icon-$60x60@3x~ipad.png */ = {isa = PBXFileReference; name = "dark-Icon-$60x60@3x~ipad.png"; path = "6pm/DynamicAppIcons/dark-Icon-$60x60@3x~ipad.png"; sourceTree = ""; fileEncoding = undefined; lastKnownFileType = unknown; explicitFileType = undefined; includeInIndex = 0; }; + 6F922BBFF4194EBB99167D28 /* light-Icon-$60x60@2x.png */ = {isa = PBXFileReference; name = "light-Icon-$60x60@2x.png"; path = "6pm/DynamicAppIcons/light-Icon-$60x60@2x.png"; sourceTree = ""; fileEncoding = undefined; lastKnownFileType = unknown; explicitFileType = undefined; includeInIndex = 0; }; + AA515C41595F4BF8B2D7C852 /* light-Icon-$60x60@3x.png */ = {isa = PBXFileReference; name = "light-Icon-$60x60@3x.png"; path = "6pm/DynamicAppIcons/light-Icon-$60x60@3x.png"; sourceTree = ""; fileEncoding = undefined; lastKnownFileType = unknown; explicitFileType = undefined; includeInIndex = 0; }; + 1AE79E9F89CA4B568CDC67B9 /* light-Icon-$60x60@2x~ipad.png */ = {isa = PBXFileReference; name = "light-Icon-$60x60@2x~ipad.png"; path = "6pm/DynamicAppIcons/light-Icon-$60x60@2x~ipad.png"; sourceTree = ""; fileEncoding = undefined; lastKnownFileType = unknown; explicitFileType = undefined; includeInIndex = 0; }; + F09F606E033242C0B2E37E87 /* light-Icon-$60x60@3x~ipad.png */ = {isa = PBXFileReference; name = "light-Icon-$60x60@3x~ipad.png"; path = "6pm/DynamicAppIcons/light-Icon-$60x60@3x~ipad.png"; sourceTree = ""; fileEncoding = undefined; lastKnownFileType = unknown; explicitFileType = undefined; includeInIndex = 0; }; + 1569C49E7D104F6E8D8A69CC /* digital-Icon-$60x60@2x.png */ = {isa = PBXFileReference; name = "digital-Icon-$60x60@2x.png"; path = "6pm/DynamicAppIcons/digital-Icon-$60x60@2x.png"; sourceTree = ""; fileEncoding = undefined; lastKnownFileType = unknown; explicitFileType = undefined; includeInIndex = 0; }; + 7CE9B83E0934443389DD706D /* digital-Icon-$60x60@3x.png */ = {isa = PBXFileReference; name = "digital-Icon-$60x60@3x.png"; path = "6pm/DynamicAppIcons/digital-Icon-$60x60@3x.png"; sourceTree = ""; fileEncoding = undefined; lastKnownFileType = unknown; explicitFileType = undefined; includeInIndex = 0; }; + E80D36216A6541A2B4359422 /* digital-Icon-$60x60@2x~ipad.png */ = {isa = PBXFileReference; name = "digital-Icon-$60x60@2x~ipad.png"; path = "6pm/DynamicAppIcons/digital-Icon-$60x60@2x~ipad.png"; sourceTree = ""; fileEncoding = undefined; lastKnownFileType = unknown; explicitFileType = undefined; includeInIndex = 0; }; + 693DEDBEE1E74385B0D5E47F /* digital-Icon-$60x60@3x~ipad.png */ = {isa = PBXFileReference; name = "digital-Icon-$60x60@3x~ipad.png"; path = "6pm/DynamicAppIcons/digital-Icon-$60x60@3x~ipad.png"; sourceTree = ""; fileEncoding = undefined; lastKnownFileType = unknown; explicitFileType = undefined; includeInIndex = 0; }; + 50830C30CD1049FD86737A95 /* original-Icon-$60x60@2x.png */ = {isa = PBXFileReference; name = "original-Icon-$60x60@2x.png"; path = "6pm/DynamicAppIcons/original-Icon-$60x60@2x.png"; sourceTree = ""; fileEncoding = undefined; lastKnownFileType = unknown; explicitFileType = undefined; includeInIndex = 0; }; + E90F9E953896402591338650 /* original-Icon-$60x60@3x.png */ = {isa = PBXFileReference; name = "original-Icon-$60x60@3x.png"; path = "6pm/DynamicAppIcons/original-Icon-$60x60@3x.png"; sourceTree = ""; fileEncoding = undefined; lastKnownFileType = unknown; explicitFileType = undefined; includeInIndex = 0; }; + 926873AE9619426F9B998533 /* original-Icon-$60x60@2x~ipad.png */ = {isa = PBXFileReference; name = "original-Icon-$60x60@2x~ipad.png"; path = "6pm/DynamicAppIcons/original-Icon-$60x60@2x~ipad.png"; sourceTree = ""; fileEncoding = undefined; lastKnownFileType = unknown; explicitFileType = undefined; includeInIndex = 0; }; + 920649AAEE8A4688983D03A4 /* original-Icon-$60x60@3x~ipad.png */ = {isa = PBXFileReference; name = "original-Icon-$60x60@3x~ipad.png"; path = "6pm/DynamicAppIcons/original-Icon-$60x60@3x~ipad.png"; sourceTree = ""; fileEncoding = undefined; lastKnownFileType = unknown; explicitFileType = undefined; includeInIndex = 0; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ @@ -162,22 +162,22 @@ CB8E79DF79AB447E92B6ADBE /* DynamicAppIcons */ = { isa = PBXGroup; children = ( - C224E6DA45F6492D80AFC45D /* dark-Icon-$60x60@2x.png */, - 3049E96034E14262990BBE57 /* dark-Icon-$60x60@3x.png */, - 859709507FC3404FAA16B8AB /* dark-Icon-$60x60@2x~ipad.png */, - C89D4713D16E42759388C089 /* dark-Icon-$60x60@3x~ipad.png */, - C5235AD8C3BA4189894CB1E2 /* light-Icon-$60x60@2x.png */, - 1957B3D5E23A48FFA16A7D4A /* light-Icon-$60x60@3x.png */, - BCFAED807C1D48358DF93C01 /* light-Icon-$60x60@2x~ipad.png */, - 9BF680DA91684AE6843BCDDE /* light-Icon-$60x60@3x~ipad.png */, - E4944EEA3A0347AEBED34BF5 /* digital-Icon-$60x60@2x.png */, - C4E44A340C384096966CA358 /* digital-Icon-$60x60@3x.png */, - BD4B984B897F455B85208999 /* digital-Icon-$60x60@2x~ipad.png */, - 7FAF182A3095411BB6DF1944 /* digital-Icon-$60x60@3x~ipad.png */, - 08C366D51C3A4B21BCDCB271 /* original-Icon-$60x60@2x.png */, - B3A32AA9717C4A338798E492 /* original-Icon-$60x60@3x.png */, - B53D1D6A002E41C4A6D1DFE0 /* original-Icon-$60x60@2x~ipad.png */, - 76E3F4CC592144D0A17A15D3 /* original-Icon-$60x60@3x~ipad.png */, + 8AE181AAAD0247AA9B1AA6E5 /* dark-Icon-$60x60@2x.png */, + C09DA74A2DFB4364A9D9E36B /* dark-Icon-$60x60@3x.png */, + 0450EF9B96CE4206A1883DF9 /* dark-Icon-$60x60@2x~ipad.png */, + 95BC66CE48074124A42F38C2 /* dark-Icon-$60x60@3x~ipad.png */, + 6F922BBFF4194EBB99167D28 /* light-Icon-$60x60@2x.png */, + AA515C41595F4BF8B2D7C852 /* light-Icon-$60x60@3x.png */, + 1AE79E9F89CA4B568CDC67B9 /* light-Icon-$60x60@2x~ipad.png */, + F09F606E033242C0B2E37E87 /* light-Icon-$60x60@3x~ipad.png */, + 1569C49E7D104F6E8D8A69CC /* digital-Icon-$60x60@2x.png */, + 7CE9B83E0934443389DD706D /* digital-Icon-$60x60@3x.png */, + E80D36216A6541A2B4359422 /* digital-Icon-$60x60@2x~ipad.png */, + 693DEDBEE1E74385B0D5E47F /* digital-Icon-$60x60@3x~ipad.png */, + 50830C30CD1049FD86737A95 /* original-Icon-$60x60@2x.png */, + E90F9E953896402591338650 /* original-Icon-$60x60@3x.png */, + 926873AE9619426F9B998533 /* original-Icon-$60x60@2x~ipad.png */, + 920649AAEE8A4688983D03A4 /* original-Icon-$60x60@3x~ipad.png */, ); name = DynamicAppIcons; path = ""; @@ -268,22 +268,22 @@ 13B07FBF1A68108700A75B9A /* Images.xcassets in Resources */, 3E461D99554A48A4959DE609 /* SplashScreen.storyboard in Resources */, DEE1C0AF3858C12C88E3160B /* PrivacyInfo.xcprivacy in Resources */, - 3BB2EBF26496492E9C5291AE /* dark-Icon-$60x60@2x.png in Resources */, - 8D1EA12517904B58A4060C92 /* dark-Icon-$60x60@3x.png in Resources */, - B4F5C53D92C947538F8F0E3D /* dark-Icon-$60x60@2x~ipad.png in Resources */, - B8F1DB250ADA4AA4A31AC550 /* dark-Icon-$60x60@3x~ipad.png in Resources */, - 254E59C792FC4A75B5C140CA /* light-Icon-$60x60@2x.png in Resources */, - 40CD5016A8414B28A587BD3F /* light-Icon-$60x60@3x.png in Resources */, - D209B3B2B07D40F39ACE541A /* light-Icon-$60x60@2x~ipad.png in Resources */, - DD39B8087D944E3E936B042F /* light-Icon-$60x60@3x~ipad.png in Resources */, - 501625193CE44138B9EA1DA0 /* digital-Icon-$60x60@2x.png in Resources */, - 33BC544FAE3D454F818DDD37 /* digital-Icon-$60x60@3x.png in Resources */, - 93033B72B452407D812C2F3A /* digital-Icon-$60x60@2x~ipad.png in Resources */, - 32FF1BC21A14481DBB6C5461 /* digital-Icon-$60x60@3x~ipad.png in Resources */, - CBEA844903474EDFA4DD0F0F /* original-Icon-$60x60@2x.png in Resources */, - 3D818C37A72642309F5DA6BD /* original-Icon-$60x60@3x.png in Resources */, - 1F938078E62244CFA74BA2E8 /* original-Icon-$60x60@2x~ipad.png in Resources */, - 24908DA86A11404AA436ABB2 /* original-Icon-$60x60@3x~ipad.png in Resources */, + 9AAE6F7B17474514A4F6A076 /* dark-Icon-$60x60@2x.png in Resources */, + 8F887BD4EBDF493CAB9DA7BB /* dark-Icon-$60x60@3x.png in Resources */, + 62A0F5C2C8A64B0B8F03F755 /* dark-Icon-$60x60@2x~ipad.png in Resources */, + 5639C190B4F34D70B21AF34E /* dark-Icon-$60x60@3x~ipad.png in Resources */, + 1F934D5C53694A329D8B42EE /* light-Icon-$60x60@2x.png in Resources */, + 8585711A3D4048239326F927 /* light-Icon-$60x60@3x.png in Resources */, + A72C8E349C2A43B5AD8E07E2 /* light-Icon-$60x60@2x~ipad.png in Resources */, + 048EB12DC4334C6A8FE31AA2 /* light-Icon-$60x60@3x~ipad.png in Resources */, + EAC0082CEAA340A6880EB1DD /* digital-Icon-$60x60@2x.png in Resources */, + 9071AE06FF3141A3B7EB371F /* digital-Icon-$60x60@3x.png in Resources */, + 8286A99373C74812B4809C56 /* digital-Icon-$60x60@2x~ipad.png in Resources */, + E3AB74344A33432E9E41E3BC /* digital-Icon-$60x60@3x~ipad.png in Resources */, + D9784C09B1EF4A45B43C4D76 /* original-Icon-$60x60@2x.png in Resources */, + 0063D34B83404FE6B734E0F7 /* original-Icon-$60x60@3x.png in Resources */, + 935DA4111571499A9AA68A56 /* original-Icon-$60x60@2x~ipad.png in Resources */, + A908A88A8A76484A9C44E02E /* original-Icon-$60x60@3x~ipad.png in Resources */, ); runOnlyForDeploymentPostprocessing = 0; }; diff --git a/apps/mobile/package.json b/apps/mobile/package.json index 23e1c98f..ea5ef114 100644 --- a/apps/mobile/package.json +++ b/apps/mobile/package.json @@ -107,7 +107,7 @@ "svg-path-properties": "^1.3.0", "tailwind-merge": "^2.3.0", "tailwindcss-animate": "^1.0.7", - "victory-native": "^41.0.2", + "victory-native": "^41.4.0", "zod": "^3.23.8", "zustand": "^4.5.4" }, diff --git a/apps/mobile/tailwind.config.js b/apps/mobile/tailwind.config.js index f9460208..7775f67c 100644 --- a/apps/mobile/tailwind.config.js +++ b/apps/mobile/tailwind.config.js @@ -16,7 +16,6 @@ module.exports = { }, extend: { fontFamily: { - mono: ['Space Mono'], regular: ['Haskoy-Regular'], medium: ['Haskoy-Medium'], semiBold: ['Haskoy-SemiBold'], diff --git a/packages/currency/src/formatter.ts b/packages/currency/src/formatter.ts index abaaa93c..99872c0b 100644 --- a/packages/currency/src/formatter.ts +++ b/packages/currency/src/formatter.ts @@ -1,4 +1,5 @@ export function nFormatter(num: number, digits: number) { + 'worklet' const lookup = [ { value: 1, symbol: '' }, { value: 1e3, symbol: 'k' }, diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 99f96891..768624fd 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -293,7 +293,7 @@ importers: version: 0.28.16(expo@51.0.31(@babel/core@7.25.2)(@babel/preset-env@7.25.4(@babel/core@7.25.2))) expo-router: specifier: ~3.5.15 - version: 3.5.23(wdmb7b7dywngkq3iaob6t4cnwq) + version: 3.5.23(expo-constants@16.0.2(expo@51.0.31(@babel/core@7.25.2)(@babel/preset-env@7.25.4(@babel/core@7.25.2))))(expo-linking@6.3.1(expo@51.0.31(@babel/core@7.25.2)(@babel/preset-env@7.25.4(@babel/core@7.25.2))))(expo-modules-autolinking@1.11.2)(expo-status-bar@1.12.1)(expo@51.0.31(@babel/core@7.25.2)(@babel/preset-env@7.25.4(@babel/core@7.25.2)))(react-native-reanimated@3.10.1(@babel/core@7.25.2)(react-native@0.74.2(@babel/core@7.25.2)(@babel/preset-env@7.25.4(@babel/core@7.25.2))(@types/react@18.2.79)(react@18.3.1))(react@18.3.1))(react-native-safe-area-context@4.10.1(react-native@0.74.2(@babel/core@7.25.2)(@babel/preset-env@7.25.4(@babel/core@7.25.2))(@types/react@18.2.79)(react@18.3.1))(react@18.3.1))(react-native-screens@3.31.1(react-native@0.74.2(@babel/core@7.25.2)(@babel/preset-env@7.25.4(@babel/core@7.25.2))(@types/react@18.2.79)(react@18.3.1))(react@18.3.1))(react-native@0.74.2(@babel/core@7.25.2)(@babel/preset-env@7.25.4(@babel/core@7.25.2))(@types/react@18.2.79)(react@18.3.1))(react@18.3.1)(typescript@5.3.3) expo-secure-store: specifier: ^13.0.1 version: 13.0.2(expo@51.0.31(@babel/core@7.25.2)(@babel/preset-env@7.25.4(@babel/core@7.25.2))) @@ -376,8 +376,8 @@ importers: specifier: ^1.0.7 version: 1.0.7(tailwindcss@3.4.10) victory-native: - specifier: ^41.0.2 - version: 41.1.0(@shopify/react-native-skia@1.2.3(react-native-reanimated@3.10.1(@babel/core@7.25.2)(react-native@0.74.2(@babel/core@7.25.2)(@babel/preset-env@7.25.4(@babel/core@7.25.2))(@types/react@18.2.79)(react@18.3.1))(react@18.3.1))(react-native@0.74.2(@babel/core@7.25.2)(@babel/preset-env@7.25.4(@babel/core@7.25.2))(@types/react@18.2.79)(react@18.3.1))(react@18.3.1))(react-native-gesture-handler@2.16.2(react-native@0.74.2(@babel/core@7.25.2)(@babel/preset-env@7.25.4(@babel/core@7.25.2))(@types/react@18.2.79)(react@18.3.1))(react@18.3.1))(react-native-reanimated@3.10.1(@babel/core@7.25.2)(react-native@0.74.2(@babel/core@7.25.2)(@babel/preset-env@7.25.4(@babel/core@7.25.2))(@types/react@18.2.79)(react@18.3.1))(react@18.3.1))(react-native@0.74.2(@babel/core@7.25.2)(@babel/preset-env@7.25.4(@babel/core@7.25.2))(@types/react@18.2.79)(react@18.3.1))(react@18.3.1) + specifier: ^41.4.0 + version: 41.4.0(@shopify/react-native-skia@1.2.3(react-native-reanimated@3.10.1(@babel/core@7.25.2)(react-native@0.74.2(@babel/core@7.25.2)(@babel/preset-env@7.25.4(@babel/core@7.25.2))(@types/react@18.2.79)(react@18.3.1))(react@18.3.1))(react-native@0.74.2(@babel/core@7.25.2)(@babel/preset-env@7.25.4(@babel/core@7.25.2))(@types/react@18.2.79)(react@18.3.1))(react@18.3.1))(react-native-gesture-handler@2.16.2(react-native@0.74.2(@babel/core@7.25.2)(@babel/preset-env@7.25.4(@babel/core@7.25.2))(@types/react@18.2.79)(react@18.3.1))(react@18.3.1))(react-native-reanimated@3.10.1(@babel/core@7.25.2)(react-native@0.74.2(@babel/core@7.25.2)(@babel/preset-env@7.25.4(@babel/core@7.25.2))(@types/react@18.2.79)(react@18.3.1))(react@18.3.1))(react-native@0.74.2(@babel/core@7.25.2)(@babel/preset-env@7.25.4(@babel/core@7.25.2))(@types/react@18.2.79)(react@18.3.1))(react@18.3.1) zod: specifier: ^3.23.8 version: 3.23.8 @@ -2553,7 +2553,7 @@ packages: resolution: {integrity: sha512-bUzP4Awlljx5RKEExw8WYtif8EuQni2glDaieYROKTnaxsu9kEIA515sXQgUDZU4Ob12VoL7+z70uO3qrlfXcQ==} peerDependencies: '@react-navigation/native': ^6.0.0 - react: '*' + react: 18.2.0 react-native: '*' react-native-safe-area-context: '>= 3.0.0' @@ -2569,7 +2569,7 @@ packages: '@react-navigation/native@6.1.18': resolution: {integrity: sha512-mIT9MiL/vMm4eirLcmw2h6h/Nm5FICtnYSdohq4vTLA2FF/6PNhByM7s8ffqoVfE5L0uAa6Xda1B7oddolUiGg==} peerDependencies: - react: '*' + react: 18.2.0 react-native: '*' '@react-navigation/routers@6.1.9': @@ -7344,8 +7344,8 @@ packages: resolution: {integrity: sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==} engines: {node: '>= 0.8'} - victory-native@41.1.0: - resolution: {integrity: sha512-BkVfXIEc/wMaICkiVTASGWjDlrrx4OHvn3xtG2b6zaks5Po2PXpXinvgfAdwHgBro9NHP0DrBQfNyxBCnNZJHw==} + victory-native@41.4.0: + resolution: {integrity: sha512-P1vSyfBnyNTUTuM0asR51J2GIsfPwPATx3y+ouwdVNCNhnpXv6WsyFbR1xMh1G20GG114+y8G/X6GtMhz8neTQ==} peerDependencies: '@shopify/react-native-skia': '>=1.2.3' react: '*' @@ -12450,8 +12450,8 @@ snapshots: - encoding - supports-color - expo-router@3.5.23(wdmb7b7dywngkq3iaob6t4cnwq): - dependencies: + ? expo-router@3.5.23(expo-constants@16.0.2(expo@51.0.31(@babel/core@7.25.2)(@babel/preset-env@7.25.4(@babel/core@7.25.2))))(expo-linking@6.3.1(expo@51.0.31(@babel/core@7.25.2)(@babel/preset-env@7.25.4(@babel/core@7.25.2))))(expo-modules-autolinking@1.11.2)(expo-status-bar@1.12.1)(expo@51.0.31(@babel/core@7.25.2)(@babel/preset-env@7.25.4(@babel/core@7.25.2)))(react-native-reanimated@3.10.1(@babel/core@7.25.2)(react-native@0.74.2(@babel/core@7.25.2)(@babel/preset-env@7.25.4(@babel/core@7.25.2))(@types/react@18.2.79)(react@18.3.1))(react@18.3.1))(react-native-safe-area-context@4.10.1(react-native@0.74.2(@babel/core@7.25.2)(@babel/preset-env@7.25.4(@babel/core@7.25.2))(@types/react@18.2.79)(react@18.3.1))(react@18.3.1))(react-native-screens@3.31.1(react-native@0.74.2(@babel/core@7.25.2)(@babel/preset-env@7.25.4(@babel/core@7.25.2))(@types/react@18.2.79)(react@18.3.1))(react@18.3.1))(react-native@0.74.2(@babel/core@7.25.2)(@babel/preset-env@7.25.4(@babel/core@7.25.2))(@types/react@18.2.79)(react@18.3.1))(react@18.3.1)(typescript@5.3.3) + : dependencies: '@expo/metro-runtime': 3.2.3(react-native@0.74.2(@babel/core@7.25.2)(@babel/preset-env@7.25.4(@babel/core@7.25.2))(@types/react@18.2.79)(react@18.3.1)) '@expo/server': 0.4.4(typescript@5.3.3) '@radix-ui/react-slot': 1.0.1(react@18.3.1) @@ -15936,7 +15936,7 @@ snapshots: vary@1.1.2: {} - victory-native@41.1.0(@shopify/react-native-skia@1.2.3(react-native-reanimated@3.10.1(@babel/core@7.25.2)(react-native@0.74.2(@babel/core@7.25.2)(@babel/preset-env@7.25.4(@babel/core@7.25.2))(@types/react@18.2.79)(react@18.3.1))(react@18.3.1))(react-native@0.74.2(@babel/core@7.25.2)(@babel/preset-env@7.25.4(@babel/core@7.25.2))(@types/react@18.2.79)(react@18.3.1))(react@18.3.1))(react-native-gesture-handler@2.16.2(react-native@0.74.2(@babel/core@7.25.2)(@babel/preset-env@7.25.4(@babel/core@7.25.2))(@types/react@18.2.79)(react@18.3.1))(react@18.3.1))(react-native-reanimated@3.10.1(@babel/core@7.25.2)(react-native@0.74.2(@babel/core@7.25.2)(@babel/preset-env@7.25.4(@babel/core@7.25.2))(@types/react@18.2.79)(react@18.3.1))(react@18.3.1))(react-native@0.74.2(@babel/core@7.25.2)(@babel/preset-env@7.25.4(@babel/core@7.25.2))(@types/react@18.2.79)(react@18.3.1))(react@18.3.1): + victory-native@41.4.0(@shopify/react-native-skia@1.2.3(react-native-reanimated@3.10.1(@babel/core@7.25.2)(react-native@0.74.2(@babel/core@7.25.2)(@babel/preset-env@7.25.4(@babel/core@7.25.2))(@types/react@18.2.79)(react@18.3.1))(react@18.3.1))(react-native@0.74.2(@babel/core@7.25.2)(@babel/preset-env@7.25.4(@babel/core@7.25.2))(@types/react@18.2.79)(react@18.3.1))(react@18.3.1))(react-native-gesture-handler@2.16.2(react-native@0.74.2(@babel/core@7.25.2)(@babel/preset-env@7.25.4(@babel/core@7.25.2))(@types/react@18.2.79)(react@18.3.1))(react@18.3.1))(react-native-reanimated@3.10.1(@babel/core@7.25.2)(react-native@0.74.2(@babel/core@7.25.2)(@babel/preset-env@7.25.4(@babel/core@7.25.2))(@types/react@18.2.79)(react@18.3.1))(react@18.3.1))(react-native@0.74.2(@babel/core@7.25.2)(@babel/preset-env@7.25.4(@babel/core@7.25.2))(@types/react@18.2.79)(react@18.3.1))(react@18.3.1): dependencies: '@shopify/react-native-skia': 1.2.3(react-native-reanimated@3.10.1(@babel/core@7.25.2)(react-native@0.74.2(@babel/core@7.25.2)(@babel/preset-env@7.25.4(@babel/core@7.25.2))(@types/react@18.2.79)(react@18.3.1))(react@18.3.1))(react-native@0.74.2(@babel/core@7.25.2)(@babel/preset-env@7.25.4(@babel/core@7.25.2))(@types/react@18.2.79)(react@18.3.1))(react@18.3.1) d3-scale: 4.0.2