mirror of
https://github.com/ikun0014/lx-music-mobile.git
synced 2025-05-23 22:37:41 +08:00
修复导入歌单时可能会导致歌单数据存储异常的问题(#500)
This commit is contained in:
parent
0d996e2bf3
commit
8210da380a
@ -5,6 +5,7 @@
|
||||
### 修复
|
||||
|
||||
- 修复重复的数据初始化调用
|
||||
- 修复导入歌单时可能会导致歌单数据存储异常的问题(#500)
|
||||
|
||||
### 变更
|
||||
|
||||
|
@ -2,7 +2,9 @@ import AsyncStorage from '@react-native-async-storage/async-storage'
|
||||
import { log } from '@/utils/log'
|
||||
|
||||
const partKeyPrefix = '@___PART___'
|
||||
const partKeyArrPrefix = '@___PART_A___'
|
||||
const partKeyPrefixRxp = /^@___PART___/
|
||||
const partKeyArrPrefixRxp = /^@___PART_A___/
|
||||
const keySplit = ','
|
||||
const limit = 500000
|
||||
|
||||
@ -15,16 +17,25 @@ const buildData = (key: string, value: any, datas: Array<[string, string]>) => {
|
||||
|
||||
const partKeys = []
|
||||
for (let i = 0, len = Math.floor(valueStr.length / limit); i <= len; i++) {
|
||||
let partKey = `${partKeyPrefix}${key}${i}`
|
||||
let partKey = `${partKeyArrPrefix}${key}${i}`
|
||||
partKeys.push(partKey)
|
||||
datas.push([partKey, valueStr.substring(i * limit, (i + 1) * limit)])
|
||||
}
|
||||
datas.push([key, `${partKeyPrefix}${partKeys.join(keySplit)}`])
|
||||
datas.push([key, partKeyArrPrefix + JSON.stringify(partKeys)])
|
||||
}
|
||||
|
||||
const handleGetDataOld = async<T>(partKeys: string): Promise<T> => {
|
||||
const keys = partKeys.replace(partKeyPrefixRxp, '').split(keySplit)
|
||||
|
||||
return AsyncStorage.multiGet(keys).then(datas => {
|
||||
return JSON.parse(datas.map(data => data[1]).join(''))
|
||||
})
|
||||
}
|
||||
|
||||
const handleGetData = async<T>(partKeys: string): Promise<T> => {
|
||||
const keys = partKeys.replace(partKeyPrefixRxp, '').split(keySplit)
|
||||
if (partKeys.startsWith(partKeyPrefix)) return handleGetDataOld<T>(partKeys)
|
||||
|
||||
const keys = JSON.parse(partKeys.replace(partKeyArrPrefixRxp, '')) as string[]
|
||||
return AsyncStorage.multiGet(keys).then(datas => {
|
||||
return JSON.parse(datas.map(data => data[1]).join(''))
|
||||
})
|
||||
@ -35,6 +46,7 @@ export const saveData = async(key: string, value: any) => {
|
||||
buildData(key, value, datas)
|
||||
|
||||
try {
|
||||
await removeData(key)
|
||||
await AsyncStorage.multiSet(datas)
|
||||
} catch (e: any) {
|
||||
// saving error
|
||||
@ -52,7 +64,7 @@ export const getData = async<T = unknown>(key: string): Promise<T | null> => {
|
||||
log.error('storage error[getData]:', key, e.message)
|
||||
throw e
|
||||
}
|
||||
if (value && partKeyPrefixRxp.test(value)) {
|
||||
if (value && (partKeyPrefixRxp.test(value) || partKeyArrPrefixRxp.test(value))) {
|
||||
return handleGetData<T>(value)
|
||||
} else if (value == null) return value
|
||||
return JSON.parse(value)
|
||||
@ -67,7 +79,8 @@ export const removeData = async(key: string) => {
|
||||
log.error('storage error[removeData]:', key, e.message)
|
||||
throw e
|
||||
}
|
||||
if (value && partKeyPrefixRxp.test(value)) {
|
||||
if (value) {
|
||||
if (partKeyPrefixRxp.test(value)) {
|
||||
let partKeys = value.replace(partKeyPrefixRxp, '').split(keySplit)
|
||||
partKeys.push(key)
|
||||
try {
|
||||
@ -77,7 +90,21 @@ export const removeData = async(key: string) => {
|
||||
log.error('storage error[removeData]:', key, e.message)
|
||||
throw e
|
||||
}
|
||||
} else {
|
||||
return
|
||||
} else if (partKeyArrPrefixRxp.test(value)) {
|
||||
let partKeys = JSON.parse(value.replace(partKeyArrPrefixRxp, '')) as string[]
|
||||
partKeys.push(key)
|
||||
try {
|
||||
await AsyncStorage.multiRemove(partKeys)
|
||||
} catch (e: any) {
|
||||
// remove error
|
||||
log.error('storage error[removeData]:', key, e.message)
|
||||
throw e
|
||||
}
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
await AsyncStorage.removeItem(key)
|
||||
} catch (e: any) {
|
||||
@ -85,7 +112,6 @@ export const removeData = async(key: string) => {
|
||||
log.error('storage error[removeData]:', key, e.message)
|
||||
throw e
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export const getAllKeys = async() => {
|
||||
@ -114,7 +140,7 @@ export const getDataMultiple = async<T extends readonly string[]>(keys: T) => {
|
||||
}
|
||||
const promises: Array<Promise<ReadonlyArray<[unknown | null]>>> = []
|
||||
for (const [, value] of datas) {
|
||||
if (value && partKeyPrefixRxp.test(value)) {
|
||||
if (value && (partKeyPrefixRxp.test(value) || partKeyArrPrefixRxp.test(value))) {
|
||||
promises.push(handleGetData(value))
|
||||
} else {
|
||||
// eslint-disable-next-line @typescript-eslint/no-unsafe-argument
|
||||
@ -132,6 +158,7 @@ export const saveDataMultiple = async(datas: Array<[string, any]>) => {
|
||||
buildData(key, value, allData)
|
||||
}
|
||||
try {
|
||||
await removeDataMultiple(datas.map(k => k[0]))
|
||||
await AsyncStorage.multiSet(allData)
|
||||
} catch (e: any) {
|
||||
// save error
|
||||
@ -147,8 +174,12 @@ export const removeDataMultiple = async(keys: string[]) => {
|
||||
let allKeys = []
|
||||
for (const [key, value] of datas) {
|
||||
allKeys.push(key)
|
||||
if (value && partKeyPrefixRxp.test(value)) {
|
||||
if (value) {
|
||||
if (partKeyPrefixRxp.test(value)) {
|
||||
allKeys.push(...value.replace(partKeyPrefixRxp, '').split(keySplit))
|
||||
} else if (partKeyArrPrefixRxp.test(value)) {
|
||||
allKeys.push(...JSON.parse(value.replace(partKeyPrefixRxp, '')) as string[])
|
||||
}
|
||||
}
|
||||
}
|
||||
try {
|
||||
|
@ -48,7 +48,8 @@ export const handleImport = (path: string, position: number) => {
|
||||
void readListData(path).then(async listData => {
|
||||
if (listData == null) return
|
||||
void handleImportListPart(listData, position)
|
||||
}).catch(() => {
|
||||
}).catch((err) => {
|
||||
log.error(err)
|
||||
toast(global.i18n.t('setting_backup_part_import_list_tip_error'))
|
||||
})
|
||||
}
|
||||
|
@ -103,7 +103,8 @@ export const handleImportListPart = async(listData: LX.ConfigFile.MyListInfoPart
|
||||
position: Math.max(position, -1),
|
||||
}).then(() => {
|
||||
toast(global.i18n.t('setting_backup_part_import_list_tip_success'))
|
||||
}).catch(() => {
|
||||
}).catch((err) => {
|
||||
log.error(err)
|
||||
toast(global.i18n.t('setting_backup_part_import_list_tip_error'))
|
||||
})
|
||||
}
|
||||
@ -160,7 +161,8 @@ export const handleImportList = (path: string) => {
|
||||
void importPlayList(path).then((skipTip) => {
|
||||
if (skipTip) return
|
||||
toast(global.i18n.t('setting_backup_part_import_list_tip_success'))
|
||||
}).catch(() => {
|
||||
}).catch((err) => {
|
||||
log.error(err)
|
||||
toast(global.i18n.t('setting_backup_part_import_list_tip_error'))
|
||||
})
|
||||
}
|
||||
|
@ -37,7 +37,7 @@ export const clearLogs = async() => {
|
||||
export const log = {
|
||||
info(...msgs: any[]) {
|
||||
// console.info(...msgs)
|
||||
const msg = msgs.map(m => typeof m == 'string' ? m : JSON.stringify(m)).join(' ')
|
||||
const msg = msgs.map(m => typeof m == 'string' ? m : m instanceof Error ? m.stack ?? m.message : JSON.stringify(m)).join(' ')
|
||||
if (msg.startsWith('%c')) return
|
||||
const time = new Date().toLocaleString()
|
||||
if (logTools.tempLog) {
|
||||
@ -46,15 +46,14 @@ export const log = {
|
||||
},
|
||||
warn(...msgs: any[]) {
|
||||
// console.warn(...msgs)
|
||||
const msg = msgs.map(m => typeof m == 'string' ? m : JSON.stringify(m)).join(' ')
|
||||
const msg = msgs.map(m => typeof m == 'string' ? m : m instanceof Error ? m.stack ?? m.message : JSON.stringify(m)).join(' ')
|
||||
const time = new Date().toLocaleString()
|
||||
if (logTools.tempLog) {
|
||||
logTools.tempLog.push({ type: 'WARN', time, text: msg })
|
||||
} else logTools.writeLog(`${time} WARN ${msg}`)
|
||||
},
|
||||
error(...msgs: any[]) {
|
||||
// console.error...(msgs)
|
||||
const msg = msgs.map(m => typeof m == 'string' ? m : JSON.stringify(m)).join(' ')
|
||||
const msg = msgs.map(m => typeof m == 'string' ? m : m instanceof Error ? m.stack ?? m.message : JSON.stringify(m)).join(' ')
|
||||
const time = new Date().toLocaleString()
|
||||
if (logTools.tempLog) {
|
||||
logTools.tempLog.push({ type: 'ERROR', time, text: msg })
|
||||
|
Loading…
x
Reference in New Issue
Block a user