mirror of
https://github.com/ikun0014/lx-music-mobile.git
synced 2025-05-23 22:37:41 +08:00
完善同步
This commit is contained in:
parent
7c8a706ad3
commit
2169c9eb3b
18
package-lock.json
generated
18
package-lock.json
generated
@ -1,17 +1,17 @@
|
|||||||
{
|
{
|
||||||
"name": "lx-music-mobile",
|
"name": "lx-music-mobile",
|
||||||
"version": "1.0.0-beta.4",
|
"version": "1.0.0-beta.5",
|
||||||
"lockfileVersion": 2,
|
"lockfileVersion": 2,
|
||||||
"requires": true,
|
"requires": true,
|
||||||
"packages": {
|
"packages": {
|
||||||
"": {
|
"": {
|
||||||
"name": "lx-music-mobile",
|
"name": "lx-music-mobile",
|
||||||
"version": "1.0.0-beta.4",
|
"version": "1.0.0-beta.5",
|
||||||
"license": "Apache-2.0",
|
"license": "Apache-2.0",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@craftzdog/react-native-buffer": "^6.0.5",
|
"@craftzdog/react-native-buffer": "^6.0.5",
|
||||||
"@react-native-async-storage/async-storage": "^1.17.11",
|
"@react-native-async-storage/async-storage": "^1.17.11",
|
||||||
"@react-native-clipboard/clipboard": "^1.11.1",
|
"@react-native-clipboard/clipboard": "^1.11.2",
|
||||||
"@react-native-community/checkbox": "^0.5.14",
|
"@react-native-community/checkbox": "^0.5.14",
|
||||||
"@react-native-community/slider": "^4.4.2",
|
"@react-native-community/slider": "^4.4.2",
|
||||||
"iconv-lite": "^0.6.3",
|
"iconv-lite": "^0.6.3",
|
||||||
@ -2123,9 +2123,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@react-native-clipboard/clipboard": {
|
"node_modules/@react-native-clipboard/clipboard": {
|
||||||
"version": "1.11.1",
|
"version": "1.11.2",
|
||||||
"resolved": "https://registry.npmjs.org/@react-native-clipboard/clipboard/-/clipboard-1.11.1.tgz",
|
"resolved": "https://registry.npmjs.org/@react-native-clipboard/clipboard/-/clipboard-1.11.2.tgz",
|
||||||
"integrity": "sha512-nvSIIHzybVWqYxcJE5hpT17ekxAAg383Ggzw5WrYHtkKX61N1AwaKSNmXs5xHV7pmKSOe/yWjtSwxIzfW51I5Q==",
|
"integrity": "sha512-bHyZVW62TuleiZsXNHS1Pv16fWc0fh8O9WvBzl4h2fykqZRW9a+Pv/RGTH56E3X2PqzHP38K5go8zmCZUoIsoQ==",
|
||||||
"peerDependencies": {
|
"peerDependencies": {
|
||||||
"react": ">=16.0",
|
"react": ">=16.0",
|
||||||
"react-native": ">=0.57.0"
|
"react-native": ">=0.57.0"
|
||||||
@ -13269,9 +13269,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"@react-native-clipboard/clipboard": {
|
"@react-native-clipboard/clipboard": {
|
||||||
"version": "1.11.1",
|
"version": "1.11.2",
|
||||||
"resolved": "https://registry.npmjs.org/@react-native-clipboard/clipboard/-/clipboard-1.11.1.tgz",
|
"resolved": "https://registry.npmjs.org/@react-native-clipboard/clipboard/-/clipboard-1.11.2.tgz",
|
||||||
"integrity": "sha512-nvSIIHzybVWqYxcJE5hpT17ekxAAg383Ggzw5WrYHtkKX61N1AwaKSNmXs5xHV7pmKSOe/yWjtSwxIzfW51I5Q==",
|
"integrity": "sha512-bHyZVW62TuleiZsXNHS1Pv16fWc0fh8O9WvBzl4h2fykqZRW9a+Pv/RGTH56E3X2PqzHP38K5go8zmCZUoIsoQ==",
|
||||||
"requires": {}
|
"requires": {}
|
||||||
},
|
},
|
||||||
"@react-native-community/checkbox": {
|
"@react-native-community/checkbox": {
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "lx-music-mobile",
|
"name": "lx-music-mobile",
|
||||||
"version": "1.0.0-beta.4",
|
"version": "1.0.0-beta.5",
|
||||||
"versionCode": 53,
|
"versionCode": 53,
|
||||||
"private": true,
|
"private": true,
|
||||||
"scripts": {
|
"scripts": {
|
||||||
@ -44,7 +44,7 @@
|
|||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@craftzdog/react-native-buffer": "^6.0.5",
|
"@craftzdog/react-native-buffer": "^6.0.5",
|
||||||
"@react-native-async-storage/async-storage": "^1.17.11",
|
"@react-native-async-storage/async-storage": "^1.17.11",
|
||||||
"@react-native-clipboard/clipboard": "^1.11.1",
|
"@react-native-clipboard/clipboard": "^1.11.2",
|
||||||
"@react-native-community/checkbox": "^0.5.14",
|
"@react-native-community/checkbox": "^0.5.14",
|
||||||
"@react-native-community/slider": "^4.4.2",
|
"@react-native-community/slider": "^4.4.2",
|
||||||
"iconv-lite": "^0.6.3",
|
"iconv-lite": "^0.6.3",
|
||||||
|
@ -42,8 +42,6 @@ global.lx = {
|
|||||||
// prevListPlayIndex: -1,
|
// prevListPlayIndex: -1,
|
||||||
|
|
||||||
// syncKeyInfo: {},
|
// syncKeyInfo: {},
|
||||||
isSyncEnableing: false,
|
|
||||||
|
|
||||||
|
|
||||||
isEnableSyncLog: false,
|
isEnableSyncLog: false,
|
||||||
|
|
||||||
|
@ -33,6 +33,7 @@ const handleConnection = (socket: LX.Sync.Socket) => {
|
|||||||
|
|
||||||
const heartbeatTools = {
|
const heartbeatTools = {
|
||||||
failedNum: 0,
|
failedNum: 0,
|
||||||
|
maxTryNum: 3,
|
||||||
pingTimeout: null as NodeJS.Timeout | null,
|
pingTimeout: null as NodeJS.Timeout | null,
|
||||||
delayRetryTimeout: null as NodeJS.Timeout | null,
|
delayRetryTimeout: null as NodeJS.Timeout | null,
|
||||||
handleOpen() {
|
handleOpen() {
|
||||||
@ -59,16 +60,21 @@ const heartbeatTools = {
|
|||||||
// client = null
|
// client = null
|
||||||
if (!client) return
|
if (!client) return
|
||||||
|
|
||||||
if (this.failedNum > 3) throw new Error('connect error')
|
if (++this.failedNum > this.maxTryNum) {
|
||||||
|
this.failedNum = 0
|
||||||
|
throw new Error('connect error')
|
||||||
|
}
|
||||||
|
|
||||||
this.delayRetryTimeout = setTimeout(() => {
|
this.delayRetryTimeout = setTimeout(() => {
|
||||||
this.delayRetryTimeout = null
|
this.delayRetryTimeout = null
|
||||||
if (!client) return
|
if (!client) return
|
||||||
console.log(dateFormat(new Date()), 'reconnnect...')
|
console.log(dateFormat(new Date()), 'reconnnect...')
|
||||||
|
sendSyncStatus({
|
||||||
|
status: false,
|
||||||
|
message: `Try reconnnect... (${this.failedNum}/${this.maxTryNum})`,
|
||||||
|
})
|
||||||
connect(client.data.urlInfo, client.data.keyInfo)
|
connect(client.data.urlInfo, client.data.keyInfo)
|
||||||
}, 2000)
|
}, 2000)
|
||||||
|
|
||||||
this.failedNum++
|
|
||||||
},
|
},
|
||||||
clearTimeout() {
|
clearTimeout() {
|
||||||
if (this.delayRetryTimeout) {
|
if (this.delayRetryTimeout) {
|
||||||
@ -186,15 +192,25 @@ export const connect = (urlInfo: LX.Sync.UrlInfo, keyInfo: LX.Sync.KeyInfo) => {
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
client.addEventListener('close', () => {
|
client.addEventListener('close', ({ code }) => {
|
||||||
sendSyncStatus({
|
|
||||||
status: false,
|
|
||||||
message: '',
|
|
||||||
})
|
|
||||||
const err = new Error('closed')
|
const err = new Error('closed')
|
||||||
for (const handler of closeEvents) void handler(err)
|
for (const handler of closeEvents) void handler(err)
|
||||||
closeEvents = []
|
closeEvents = []
|
||||||
events = {}
|
events = {}
|
||||||
|
switch (code) {
|
||||||
|
case SYNC_CLOSE_CODE.normal:
|
||||||
|
// case SYNC_CLOSE_CODE.failed:
|
||||||
|
sendSyncStatus({
|
||||||
|
status: false,
|
||||||
|
message: '',
|
||||||
|
})
|
||||||
|
}
|
||||||
|
})
|
||||||
|
client.addEventListener('error', ({ message }) => {
|
||||||
|
sendSyncStatus({
|
||||||
|
status: false,
|
||||||
|
message,
|
||||||
|
})
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -204,6 +220,7 @@ export const disconnect = async() => {
|
|||||||
client.close(SYNC_CLOSE_CODE.normal)
|
client.close(SYNC_CLOSE_CODE.normal)
|
||||||
client = null
|
client = null
|
||||||
heartbeatTools.clearTimeout()
|
heartbeatTools.clearTimeout()
|
||||||
|
heartbeatTools.failedNum = 0
|
||||||
}
|
}
|
||||||
|
|
||||||
export const getStatus = (): LX.Sync.Status => status
|
export const getStatus = (): LX.Sync.Status => status
|
||||||
|
@ -5,13 +5,18 @@ import { SYNC_CODE } from '@/config/constant'
|
|||||||
import log from '../log'
|
import log from '../log'
|
||||||
import { parseUrl } from './utils'
|
import { parseUrl } from './utils'
|
||||||
|
|
||||||
|
let connectId = 0
|
||||||
|
|
||||||
const handleConnect = async(host: string, authCode?: string) => {
|
const handleConnect = async(host: string, authCode?: string) => {
|
||||||
// const hostInfo = await getSyncHost()
|
// const hostInfo = await getSyncHost()
|
||||||
// console.log(hostInfo)
|
// console.log(hostInfo)
|
||||||
// if (!hostInfo || !hostInfo.host || !hostInfo.port) throw new Error(SYNC_CODE.unknownServiceAddress)
|
// if (!hostInfo || !hostInfo.host || !hostInfo.port) throw new Error(SYNC_CODE.unknownServiceAddress)
|
||||||
|
const id = connectId
|
||||||
const urlInfo = parseUrl(host)
|
const urlInfo = parseUrl(host)
|
||||||
await disconnectServer(false)
|
await disconnectServer(false)
|
||||||
|
if (id != connectId) return
|
||||||
const keyInfo = await handleAuth(urlInfo, authCode)
|
const keyInfo = await handleAuth(urlInfo, authCode)
|
||||||
|
if (id != connectId) return
|
||||||
socketConnect(urlInfo, keyInfo)
|
socketConnect(urlInfo, keyInfo)
|
||||||
}
|
}
|
||||||
const handleDisconnect = async() => {
|
const handleDisconnect = async() => {
|
||||||
@ -23,7 +28,9 @@ const connectServer = async(host: string, authCode?: string) => {
|
|||||||
status: false,
|
status: false,
|
||||||
message: SYNC_CODE.connecting,
|
message: SYNC_CODE.connecting,
|
||||||
})
|
})
|
||||||
|
const id = connectId
|
||||||
return handleConnect(host, authCode).catch(async err => {
|
return handleConnect(host, authCode).catch(async err => {
|
||||||
|
if (id != connectId) return
|
||||||
sendSyncStatus({
|
sendSyncStatus({
|
||||||
status: false,
|
status: false,
|
||||||
message: err.message,
|
message: err.message,
|
||||||
@ -44,6 +51,7 @@ const connectServer = async(host: string, authCode?: string) => {
|
|||||||
const disconnectServer = async(isResetStatus = true) => handleDisconnect().then(() => {
|
const disconnectServer = async(isResetStatus = true) => handleDisconnect().then(() => {
|
||||||
log.info('disconnect...')
|
log.info('disconnect...')
|
||||||
if (isResetStatus) {
|
if (isResetStatus) {
|
||||||
|
connectId++
|
||||||
sendSyncStatus({
|
sendSyncStatus({
|
||||||
status: false,
|
status: false,
|
||||||
message: '',
|
message: '',
|
||||||
|
@ -121,9 +121,8 @@ const HistoryList = forwardRef<HistoryListType, HistoryListProps>(({ onSelect },
|
|||||||
)
|
)
|
||||||
})
|
})
|
||||||
|
|
||||||
export default memo(({ setHost, isWaiting }: {
|
export default memo(({ setHost }: {
|
||||||
setHost: (host: string) => void
|
setHost: (host: string) => void
|
||||||
isWaiting: boolean
|
|
||||||
}) => {
|
}) => {
|
||||||
const t = useI18n()
|
const t = useI18n()
|
||||||
const isEnableSync = useSettingValue('sync.enable')
|
const isEnableSync = useSettingValue('sync.enable')
|
||||||
@ -141,7 +140,7 @@ export default memo(({ setHost, isWaiting }: {
|
|||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<View style={styles.btn}>
|
<View style={styles.btn}>
|
||||||
<Button disabled={isWaiting || isEnableSync} onPress={showPopup}>{t('setting_sync_history')}</Button>
|
<Button disabled={isEnableSync} onPress={showPopup}>{t('setting_sync_history')}</Button>
|
||||||
</View>
|
</View>
|
||||||
<HistoryList ref={listRef} onSelect={handleSelect} />
|
<HistoryList ref={listRef} onSelect={handleSelect} />
|
||||||
</>
|
</>
|
||||||
|
@ -50,11 +50,9 @@ const HostInput = memo(({ setHost, host, disabled }: {
|
|||||||
})
|
})
|
||||||
|
|
||||||
|
|
||||||
export default memo(({ host, setHost, isWaiting, setIsWaiting }: {
|
export default memo(({ host, setHost }: {
|
||||||
host: string
|
host: string
|
||||||
isWaiting: boolean
|
|
||||||
setHost: (host: string) => void
|
setHost: (host: string) => void
|
||||||
setIsWaiting: (isWaiting: boolean) => void
|
|
||||||
}) => {
|
}) => {
|
||||||
const t = useI18n()
|
const t = useI18n()
|
||||||
const setIsEnableSync = useCallback((enable: boolean) => {
|
const setIsEnableSync = useCallback((enable: boolean) => {
|
||||||
@ -104,13 +102,8 @@ export default memo(({ host, setHost, isWaiting, setIsWaiting }: {
|
|||||||
|
|
||||||
if (enable) void addSyncHostHistory(host)
|
if (enable) void addSyncHostHistory(host)
|
||||||
|
|
||||||
global.lx.isSyncEnableing = true
|
void (enable ? connectServer(host) : disconnectServer())
|
||||||
setIsWaiting(true)
|
}, [host, setIsEnableSync])
|
||||||
;(enable ? connectServer(host) : disconnectServer()).finally(() => {
|
|
||||||
global.lx.isSyncEnableing = false
|
|
||||||
setIsWaiting(false)
|
|
||||||
})
|
|
||||||
}, [host, setIsEnableSync, setIsWaiting])
|
|
||||||
|
|
||||||
|
|
||||||
const handleUpdateHost = useCallback((h: string) => {
|
const handleUpdateHost = useCallback((h: string) => {
|
||||||
@ -155,12 +148,12 @@ export default memo(({ host, setHost, isWaiting, setIsWaiting }: {
|
|||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<View style={styles.infoContent}>
|
<View style={styles.infoContent}>
|
||||||
<CheckBoxItem disabled={isWaiting || !host} check={isEnableSync} label={t('setting_sync_enbale')} onChange={handleSetEnableSync} />
|
<CheckBoxItem disabled={!host} check={isEnableSync} label={t('setting_sync_enbale')} onChange={handleSetEnableSync} />
|
||||||
<Text style={styles.textAddr} size={13}>{t('setting_sync_address', { address })}</Text>
|
<Text style={styles.textAddr} size={13}>{t('setting_sync_address', { address })}</Text>
|
||||||
<Text style={styles.text} size={13}>{t('setting_sync_status', { status })}</Text>
|
<Text style={styles.text} size={13}>{t('setting_sync_status', { status })}</Text>
|
||||||
</View>
|
</View>
|
||||||
<View style={styles.inputContent} >
|
<View style={styles.inputContent} >
|
||||||
<HostInput setHost={handleUpdateHost} host={host} disabled={isWaiting || isEnableSync} />
|
<HostInput setHost={handleUpdateHost} host={host} disabled={isEnableSync} />
|
||||||
</View>
|
</View>
|
||||||
<ConfirmAlert
|
<ConfirmAlert
|
||||||
onCancel={handleCancelSetCode}
|
onCancel={handleCancelSetCode}
|
||||||
|
@ -10,12 +10,11 @@ export default memo(() => {
|
|||||||
const t = useI18n()
|
const t = useI18n()
|
||||||
|
|
||||||
const [host, setHost] = useState('')
|
const [host, setHost] = useState('')
|
||||||
const [isWaiting, setIsWaiting] = useState(global.lx.isSyncEnableing)
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Section title={t('setting_sync')}>
|
<Section title={t('setting_sync')}>
|
||||||
<IsEnable host={host} setHost={setHost} isWaiting={isWaiting} setIsWaiting={setIsWaiting} />
|
<IsEnable host={host} setHost={setHost} />
|
||||||
<History setHost={setHost} isWaiting={isWaiting} />
|
<History setHost={setHost} />
|
||||||
</Section>
|
</Section>
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
|
1
src/types/app.d.ts
vendored
1
src/types/app.d.ts
vendored
@ -28,7 +28,6 @@ interface Lx {
|
|||||||
restorePlayInfo: LX.Player.SavedPlayInfo | null
|
restorePlayInfo: LX.Player.SavedPlayInfo | null
|
||||||
isScreenKeepAwake: boolean
|
isScreenKeepAwake: boolean
|
||||||
isPlayedStop: boolean
|
isPlayedStop: boolean
|
||||||
isSyncEnableing: boolean
|
|
||||||
isEnableSyncLog: boolean
|
isEnableSyncLog: boolean
|
||||||
playerTrackId: string
|
playerTrackId: string
|
||||||
|
|
||||||
|
@ -1179,10 +1179,10 @@
|
|||||||
dependencies:
|
dependencies:
|
||||||
"merge-options" "^3.0.4"
|
"merge-options" "^3.0.4"
|
||||||
|
|
||||||
"@react-native-clipboard/clipboard@^1.11.1":
|
"@react-native-clipboard/clipboard@^1.11.2":
|
||||||
"integrity" "sha512-nvSIIHzybVWqYxcJE5hpT17ekxAAg383Ggzw5WrYHtkKX61N1AwaKSNmXs5xHV7pmKSOe/yWjtSwxIzfW51I5Q=="
|
"integrity" "sha512-bHyZVW62TuleiZsXNHS1Pv16fWc0fh8O9WvBzl4h2fykqZRW9a+Pv/RGTH56E3X2PqzHP38K5go8zmCZUoIsoQ=="
|
||||||
"resolved" "https://registry.npmjs.org/@react-native-clipboard/clipboard/-/clipboard-1.11.1.tgz"
|
"resolved" "https://registry.npmjs.org/@react-native-clipboard/clipboard/-/clipboard-1.11.2.tgz"
|
||||||
"version" "1.11.1"
|
"version" "1.11.2"
|
||||||
|
|
||||||
"@react-native-community/checkbox@^0.5.14":
|
"@react-native-community/checkbox@^0.5.14":
|
||||||
"integrity" "sha512-UmGf3wBpoCXLmVRKIDZyzOG+QR1fOhm0FOw4KzxHTCXpsBvZgIn5wbJ+MWk4io5RohQdY8GSX2MYFmkPJeJpeA=="
|
"integrity" "sha512-UmGf3wBpoCXLmVRKIDZyzOG+QR1fOhm0FOw4KzxHTCXpsBvZgIn5wbJ+MWk4io5RohQdY8GSX2MYFmkPJeJpeA=="
|
||||||
|
Loading…
x
Reference in New Issue
Block a user