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
906e2eb9f8
commit
adb9c7c582
@ -15,6 +15,7 @@ import java.io.InputStream;
|
||||
import java.io.InputStreamReader;
|
||||
import java.lang.reflect.Array;
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.ArrayList;
|
||||
import java.util.concurrent.Callable;
|
||||
|
||||
public class Utils {
|
||||
@ -34,9 +35,10 @@ public class Utils {
|
||||
}
|
||||
|
||||
// https://gist.github.com/PauloLuan/4bcecc086095bce28e22?permalink_comment_id=2591001#gistcomment-2591001
|
||||
public static String getExternalStoragePath(ReactApplicationContext mContext, boolean is_removable) {
|
||||
public static ArrayList<String> getExternalStoragePath(ReactApplicationContext mContext, boolean is_removable) {
|
||||
StorageManager mStorageManager = (StorageManager) mContext.getSystemService(Context.STORAGE_SERVICE);
|
||||
Class<?> storageVolumeClazz;
|
||||
ArrayList<String> paths = new ArrayList<>();
|
||||
try {
|
||||
storageVolumeClazz = Class.forName("android.os.storage.StorageVolume");
|
||||
Method getVolumeList = mStorageManager.getClass().getMethod("getVolumeList");
|
||||
@ -49,13 +51,13 @@ public class Utils {
|
||||
String path = (String) getPath.invoke(storageVolumeElement);
|
||||
boolean removable = (Boolean) isRemovable.invoke(storageVolumeElement);
|
||||
if (is_removable == removable) {
|
||||
return path;
|
||||
paths.add(path);
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return null;
|
||||
return paths;
|
||||
}
|
||||
|
||||
public static String convertStreamToString(InputStream is) throws Exception {
|
||||
|
@ -35,6 +35,7 @@ import com.facebook.react.bridge.WritableMap;
|
||||
import com.facebook.react.bridge.WritableNativeArray;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.Objects;
|
||||
@ -398,7 +399,10 @@ public class UtilsModule extends ReactContextBaseJavaModule {
|
||||
|
||||
@ReactMethod
|
||||
public void getExternalStoragePath(Promise promise) {
|
||||
promise.resolve(Utils.getExternalStoragePath(reactContext, true));
|
||||
WritableArray arr = Arguments.createArray();
|
||||
ArrayList<String> paths = Utils.getExternalStoragePath(reactContext, true);
|
||||
for (String p: paths) arr.pushString(p);
|
||||
promise.resolve(arr);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -14,7 +14,7 @@
|
||||
- 优化播放详情页歌曲封面、控制按钮对各尺寸屏幕的适配,修改横屏下的控制栏按钮布局
|
||||
- 优化横竖屏界面的暂时判断,现在趋于方屏的屏幕按竖屏的方式显示,横屏下的播放栏添加上一曲切歌按钮
|
||||
- 添加对wy源某些歌曲有问题的歌词进行修复(#370)
|
||||
- 文件选择器允许(在旧系统)选择外置存储设备上的路径
|
||||
- 文件选择器允许(在旧系统)选择外置存储设备上的路径,长按存储卡按钮可显示手动输入存储路径的窗口
|
||||
- 图片显示改用第三方的图片组件,支持gif类型的图片显示,尝试解决某些设备上图片过多导致的应用崩溃问题
|
||||
- 歌曲评论内容过长时自动折叠,需手动展开
|
||||
- 改进本地音乐在线信息的匹配机制
|
||||
|
@ -1,52 +1,17 @@
|
||||
import { forwardRef, memo, useCallback, useEffect, useImperativeHandle, useRef, useState } from 'react'
|
||||
import { memo, useCallback, useEffect, useRef } from 'react'
|
||||
import { View, TouchableOpacity } from 'react-native'
|
||||
import Input, { type InputType } from '@/components/common/Input'
|
||||
import Text from '@/components/common/Text'
|
||||
import { Icon } from '@/components/common/Icon'
|
||||
import ConfirmAlert, { type ConfirmAlertType } from '@/components/common/ConfirmAlert'
|
||||
import { createStyle, toast } from '@/utils/tools'
|
||||
import { mkdir, readDir } from '@/utils/fs'
|
||||
import { createStyle } from '@/utils/tools'
|
||||
import { readDir } from '@/utils/fs'
|
||||
import { useTheme } from '@/store/theme/hook'
|
||||
import { scaleSizeH } from '@/utils/pixelRatio'
|
||||
import { getExternalStoragePath } from '@/utils/nativeModules/utils'
|
||||
import { useUnmounted } from '@/utils/hooks'
|
||||
import { useStatusbarHeight } from '@/store/common/hook'
|
||||
const filterFileName = /[\\/:*?#"<>|]/
|
||||
import NewFolderModal, { type NewFolderType } from './NewFolderModal'
|
||||
import OpenStorageModal, { type OpenDirModalType } from './OpenStorageModal'
|
||||
|
||||
|
||||
interface NameInputType {
|
||||
setName: (text: string) => void
|
||||
getText: () => string
|
||||
focus: () => void
|
||||
}
|
||||
const NameInput = forwardRef<NameInputType, {}>((props, ref) => {
|
||||
const theme = useTheme()
|
||||
const [text, setText] = useState('')
|
||||
const inputRef = useRef<InputType>(null)
|
||||
|
||||
useImperativeHandle(ref, () => ({
|
||||
getText() {
|
||||
return text.trim()
|
||||
},
|
||||
setName(text) {
|
||||
setText(text)
|
||||
},
|
||||
focus() {
|
||||
inputRef.current?.focus()
|
||||
},
|
||||
}))
|
||||
|
||||
return (
|
||||
<Input
|
||||
ref={inputRef}
|
||||
placeholder={global.i18n.t('create_new_folder_tip')}
|
||||
value={text}
|
||||
onChangeText={setText}
|
||||
style={{ ...styles.input, backgroundColor: theme['c-primary-input-background'] }}
|
||||
/>
|
||||
)
|
||||
})
|
||||
|
||||
export default memo(({
|
||||
title,
|
||||
path,
|
||||
@ -57,24 +22,21 @@ export default memo(({
|
||||
onRefreshDir: (dir: string) => Promise<void>
|
||||
}) => {
|
||||
const theme = useTheme()
|
||||
const confirmAlertRef = useRef<ConfirmAlertType>(null)
|
||||
const nameInputRef = useRef<NameInputType>(null)
|
||||
const storagePathRef = useRef('')
|
||||
const [isShowStorage, setIsShowStorage] = useState(false)
|
||||
const isUnmounted = useUnmounted()
|
||||
const newFolderTypeRef = useRef<NewFolderType>(null)
|
||||
const openDirModalTypeRef = useRef<OpenDirModalType>(null)
|
||||
const storagePathsRef = useRef<string[]>([])
|
||||
const statusBarHeight = useStatusbarHeight()
|
||||
|
||||
const checkExternalStoragePath = useCallback(() => {
|
||||
void getExternalStoragePath().then((storagePath) => {
|
||||
if (storagePath) {
|
||||
void readDir(storagePath).then(() => {
|
||||
if (isUnmounted.current) return
|
||||
storagePathRef.current = storagePath
|
||||
setIsShowStorage(true)
|
||||
}).catch(() => {
|
||||
setIsShowStorage(false)
|
||||
})
|
||||
} else setIsShowStorage(false)
|
||||
// storagePathsRef.current = []
|
||||
void getExternalStoragePath().then(async(storagePaths) => {
|
||||
for (const path of storagePaths) {
|
||||
try {
|
||||
await readDir(path)
|
||||
} catch { continue }
|
||||
storagePathsRef.current.push(path)
|
||||
break
|
||||
}
|
||||
})
|
||||
}, [])
|
||||
useEffect(() => {
|
||||
@ -87,38 +49,18 @@ export default memo(({
|
||||
}
|
||||
|
||||
const toggleStorageDir = () => {
|
||||
void onRefreshDir(storagePathRef.current)
|
||||
}
|
||||
|
||||
const handleShow = () => {
|
||||
confirmAlertRef.current?.setVisible(true)
|
||||
requestAnimationFrame(() => {
|
||||
setTimeout(() => {
|
||||
nameInputRef.current?.focus()
|
||||
}, 300)
|
||||
})
|
||||
}
|
||||
|
||||
const handleHideNewFolderAlert = () => {
|
||||
nameInputRef.current?.setName('')
|
||||
}
|
||||
const handleConfirmNewFolderAlert = () => {
|
||||
const text = nameInputRef.current?.getText() ?? ''
|
||||
if (!text) return
|
||||
if (filterFileName.test(text)) {
|
||||
toast(global.i18n.t('create_new_folder_error_tip'), 'long')
|
||||
if (storagePathsRef.current.length) {
|
||||
void onRefreshDir(storagePathsRef.current[0])
|
||||
return
|
||||
}
|
||||
const newPath = `${path}/${text}`
|
||||
mkdir(newPath).then(() => {
|
||||
void onRefreshDir(path).then(() => {
|
||||
void onRefreshDir(newPath)
|
||||
})
|
||||
nameInputRef.current?.setName('')
|
||||
}).catch((err: any) => {
|
||||
toast('Create failed: ' + (err.message as string))
|
||||
})
|
||||
confirmAlertRef.current?.setVisible(false)
|
||||
openStorage()
|
||||
}
|
||||
const openStorage = () => {
|
||||
openDirModalTypeRef.current?.show(storagePathsRef.current)
|
||||
}
|
||||
|
||||
const handleShowNewFolderModal = () => {
|
||||
newFolderTypeRef.current?.show(path)
|
||||
}
|
||||
|
||||
return (
|
||||
@ -134,14 +76,10 @@ export default memo(({
|
||||
<Text style={styles.subTitle} color={theme['c-primary-font']} size={13} numberOfLines={1}>{path}</Text>
|
||||
</View>
|
||||
<View style={styles.actions}>
|
||||
{
|
||||
isShowStorage ? (
|
||||
<TouchableOpacity style={styles.actionBtn} onPress={toggleStorageDir}>
|
||||
<Icon name="sd-card" color={theme['c-primary-font']} size={22} />
|
||||
</TouchableOpacity>
|
||||
) : null
|
||||
}
|
||||
<TouchableOpacity style={styles.actionBtn} onPress={handleShow}>
|
||||
<TouchableOpacity style={styles.actionBtn} onPress={toggleStorageDir} onLongPress={openStorage}>
|
||||
<Icon name="sd-card" color={theme['c-primary-font']} size={22} />
|
||||
</TouchableOpacity>
|
||||
<TouchableOpacity style={styles.actionBtn} onPress={handleShowNewFolderModal}>
|
||||
<Icon name="add_folder" color={theme['c-primary-font']} size={22} />
|
||||
</TouchableOpacity>
|
||||
<TouchableOpacity style={styles.actionBtn} onPress={refresh}>
|
||||
@ -149,16 +87,8 @@ export default memo(({
|
||||
</TouchableOpacity>
|
||||
</View>
|
||||
</View>
|
||||
<ConfirmAlert
|
||||
onHide={handleHideNewFolderAlert}
|
||||
onConfirm={handleConfirmNewFolderAlert}
|
||||
ref={confirmAlertRef}
|
||||
>
|
||||
<View style={styles.newFolderContent}>
|
||||
<Text style={styles.newFolderTitle}>{global.i18n.t('create_new_folder')}</Text>
|
||||
<NameInput ref={nameInputRef} />
|
||||
</View>
|
||||
</ConfirmAlert>
|
||||
<OpenStorageModal ref={openDirModalTypeRef} onRefreshDir={onRefreshDir} />
|
||||
<NewFolderModal ref={newFolderTypeRef} onRefreshDir={onRefreshDir} />
|
||||
</>
|
||||
)
|
||||
})
|
||||
|
118
src/components/common/ChoosePath/components/NewFolderModal.tsx
Normal file
118
src/components/common/ChoosePath/components/NewFolderModal.tsx
Normal file
@ -0,0 +1,118 @@
|
||||
import { forwardRef, useImperativeHandle, useRef, useState } from 'react'
|
||||
import { View } from 'react-native'
|
||||
import Input, { type InputType } from '@/components/common/Input'
|
||||
import Text from '@/components/common/Text'
|
||||
import ConfirmAlert, { type ConfirmAlertType } from '@/components/common/ConfirmAlert'
|
||||
import { createStyle, toast } from '@/utils/tools'
|
||||
import { mkdir } from '@/utils/fs'
|
||||
import { useTheme } from '@/store/theme/hook'
|
||||
const filterFileName = /[\\/:*?#"<>|]/
|
||||
|
||||
|
||||
interface NameInputType {
|
||||
setName: (text: string) => void
|
||||
getText: () => string
|
||||
focus: () => void
|
||||
}
|
||||
const NameInput = forwardRef<NameInputType, {}>((props, ref) => {
|
||||
const theme = useTheme()
|
||||
const [text, setText] = useState('')
|
||||
const inputRef = useRef<InputType>(null)
|
||||
|
||||
useImperativeHandle(ref, () => ({
|
||||
getText() {
|
||||
return text.trim()
|
||||
},
|
||||
setName(text) {
|
||||
setText(text)
|
||||
},
|
||||
focus() {
|
||||
inputRef.current?.focus()
|
||||
},
|
||||
}))
|
||||
|
||||
return (
|
||||
<Input
|
||||
ref={inputRef}
|
||||
placeholder={global.i18n.t('create_new_folder_tip')}
|
||||
value={text}
|
||||
onChangeText={setText}
|
||||
style={{ ...styles.input, backgroundColor: theme['c-primary-input-background'] }}
|
||||
/>
|
||||
)
|
||||
})
|
||||
|
||||
export interface NewFolderType {
|
||||
show: (path: string) => void
|
||||
}
|
||||
export default forwardRef<NewFolderType, { onRefreshDir: (dir: string) => Promise<void> }>(({ onRefreshDir }, ref) => {
|
||||
const confirmAlertRef = useRef<ConfirmAlertType>(null)
|
||||
const nameInputRef = useRef<NameInputType>(null)
|
||||
const pathRef = useRef<string>('')
|
||||
|
||||
useImperativeHandle(ref, () => ({
|
||||
show(path) {
|
||||
pathRef.current = path
|
||||
confirmAlertRef.current?.setVisible(true)
|
||||
requestAnimationFrame(() => {
|
||||
setTimeout(() => {
|
||||
nameInputRef.current?.focus()
|
||||
}, 300)
|
||||
})
|
||||
},
|
||||
}))
|
||||
|
||||
const handleHideNewFolderAlert = () => {
|
||||
nameInputRef.current?.setName('')
|
||||
}
|
||||
const handleConfirmNewFolderAlert = () => {
|
||||
const text = nameInputRef.current?.getText() ?? ''
|
||||
if (!text) return
|
||||
if (filterFileName.test(text)) {
|
||||
toast(global.i18n.t('create_new_folder_error_tip'), 'long')
|
||||
return
|
||||
}
|
||||
const newPath = `${pathRef.current}/${text}`
|
||||
mkdir(newPath).then(() => {
|
||||
void onRefreshDir(pathRef.current).then(() => {
|
||||
void onRefreshDir(newPath)
|
||||
})
|
||||
nameInputRef.current?.setName('')
|
||||
}).catch((err: any) => {
|
||||
toast('Create failed: ' + (err.message as string))
|
||||
})
|
||||
confirmAlertRef.current?.setVisible(false)
|
||||
}
|
||||
|
||||
return (
|
||||
<ConfirmAlert
|
||||
onHide={handleHideNewFolderAlert}
|
||||
onConfirm={handleConfirmNewFolderAlert}
|
||||
ref={confirmAlertRef}
|
||||
>
|
||||
<View style={styles.newFolderContent}>
|
||||
<Text style={styles.newFolderTitle}>{global.i18n.t('create_new_folder')}</Text>
|
||||
<NameInput ref={nameInputRef} />
|
||||
</View>
|
||||
</ConfirmAlert>
|
||||
)
|
||||
})
|
||||
|
||||
const styles = createStyle({
|
||||
newFolderContent: {
|
||||
flexShrink: 1,
|
||||
flexDirection: 'column',
|
||||
},
|
||||
newFolderTitle: {
|
||||
marginBottom: 5,
|
||||
},
|
||||
input: {
|
||||
flexGrow: 1,
|
||||
flexShrink: 1,
|
||||
minWidth: 240,
|
||||
borderRadius: 4,
|
||||
paddingTop: 2,
|
||||
paddingBottom: 2,
|
||||
},
|
||||
})
|
||||
|
161
src/components/common/ChoosePath/components/OpenStorageModal.tsx
Normal file
161
src/components/common/ChoosePath/components/OpenStorageModal.tsx
Normal file
@ -0,0 +1,161 @@
|
||||
import { forwardRef, useImperativeHandle, useRef, useState } from 'react'
|
||||
import { View } from 'react-native'
|
||||
import Input, { type InputType } from '@/components/common/Input'
|
||||
import Text from '@/components/common/Text'
|
||||
import ConfirmAlert, { type ConfirmAlertType } from '@/components/common/ConfirmAlert'
|
||||
import { createStyle, toast } from '@/utils/tools'
|
||||
import { readDir } from '@/utils/fs'
|
||||
import { useTheme } from '@/store/theme/hook'
|
||||
import { getOpenStoragePath, saveOpenStoragePath } from '@/utils/data'
|
||||
import Button from '../../Button'
|
||||
const filterFileName = /[\\:*?#"<>|]/
|
||||
|
||||
|
||||
interface PathInputType {
|
||||
setPath: (text: string) => void
|
||||
getText: () => string
|
||||
focus: () => void
|
||||
}
|
||||
const PathInput = forwardRef<PathInputType, {}>((props, ref) => {
|
||||
const theme = useTheme()
|
||||
const [text, setText] = useState('')
|
||||
const inputRef = useRef<InputType>(null)
|
||||
|
||||
useImperativeHandle(ref, () => ({
|
||||
getText() {
|
||||
return text.trim()
|
||||
},
|
||||
setPath(text) {
|
||||
setText(text)
|
||||
},
|
||||
focus() {
|
||||
inputRef.current?.focus()
|
||||
},
|
||||
}))
|
||||
|
||||
return (
|
||||
<Input
|
||||
ref={inputRef}
|
||||
placeholder={global.i18n.t('open_storage_tip')}
|
||||
value={text}
|
||||
onChangeText={setText}
|
||||
multiline
|
||||
numberOfLines={3}
|
||||
textAlignVertical='top'
|
||||
style={{ ...styles.input, backgroundColor: theme['c-primary-input-background'] }}
|
||||
/>
|
||||
)
|
||||
})
|
||||
|
||||
export interface OpenDirModalType {
|
||||
show: (paths: string[]) => void
|
||||
}
|
||||
export default forwardRef<OpenDirModalType, { onRefreshDir: (dir: string) => Promise<void> }>(({
|
||||
onRefreshDir,
|
||||
}, ref) => {
|
||||
const confirmAlertRef = useRef<ConfirmAlertType>(null)
|
||||
const inputRef = useRef<PathInputType>(null)
|
||||
const [paths, setPaths] = useState<string[]>([])
|
||||
|
||||
useImperativeHandle(ref, () => ({
|
||||
show(paths) {
|
||||
setPaths(paths)
|
||||
confirmAlertRef.current?.setVisible(true)
|
||||
requestAnimationFrame(() => {
|
||||
void getOpenStoragePath().then(path => {
|
||||
if (path) inputRef.current?.setPath(path)
|
||||
})
|
||||
setTimeout(() => {
|
||||
inputRef.current?.focus()
|
||||
}, 300)
|
||||
})
|
||||
},
|
||||
}))
|
||||
|
||||
// const handleHideAlert = () => {
|
||||
// inputRef.current?.setPath('')
|
||||
// }
|
||||
const handleConfirmAlert = async() => {
|
||||
const text = inputRef.current?.getText() ?? ''
|
||||
if (text) {
|
||||
if (!text.startsWith('/') || filterFileName.test(text)) {
|
||||
toast(global.i18n.t('open_storage_error_tip'), 'long')
|
||||
return
|
||||
}
|
||||
try {
|
||||
await readDir(text)
|
||||
} catch (err: any) {
|
||||
toast('Open failed: ' + err.message, 'long')
|
||||
return
|
||||
}
|
||||
void onRefreshDir(text)
|
||||
}
|
||||
void saveOpenStoragePath(text)
|
||||
confirmAlertRef.current?.setVisible(false)
|
||||
}
|
||||
|
||||
return (
|
||||
<ConfirmAlert
|
||||
onConfirm={handleConfirmAlert}
|
||||
ref={confirmAlertRef}
|
||||
>
|
||||
<View style={styles.newFolderContent} onStartShouldSetResponder={() => true}>
|
||||
<Text style={styles.newFolderTitle}>
|
||||
{
|
||||
paths.length
|
||||
? global.i18n.t('open_storage_title')
|
||||
: global.i18n.t('open_storage_not_found_title')
|
||||
}
|
||||
</Text>
|
||||
<PathInput ref={inputRef} />
|
||||
{
|
||||
paths.length ? (
|
||||
<View style={styles.list}>
|
||||
{
|
||||
paths.map(path => {
|
||||
return (
|
||||
<Button style={styles.listItem} key={path} onPress={() => inputRef.current?.setPath(path)}>
|
||||
<Text size={12}>{path}</Text>
|
||||
</Button>
|
||||
)
|
||||
})
|
||||
}
|
||||
</View>
|
||||
) : null
|
||||
}
|
||||
</View>
|
||||
</ConfirmAlert>
|
||||
)
|
||||
})
|
||||
|
||||
const styles = createStyle({
|
||||
newFolderContent: {
|
||||
flexGrow: 0,
|
||||
flexShrink: 1,
|
||||
flexDirection: 'column',
|
||||
},
|
||||
newFolderTitle: {
|
||||
marginBottom: 5,
|
||||
width: 300,
|
||||
maxWidth: '100%',
|
||||
},
|
||||
input: {
|
||||
flexGrow: 1,
|
||||
flexShrink: 1,
|
||||
minWidth: 240,
|
||||
borderRadius: 4,
|
||||
paddingTop: 3,
|
||||
paddingBottom: 3,
|
||||
height: 'auto',
|
||||
},
|
||||
list: {
|
||||
flexGrow: 1,
|
||||
flexShrink: 1,
|
||||
marginTop: 10,
|
||||
},
|
||||
listItem: {
|
||||
paddingVertical: 10,
|
||||
paddingHorizontal: 5,
|
||||
},
|
||||
})
|
||||
|
@ -55,6 +55,7 @@ export const storageDataPrefix = {
|
||||
syncHost: '@sync_host',
|
||||
syncHostHistory: '@sync_host_history',
|
||||
|
||||
openStoragePath: '@open_storage_path',
|
||||
notificationTipEnable: '@notification_tip_enable',
|
||||
ignoringBatteryOptimizationTipEnable: '@ignoring_battery_optimization_tip_enable',
|
||||
|
||||
|
@ -138,6 +138,10 @@
|
||||
"notifications_check_tip": "You have not allowed LX Music to display notifications, or the Music Service in the LX Music notification settings has been disabled, which will prevent you from using the notification bar to pause, switch songs, etc. Do you want to enable it?",
|
||||
"notifications_check_title": "Notification permission reminder",
|
||||
"ok": "OK",
|
||||
"open_storage_error_tip": "The entered path is illegal",
|
||||
"open_storage_not_found_title": "External memory card not found, please manually enter the path below to specify the external memory",
|
||||
"open_storage_tip": "Enter storage path",
|
||||
"open_storage_title": "Please manually enter the path below to specify the external storage",
|
||||
"parent_dir_name": "Parent directory",
|
||||
"pause": "Pause",
|
||||
"play": "Play",
|
||||
|
@ -138,6 +138,10 @@
|
||||
"notifications_check_tip": "你没有允许LX Music显示通知,或LX Music通知设置里的Music Service通知被禁用,这将无法使用通知栏进行暂停、切歌等操作,是否去开启?",
|
||||
"notifications_check_title": "通知权限提醒",
|
||||
"ok": "我知道了",
|
||||
"open_storage_error_tip": "输入的路径不合法",
|
||||
"open_storage_not_found_title": "未找到外置存储卡,请手动在下方输入路径以指定外置存储器",
|
||||
"open_storage_tip": "输入存储路径",
|
||||
"open_storage_title": "请手动在下方输入路径以指定外置存储器",
|
||||
"parent_dir_name": "父级目录",
|
||||
"pause": "暂停",
|
||||
"play": "播放",
|
||||
|
@ -27,6 +27,7 @@ const syncHostHistoryPrefix = storageDataPrefix.syncHostHistory
|
||||
const listPrefix = storageDataPrefix.list
|
||||
const dislikeListPrefix = storageDataPrefix.dislikeList
|
||||
const userApiPrefix = storageDataPrefix.userApi
|
||||
const openStoragePathPrefix = storageDataPrefix.openStoragePath
|
||||
|
||||
// const defaultListKey = listPrefix + 'default'
|
||||
// const loveListKey = listPrefix + 'love'
|
||||
@ -195,6 +196,25 @@ export const getIgnoreVersionFailTipTime = async() => {
|
||||
return ignoreVersionFailTipTime ?? 0
|
||||
}
|
||||
|
||||
let openStoragePath: string | null = ''
|
||||
export const saveOpenStoragePath = async(path: string) => {
|
||||
if (path) {
|
||||
openStoragePath = path
|
||||
await saveData(openStoragePathPrefix, path)
|
||||
} else {
|
||||
if (!openStoragePath) return
|
||||
openStoragePath = null
|
||||
await removeData(openStoragePathPrefix)
|
||||
}
|
||||
}
|
||||
// 获取上次打开的存储路径
|
||||
export const getOpenStoragePath = async() => {
|
||||
if (openStoragePath === '') {
|
||||
// eslint-disable-next-line require-atomic-updates
|
||||
openStoragePath = await getData<string | null>(openStoragePathPrefix)
|
||||
}
|
||||
return openStoragePath
|
||||
}
|
||||
|
||||
export const getSearchSetting = async() => {
|
||||
// eslint-disable-next-line require-atomic-updates
|
||||
|
@ -70,7 +70,7 @@ export const onScreenStateChange = (handler: (state: 'ON' | 'OFF') => void): ()
|
||||
}
|
||||
}
|
||||
|
||||
export const getExternalStoragePath = async(): Promise<string | null> => {
|
||||
export const getExternalStoragePath = async(): Promise<string[]> => {
|
||||
return UtilsModule.getExternalStoragePath()
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user