Skip to content

Commit c18da69

Browse files
committed
feat(rn): impl list setting pages
Signed-off-by: Innei <tukon479@gmail.com>
1 parent 0d124ff commit c18da69

File tree

20 files changed

+375
-14
lines changed

20 files changed

+375
-14
lines changed

apps/mobile/package.json

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
"@follow/models": "workspace:*",
2424
"@follow/shared": "workspace:*",
2525
"@follow/utils": "workspace:*",
26+
"@formatjs/intl-numberformat": "8.15.2",
2627
"@gorhom/portal": "1.0.14",
2728
"@hookform/resolvers": "3.9.1",
2829
"@infinite-list/data-model": "2.2.10",
@@ -36,6 +37,7 @@
3637
"better-auth": "1.1.9-beta.1",
3738
"cookie-es": "^1.2.2",
3839
"dayjs": "1.11.13",
40+
"dnum": "^2.14.0",
3941
"es-toolkit": "1.29.0",
4042
"expo": "52.0.18",
4143
"expo-apple-authentication": "~7.1.2",
Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
import { cn, toScientificNotation } from "@follow/utils"
2+
import { Text } from "react-native"
3+
4+
export const Balance = ({
5+
children,
6+
7+
className,
8+
precision = 2,
9+
}: {
10+
/** The token balance in wei. */
11+
children: bigint
12+
13+
className?: string
14+
precision?: number
15+
}) => {
16+
const n = BigInt(children || 0n)
17+
const formatted = format(n, { digits: precision, trailingZeros: true })
18+
19+
return <Text className={cn("tabular-nums", className)}>{formatted}</Text>
20+
}
21+
22+
function format(
23+
value: bigint,
24+
options:
25+
| number
26+
| {
27+
digits?: number
28+
compact?: boolean
29+
trailingZeros?: boolean
30+
locale?: string
31+
decimalsRounding?: "ROUND_HALF" | "ROUND_UP" | "ROUND_DOWN"
32+
signDisplay?: "auto" | "always" | "exceptZero" | "negative" | "never"
33+
} = {},
34+
): string {
35+
// Normalize options
36+
const opts = typeof options === "number" ? { digits: options } : options
37+
const {
38+
digits,
39+
compact = false,
40+
trailingZeros = false,
41+
locale = "en-US",
42+
43+
signDisplay = "auto",
44+
} = opts
45+
46+
// Convert bigint to number for formatting
47+
const num = Number(value) / 1e18 // Assuming 18 decimals (wei to ether conversion)
48+
49+
if (compact) {
50+
return new Intl.NumberFormat(locale, {
51+
notation: "compact",
52+
maximumFractionDigits: digits,
53+
minimumFractionDigits: trailingZeros ? digits : 0,
54+
signDisplay,
55+
}).format(num)
56+
}
57+
58+
// For very large or small numbers, use scientific notation
59+
if (Math.abs(num) > 1e9 || (Math.abs(num) < 1e-9 && num !== 0)) {
60+
return toScientificNotation(num.toString(), 10)
61+
}
62+
63+
return new Intl.NumberFormat(locale, {
64+
maximumFractionDigits: digits,
65+
minimumFractionDigits: trailingZeros ? digits : 0,
66+
signDisplay,
67+
useGrouping: true,
68+
}).format(num)
69+
}

apps/mobile/src/components/ui/grouped/GroupedList.tsx

Lines changed: 28 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import { Fragment } from "react"
55
import type { ViewProps } from "react-native"
66
import { Pressable, StyleSheet, Text, View } from "react-native"
77

8+
import { MingcuteRightLine } from "@/src/icons/mingcute_right_line"
89
import { RightCuteReIcon } from "@/src/icons/right_cute_re"
910
import { useColor } from "@/src/theme/colors"
1011

