u
This commit is contained in:
1 parent
d33cef825a
commit
295b3306a3
7 files changed
+477
-291
No files matched your search
@@ -1,6 +1,8 @@
|
||||
import type { LegendListRef } from '@legendapp/list'
|
||||
import type { MoneyCategoryItem } from '@/types/money/category'
|
||||
import { useCallback, useEffect, useMemo, useRef, useState } from 'react'
|
||||
import { FlatList, Pressable, Text, View } from 'react-native'
|
||||
import { LegendList } from '@legendapp/list'
|
||||
import { useEffect, useRef, useState } from 'react'
|
||||
import { Pressable, Text, View } from 'react-native'
|
||||
import { AButton, ADrawer, AInput } from '@/components/common/ao'
|
||||
import MoneyCategoryIcon from '@/components/common/MoneyCategoryIcon'
|
||||
import { useMoneyCategoryStore } from '@/store/moneyCategory'
|
||||
@@ -33,11 +35,8 @@ export default function CreateCategory({
|
||||
const [form, setForm] = useState<EditCategoryForm>({ icon: '', name: '' })
|
||||
const [confirmDisabled, setConfirmDisabled] = useState(true)
|
||||
const [confirmLoading, setConfirmLoading] = useState(false)
|
||||
const flatListData = Object.entries(moneyCategoryStore.ICON_GROUPS)
|
||||
const flatListData2 = Object.values(moneyCategoryStore.ICON_GROUPS).flat()
|
||||
const listRef = useRef<LegendListRef>(null)
|
||||
|
||||
const flatListRef = useRef<FlatList<any>>(null)
|
||||
// Drawer 打开/关闭控制
|
||||
useEffect(() => {
|
||||
setIsOpen(open)
|
||||
if (!open)
|
||||
@@ -47,24 +46,24 @@ export default function CreateCategory({
|
||||
// 确认按钮状态
|
||||
useEffect(() => {
|
||||
setConfirmDisabled(!(form.name && form.name.length <= 5 && form.icon))
|
||||
|
||||
const itemIndex = flatListData2.findIndex(item => item === form.icon)
|
||||
if (itemIndex === -1 || !flatListRef.current)
|
||||
return
|
||||
|
||||
if (form.icon) {
|
||||
setTimeout(() => {
|
||||
if (flatListRef.current) {
|
||||
flatListRef.current.scrollToIndex({
|
||||
index: Math.floor(itemIndex / 5),
|
||||
animated: true,
|
||||
viewPosition: 0.5,
|
||||
})
|
||||
}
|
||||
}, 0)
|
||||
}
|
||||
}, [form.name, form.icon])
|
||||
|
||||
useEffect(() => {
|
||||
if (!form.icon || !listRef.current) {
|
||||
return
|
||||
}
|
||||
|
||||
const index = moneyCategoryStore.findIconGroupsRow(form.icon)
|
||||
|
||||
if (index !== -1) {
|
||||
listRef.current.scrollToIndex({
|
||||
index,
|
||||
viewPosition: 0.5,
|
||||
animated: true,
|
||||
})
|
||||
}
|
||||
}, [form.icon])
|
||||
|
||||
// 编辑已有分类时填充数据
|
||||
useEffect(() => {
|
||||
if (category)
|
||||
@@ -77,55 +76,6 @@ export default function CreateCategory({
|
||||
onClose?.()
|
||||
}
|
||||
|
||||
// 渲染每组 Icon
|
||||
const renderGroup = useCallback(
|
||||
({ item }: { item: [string, string[]] }) => {
|
||||
const [groupName, icons] = item
|
||||
|
||||
return (
|
||||
<View className="mb-4">
|
||||
<Text className="text-center text-sm mb-3">{groupName}</Text>
|
||||
|
||||
<View className="flex flex-row flex-wrap">
|
||||
{icons.map((icon) => {
|
||||
const selected = form.icon === icon
|
||||
|
||||
return (
|
||||
<Pressable
|
||||
key={icon}
|
||||
className="w-1/5 mb-3 flex items-center"
|
||||
onPress={() =>
|
||||
setForm(v => ({
|
||||
...v,
|
||||
icon,
|
||||
}))}
|
||||
>
|
||||
<View
|
||||
style={{
|
||||
width: 46,
|
||||
height: 46,
|
||||
borderRadius: 28,
|
||||
justifyContent: 'center',
|
||||
alignItems: 'center',
|
||||
backgroundColor: selected ? '#333' : '#F3F4F6',
|
||||
}}
|
||||
>
|
||||
<MoneyCategoryIcon
|
||||
name={icon}
|
||||
size={32}
|
||||
color={selected ? '#fff' : '#000'}
|
||||
/>
|
||||
</View>
|
||||
</Pressable>
|
||||
)
|
||||
})}
|
||||
</View>
|
||||
</View>
|
||||
)
|
||||
},
|
||||
[form.icon],
|
||||
)
|
||||
|
||||
return (
|
||||
<ADrawer
|
||||
visible={isOpen}
|
||||
@@ -161,15 +111,72 @@ export default function CreateCategory({
|
||||
</View>
|
||||
)}
|
||||
>
|
||||
<FlatList
|
||||
ref={flatListRef}
|
||||
data={flatListData}
|
||||
keyExtractor={([groupName]) => groupName}
|
||||
renderItem={renderGroup}
|
||||
getItemLayout={(data, index) => {
|
||||
return { length: 80, offset: 80 * index, index }
|
||||
}}
|
||||
/>
|
||||
<View className="flex-1">
|
||||
<AInput
|
||||
className="mx-4 mb-4"
|
||||
placeholder="分类名称"
|
||||
value={form.name}
|
||||
onChangeText={text => setForm(prevForm => ({ ...prevForm, name: text }))}
|
||||
/>
|
||||
<LegendList
|
||||
ref={listRef}
|
||||
data={moneyCategoryStore.IconGroups}
|
||||
extraData={form.icon}
|
||||
keyExtractor={item => String(item.index)}
|
||||
recycleItems
|
||||
initialContainerPoolRatio={20}
|
||||
style={{ flex: 1 }}
|
||||
initialScrollIndex={moneyCategoryStore.findIconGroupsRow(category?.icon || '')}
|
||||
renderItem={({ item }) => (
|
||||
<View className="mb-1" key={item.index}>
|
||||
{
|
||||
item.type === 'title'
|
||||
? (
|
||||
<Text className="text-center text-sm mb-3">{item.value}</Text>
|
||||
)
|
||||
: (
|
||||
<View className="flex flex-row flex-wrap">
|
||||
{item.value.map((icon) => {
|
||||
const selected = form.icon === icon
|
||||
|
||||
return (
|
||||
<Pressable
|
||||
key={icon}
|
||||
className="w-1/5 mb-3 flex items-center"
|
||||
onPress={() => {
|
||||
setForm(prevForm => ({
|
||||
...prevForm,
|
||||
icon,
|
||||
}))
|
||||
}}
|
||||
>
|
||||
<View
|
||||
style={{
|
||||
width: 46,
|
||||
height: 46,
|
||||
borderRadius: 28,
|
||||
justifyContent: 'center',
|
||||
alignItems: 'center',
|
||||
backgroundColor: selected ? '#333' : '#F3F4F6',
|
||||
}}
|
||||
>
|
||||
<MoneyCategoryIcon
|
||||
name={icon}
|
||||
size={32}
|
||||
color={selected ? '#fff' : '#000'}
|
||||
/>
|
||||
</View>
|
||||
</Pressable>
|
||||
)
|
||||
})}
|
||||
</View>
|
||||
)
|
||||
}
|
||||
</View>
|
||||
)}
|
||||
/>
|
||||
</View>
|
||||
|
||||
</ADrawer>
|
||||
)
|
||||
}
|
||||
Reference in new issue
Block a user