mirror of
https://github.com/ikun0014/lx-music-mobile.git
synced 2025-07-03 14:52:09 +08:00
添加同步历史列表
This commit is contained in:
parent
59cc117143
commit
90a0f548c2
@ -254,6 +254,7 @@
|
||||
"setting_sync_enbale": "Enable sync",
|
||||
"setting_sync_history": "History address",
|
||||
"setting_sync_history_empty": "Nothing here",
|
||||
"setting_sync_history_title": "Connection history",
|
||||
"setting_sync_host_label": "Synchronization service IP address",
|
||||
"setting_sync_host_tip": "Please enter the synchronization service IP address",
|
||||
"setting_sync_port_label": "Synchronization service port number",
|
||||
|
@ -1,4 +1,4 @@
|
||||
import ChoosePath, { ChoosePathType } from '@/components/common/ChoosePath'
|
||||
import ChoosePath, { type ChoosePathType } from '@/components/common/ChoosePath'
|
||||
import { LXM_FILE_EXT_RXP } from '@/config/constant'
|
||||
import React, { forwardRef, useImperativeHandle, useRef, useState } from 'react'
|
||||
import { InteractionManager } from 'react-native'
|
||||
|
@ -1,97 +1,142 @@
|
||||
import React, { memo, useRef, useState, useEffect, useCallback } from 'react'
|
||||
import React, { memo, useRef, useState, useCallback, useImperativeHandle, forwardRef } from 'react'
|
||||
import { View, TouchableOpacity, ScrollView } from 'react-native'
|
||||
// import { gzip, ungzip } from 'pako'
|
||||
import { Icon } from '@/components/common/Icon'
|
||||
|
||||
import Button from '../components/Button'
|
||||
import { useTranslation } from '@/plugins/i18n'
|
||||
import { createStyle, getSyncHostHistory, removeSyncHostHistory, setSyncHost } from '@/utils/tools'
|
||||
import Popup from '@/components/common/Popup'
|
||||
import { getSyncHostHistory, removeSyncHostHistory, setSyncHost } from '@/utils/data'
|
||||
import Popup, { type PopupType } from '@/components/common/Popup'
|
||||
import { BorderWidths } from '@/theme'
|
||||
import Text from '@/components/common/Text'
|
||||
import { useTheme } from '@/store/theme/hook'
|
||||
import { useI18n } from '@/lang'
|
||||
import { useSettingValue } from '@/store/setting/hook'
|
||||
import { createStyle } from '@/utils/tools'
|
||||
|
||||
const HistoryListItem = ({ item, index, remove, setHostInfo }) => {
|
||||
const theme = useGetter('common', 'theme')
|
||||
type SyncHistoryItem = Awaited<ReturnType<typeof getSyncHostHistory>>[number]
|
||||
|
||||
const HistoryListItem = ({ item, index, onRemove, onSelect }: {
|
||||
item: SyncHistoryItem
|
||||
index: number
|
||||
onRemove: (index: number) => void
|
||||
onSelect: (index: number) => void
|
||||
}) => {
|
||||
const theme = useTheme()
|
||||
const handleSetHost = () => {
|
||||
setHostInfo({
|
||||
host: item.host,
|
||||
port: item.port,
|
||||
})
|
||||
setSyncHost({
|
||||
host: item.host,
|
||||
port: item.port,
|
||||
})
|
||||
onSelect(index)
|
||||
// setHostInfo({
|
||||
// host: item.host,
|
||||
// port: item.port,
|
||||
// })
|
||||
// setSyncHost({
|
||||
// host: item.host,
|
||||
// port: item.port,
|
||||
// })
|
||||
}
|
||||
const handleRemove = () => {
|
||||
remove(index)
|
||||
onRemove(index)
|
||||
}
|
||||
|
||||
return (
|
||||
<View style={{ ...styles.listItem, borderBottomColor: theme.borderColor }}>
|
||||
<View style={{ ...styles.listItem, borderBottomColor: theme['c-border-background'] }}>
|
||||
<TouchableOpacity style={styles.listName} onPress={handleSetHost}>
|
||||
<Text numberOfLines={1}>{item.host}</Text>
|
||||
<Text color={theme['c-font-label']} numberOfLines={1}>{item.port}</Text>
|
||||
</TouchableOpacity>
|
||||
<TouchableOpacity onPress={handleRemove} style={styles.listMoreBtn}>
|
||||
<Icon name="remove" style={{ color: theme.normal35 }} size={16} />
|
||||
<TouchableOpacity onPress={handleRemove} style={styles.listBtn}>
|
||||
<Icon name="remove" color={theme['c-font-label']} size={12} />
|
||||
</TouchableOpacity>
|
||||
</View>
|
||||
)
|
||||
}
|
||||
const HistoryList = ({ visible, setHostInfo }) => {
|
||||
const [list, setList] = useState([])
|
||||
const isUnmountedRef = useRef(true)
|
||||
const theme = useGetter('common', 'theme')
|
||||
const { t } = useTranslation()
|
||||
|
||||
const getHistory = () => {
|
||||
getSyncHostHistory().then(historyList => {
|
||||
if (isUnmountedRef.current) return
|
||||
setList([...historyList])
|
||||
interface HistoryListProps {
|
||||
onSelect: (item: SyncHistoryItem) => void
|
||||
}
|
||||
interface HistoryListType {
|
||||
show: () => void
|
||||
}
|
||||
const HistoryList = forwardRef<HistoryListType, HistoryListProps>(({ onSelect }, ref) => {
|
||||
const popupRef = useRef<PopupType>(null)
|
||||
const [visible, setVisible] = useState(false)
|
||||
const [list, setList] = useState<SyncHistoryItem[]>([])
|
||||
// const isUnmountedRef = useRef(true)
|
||||
const theme = useTheme()
|
||||
const t = useI18n()
|
||||
|
||||
const handleShow = () => {
|
||||
popupRef.current?.setVisible(true)
|
||||
requestAnimationFrame(() => {
|
||||
void getSyncHostHistory().then(historyList => {
|
||||
setList([...historyList])
|
||||
})
|
||||
})
|
||||
}
|
||||
useImperativeHandle(ref, () => ({
|
||||
show() {
|
||||
if (visible) handleShow()
|
||||
else {
|
||||
setVisible(true)
|
||||
requestAnimationFrame(() => {
|
||||
handleShow()
|
||||
})
|
||||
}
|
||||
},
|
||||
}))
|
||||
|
||||
useEffect(() => {
|
||||
if (!visible) return
|
||||
getHistory()
|
||||
}, [visible])
|
||||
const handleSelect = useCallback((index: number) => {
|
||||
popupRef.current?.setVisible(false)
|
||||
onSelect(list[index])
|
||||
}, [list, onSelect])
|
||||
|
||||
useEffect(() => {
|
||||
isUnmountedRef.current = false
|
||||
return () => {
|
||||
isUnmountedRef.current = true
|
||||
}
|
||||
}, [])
|
||||
|
||||
const handleRemove = useCallback((index) => {
|
||||
removeSyncHostHistory(index)
|
||||
const handleRemove = useCallback((index: number) => {
|
||||
void removeSyncHostHistory(index)
|
||||
const newList = [...list]
|
||||
newList.splice(index, 1)
|
||||
setList(newList)
|
||||
}, [list])
|
||||
|
||||
return (
|
||||
<ScrollView style={styles.list}>
|
||||
{
|
||||
list.length
|
||||
? list.map((item, index) => <HistoryListItem item={item} index={index} remove={handleRemove} key={`${item.host}:${item.port}`} setHostInfo={setHostInfo} />)
|
||||
: <Text style={styles.tipText} color={theme['c-font-label']}>{t('setting_sync_history_empty')}</Text>
|
||||
}
|
||||
</ScrollView>
|
||||
)
|
||||
}
|
||||
|
||||
export default memo(({ setHostInfo, isWaiting }) => {
|
||||
const { t } = useTranslation()
|
||||
const [visible, setVisible] = useState(false)
|
||||
const isEnableSync = useGetter('common', 'isEnableSync')
|
||||
return (
|
||||
visible
|
||||
? (
|
||||
<Popup ref={popupRef} title={t('setting_sync_history_title')}>
|
||||
<ScrollView style={styles.list}>
|
||||
{
|
||||
list.length
|
||||
? list.map((item, index) => (
|
||||
<HistoryListItem
|
||||
item={item}
|
||||
index={index}
|
||||
onRemove={handleRemove}
|
||||
key={`${item.host}:${item.port}`}
|
||||
onSelect={handleSelect}
|
||||
/>
|
||||
))
|
||||
: <Text style={styles.tipText} color={theme['c-font-label']}>{t('setting_sync_history_empty')}</Text>
|
||||
}
|
||||
</ScrollView>
|
||||
</Popup>
|
||||
)
|
||||
: null
|
||||
)
|
||||
})
|
||||
|
||||
export default memo(({ setHostInfo, isWaiting }: {
|
||||
setHostInfo: (hostInfo: { host: string, port: string }) => void
|
||||
isWaiting: boolean
|
||||
}) => {
|
||||
const t = useI18n()
|
||||
const isEnableSync = useSettingValue('sync.enable')
|
||||
const listRef = useRef<HistoryListType>(null)
|
||||
|
||||
const showPopup = () => {
|
||||
setVisible(true)
|
||||
listRef.current?.show()
|
||||
}
|
||||
|
||||
const hidePopup = () => {
|
||||
setVisible(false)
|
||||
const handleSelect = (item: SyncHistoryItem) => {
|
||||
setHostInfo(item)
|
||||
void setSyncHost(item)
|
||||
}
|
||||
|
||||
return (
|
||||
@ -99,21 +144,12 @@ export default memo(({ setHostInfo, isWaiting }) => {
|
||||
<View style={styles.btn}>
|
||||
<Button disabled={isWaiting || isEnableSync} onPress={showPopup}>{t('setting_sync_history')}</Button>
|
||||
</View>
|
||||
<Popup
|
||||
visible={visible}
|
||||
hide={hidePopup}
|
||||
title={t('setting_sync_history_title')}
|
||||
>
|
||||
<HistoryList visible={visible} setHostInfo={setHostInfo} />
|
||||
</Popup>
|
||||
<HistoryList ref={listRef} onSelect={handleSelect} />
|
||||
</>
|
||||
)
|
||||
})
|
||||
|
||||
const styles = createStyle({
|
||||
cacheSize: {
|
||||
marginBottom: 5,
|
||||
},
|
||||
btn: {
|
||||
flexDirection: 'row',
|
||||
marginLeft: 25,
|
||||
@ -126,17 +162,20 @@ const styles = createStyle({
|
||||
list: {
|
||||
flexShrink: 1,
|
||||
flexGrow: 0,
|
||||
paddingLeft: 10,
|
||||
paddingRight: 10,
|
||||
paddingLeft: 15,
|
||||
paddingRight: 15,
|
||||
},
|
||||
listItem: {
|
||||
flexDirection: 'row',
|
||||
alignItems: 'center',
|
||||
paddingTop: 5,
|
||||
paddingBottom: 5,
|
||||
paddingTop: 8,
|
||||
paddingBottom: 8,
|
||||
borderBottomWidth: BorderWidths.normal,
|
||||
},
|
||||
listName: {
|
||||
flex: 1,
|
||||
},
|
||||
listBtn: {
|
||||
padding: 5,
|
||||
},
|
||||
})
|
||||
|
@ -2,7 +2,7 @@ import React, { memo, useState } from 'react'
|
||||
|
||||
import Section from '../components/Section'
|
||||
import IsEnable from './IsEnable'
|
||||
// import History from './History'
|
||||
import History from './History'
|
||||
import { useI18n } from '@/lang'
|
||||
// import SyncHost from './SyncHost'
|
||||
|
||||
@ -15,7 +15,7 @@ export default memo(() => {
|
||||
return (
|
||||
<Section title={t('setting_sync')}>
|
||||
<IsEnable hostInfo={hostInfo} setHostInfo={setHostInfo} isWaiting={isWaiting} setIsWaiting={setIsWaiting} />
|
||||
{/* <History setHostInfo={setHostInfo} isWaiting={isWaiting} /> */}
|
||||
<History setHostInfo={setHostInfo} isWaiting={isWaiting} />
|
||||
</Section>
|
||||
)
|
||||
})
|
||||
|
2
src/types/sync.d.ts
vendored
2
src/types/sync.d.ts
vendored
@ -1,4 +1,4 @@
|
||||
import { io } from 'socket.io-client'
|
||||
import { type io } from 'socket.io-client'
|
||||
|
||||
declare global {
|
||||
namespace LX {
|
||||
|
Loading…
x
Reference in New Issue
Block a user