@@ -91,7 +92,7 @@ export const GroupedInsetListNavigationLink: FC<{
9192
<Text className={"text-label text-[16px]"}>{label}</Text>
9293
</View>
9394
<View className="-mr-2 ml-4">
94-
<RightCuteReIcon height={18} width={18} color={rightIconColor} />
95+
<MingcuteRightLine height={18} width={18} color={rightIconColor} />
9596
</View>
9697
</View>
9798
</GroupedInsetListBaseCell>
@@ -160,3 +161,29 @@ export const GroupedInsetListActionCell: FC<{
160161
</Pressable>
161162
)
162163
}
164+
165+
export const GroupedInformationCell: FC<{
166+
title: string
167+
description?: string
168+
icon?: React.ReactNode
169+
iconBackgroundColor?: string
170+
}> = ({ title, description, icon, iconBackgroundColor }) => {
171+
return (
172+
<GroupedInsetListBaseCell className="flex-1 flex-col items-center justify-center rounded-[16px] p-6">
173+
{icon && (
174+
<View
175+
className="mb-3 size-[64px] items-center justify-center rounded-xl p-1"
176+
style={{ backgroundColor: iconBackgroundColor }}
177+
>
178+
{icon}
179+
</View>
180+
)}
181+
<Text className="text-3xl font-bold">{title}</Text>
182+
{!!description && (
183+
<Text className="text-label mt-3 text-balance text-center text-base leading-tight">
184+
{description}
185+
</Text>
186+
)}
187+
</GroupedInsetListBaseCell>
188+
)
189+
}

apps/mobile/src/components/ui/loading/index.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ export const LoadingIndicator: FC<
2020
color?: string
2121
className?: string
2222
} & PropsWithChildren
23-
> = ({ size = 60, color, children, className }) => {
23+
> = ({ size = 36, color, children, className }) => {
2424
const rotateValue = useSharedValue(0)
2525

2626
const rotation = useDerivedValue(() => {
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
import * as React from "react"
2+
import Svg, { Path } from "react-native-svg"
3+
4+
interface UserAdd2CuteFiIconProps {
5+
width?: number
6+
height?: number
7+
color?: string
8+
}
9+
10+
export const UserAdd2CuteFiIcon = ({
11+
width = 24,
12+
height = 24,
13+
color = "#10161F",
14+
}: UserAdd2CuteFiIconProps) => {
15+
return (
16+
<Svg width={width} height={height} fill="none" viewBox="0 0 24 24">
17+
<Path fill="#fff" fillOpacity={0.01} d="M24 0v24H0V0z" />
18+
<Path
19+
fill={color}
20+
d="M6 7a5 5 0 1 1 10 0A5 5 0 0 1 6 7M4.822 14.672C6.425 13.694 8.605 13 11 13c.447 0 .887.024 1.316.07a1 1 0 0 1 .72 1.557A5.968 5.968 0 0 0 12 18c0 .92.207 1.79.575 2.567a1 1 0 0 1-.89 1.428c-.226.003-.455.005-.685.005-2.229 0-4.335-.14-5.913-.558-.785-.208-1.524-.506-2.084-.956C2.41 20.01 2 19.345 2 18.5c0-.787.358-1.523.844-2.139.494-.625 1.177-1.2 1.978-1.69M18 14a1 1 0 0 1 1 1v2h2a1 1 0 1 1 0 2h-2v2a1 1 0 1 1-2 0v-2h-2a1 1 0 1 1 0-2h2v-2a1 1 0 0 1 1-1"
21+
/>
22+
</Svg>
23+
)
24+
}
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
import * as React from "react"
2+
import Svg, { Path } from "react-native-svg"
3+
4+
interface Wallet2CuteFiIconProps {
5+
width?: number
6+
height?: number
7+
color?: string
8+
}
9+
10+
export const Wallet2CuteFiIcon = ({
11+
width = 24,
12+
height = 24,
13+
color = "#10161F",
14+
}: Wallet2CuteFiIconProps) => {
15+
return (
16+
<Svg width={width} height={height} fill="none" viewBox="0 0 24 24">
17+
<Path fill="#fff" fillOpacity={0.01} d="M24 0v24H0V0z" />
18+
<Path
19+
fill={color}
20+
fillRule="evenodd"
21+
d="M9.06 4.647a.31.31 0 0 0-.06.069c0 .01.008.086.137.231.14.157.375.335.702.504.66.342 1.503.549 2.161.549.658 0 1.502-.207 2.161-.549.327-.169.561-.347.702-.504.129-.145.136-.22.137-.231a.309.309 0 0 0-.06-.069c-.106-.094-.31-.213-.639-.325C13.647 4.102 12.765 4 12 4c-.765 0-1.647.101-2.301.322-.33.112-.533.23-.638.325m6.63 2.214c.242-.17.469-.363.663-.58.353-.395.647-.925.647-1.567 0-.666-.317-1.188-.723-1.553-.386-.348-.872-.577-1.336-.733C14.01 2.113 12.892 2 12 2c-.892 0-2.01.113-2.941.428-.464.156-.95.385-1.336.733C7.317 3.526 7 4.048 7 4.714c0 .642.294 1.172.647 1.566.194.218.42.411.663.581C5.325 8.284 3 11.335 3 15c0 2.556 1.02 4.386 2.766 5.525C7.441 21.617 9.67 22 12 22s4.56-.383 6.234-1.475C19.98 19.386 21 17.555 21 15c0-3.665-2.325-6.716-5.31-8.139m-4.296 4.192a1 1 0 1 0-1.788.894L10.132 13H10a1 1 0 1 0 0 2h1v.5h-1a1 1 0 1 0 0 2h1v.5a1 1 0 1 0 2 0v-.5h1a1 1 0 1 0 0-2h-1V15h1a1 1 0 1 0 0-2h-.132l.526-1.053a1 1 0 1 0-1.788-.894L12 12.263z"
22+
clipRule="evenodd"
23+
/>
24+
</Svg>
25+
)
26+
}

apps/mobile/src/modules/discover/search-tabs/hooks.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ export const useDataSkeleton = (isLoading: boolean, data: any) => {
1515
return (
1616
<BaseSearchPageRootView className="items-center justify-center">
1717
<View className="-mt-72" />
18-
<LoadingIndicator color={withOpacity(textColor, 0.7)} size={32} />
18+
<LoadingIndicator color={withOpacity(textColor, 0.7)} />
1919
</BaseSearchPageRootView>
2020
)
2121
}

apps/mobile/src/modules/feed-drawer/feed-panel.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -210,7 +210,7 @@ const SubscriptionItem = memo(({ id, className }: { id: string; className?: stri
210210
if (isLoading) {
211211
return (
212212
<View className="mt-24 flex-1 flex-row items-start justify-center">
213-
<LoadingIndicator size={36} />
213+
<LoadingIndicator />
214214
</View>
215215
)
216216
}

apps/mobile/src/modules/feed/FollowFeed.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ export function FollowFeed(props: { id: string }) {
4040
if (isLoading) {
4141
return (
4242
<View className="mt-24 flex-1 flex-row items-start justify-center">
43-
<LoadingIndicator size={36} />
43+
<LoadingIndicator />
4444
</View>
4545
)
4646
}

apps/mobile/src/modules/list/FollowList.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ export const FollowList = (props: { id: string }) => {
3838
if (isLoading) {
3939
return (
4040
<View className="mt-24 flex-1 flex-row items-start justify-center">
41-
<LoadingIndicator size={36} />
41+
<LoadingIndicator />
4242
</View>
4343
)
4444
}

apps/mobile/src/modules/settings/SettingsList.tsx

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,7 @@ const UserGroupNavigationLinks: GroupNavigationLink[] = [
6060
navigation.navigate("Achievement")
6161
},
6262
iconBackgroundColor: "#6366F1",
63+
todo: true,
6364
},
6465
]
6566

@@ -107,6 +108,7 @@ const DataGroupNavigationLinks: GroupNavigationLink[] = [
107108
navigation.navigate("Actions")
108109
},
109110
iconBackgroundColor: "#059669",
111+
todo: true,
110112
},
111113

112114
{
@@ -116,6 +118,7 @@ const DataGroupNavigationLinks: GroupNavigationLink[] = [
116118
navigation.navigate("Feeds")
117119
},
118120
iconBackgroundColor: "#10B981",
121+
todo: true,
119122
},
120123
{
121124
label: "Lists",
@@ -124,6 +127,7 @@ const DataGroupNavigationLinks: GroupNavigationLink[] = [
124127
navigation.navigate("Lists")
125128
},
126129
iconBackgroundColor: "#34D399",
130+
// todo: true,
127131
},
128132
]
129133

0 commit comments

Comments
 (0)