mirror of
https://github.com/ikun0014/lx-music-mobile.git
synced 2025-07-03 19:32:09 +08:00
lint fix
This commit is contained in:
parent
4bbf3f51f9
commit
feeef4f6d2
@ -16,7 +16,7 @@
|
||||
"pack:android:debug": "./gradlew assembleDebug",
|
||||
"pack": "npm run pack:android",
|
||||
"pack:android": "cd android && gradlew.bat assembleRelease",
|
||||
"clear": "react-native clean-project",
|
||||
"clear": "cd android && gradlew.bat clean",
|
||||
"build:theme": "node src/theme/themes/createThemes.js",
|
||||
"publish": "node publish"
|
||||
},
|
||||
|
@ -1,6 +1,6 @@
|
||||
import React, { useState, useRef, useEffect } from 'react'
|
||||
import { View } from 'react-native'
|
||||
import Input, { InputType } from '@/components/common/Input'
|
||||
import Input, { type InputType } from '@/components/common/Input'
|
||||
import { createStyle } from '@/utils/tools'
|
||||
import { useI18n } from '@/lang'
|
||||
import { createUserList } from '@/core/list'
|
||||
|
@ -1,5 +1,5 @@
|
||||
import React, { forwardRef, useImperativeHandle, useRef, useState } from 'react'
|
||||
import Dialog, { DialogType } from '@/components/common/Dialog'
|
||||
import Dialog, { type DialogType } from '@/components/common/Dialog'
|
||||
import { toast } from '@/utils/tools'
|
||||
import Title from './Title'
|
||||
import List from './List'
|
||||
|
@ -1,5 +1,5 @@
|
||||
import React, { useRef, useImperativeHandle, forwardRef, useState } from 'react'
|
||||
import Modal, { MusicMultiAddModalType as ModalType, SelectInfo } from './MusicMultiAddModal'
|
||||
import Modal, { type MusicMultiAddModalType as ModalType, type SelectInfo } from './MusicMultiAddModal'
|
||||
|
||||
export interface MusicMultiAddModalType {
|
||||
show: (info: SelectInfo) => void
|
||||
|
@ -113,10 +113,10 @@ export default forwardRef<MultipleModeBarType, MultipleModeBarProps>(({ onSelect
|
||||
return (
|
||||
<Animated.View style={animaStyle}>
|
||||
<View style={styles.switchBtn}>
|
||||
<Button onPress={() => onSwitchMode('single')} style={{ ...styles.btn, backgroundColor: selectMode == 'single' ? theme['c-button-background'] : 'rgba(0,0,0,0)' }}>
|
||||
<Button onPress={() => { onSwitchMode('single') }} style={{ ...styles.btn, backgroundColor: selectMode == 'single' ? theme['c-button-background'] : 'rgba(0,0,0,0)' }}>
|
||||
<Text color={theme['c-button-font']}>{global.i18n.t('list_select_single')}</Text>
|
||||
</Button>
|
||||
<Button onPress={() => onSwitchMode('range')} style={{ ...styles.btn, backgroundColor: selectMode == 'range' ? theme['c-button-background'] : 'rgba(0,0,0,0)' }}>
|
||||
<Button onPress={() => { onSwitchMode('range') }} style={{ ...styles.btn, backgroundColor: selectMode == 'range' ? theme['c-button-background'] : 'rgba(0,0,0,0)' }}>
|
||||
<Text color={theme['c-button-font']}>{global.i18n.t('list_select_range')}</Text>
|
||||
</Button>
|
||||
</View>
|
||||
|
@ -1,5 +1,5 @@
|
||||
import React, { useState, forwardRef, useImperativeHandle, Ref } from 'react'
|
||||
import { FlatList, FlatListProps } from 'react-native'
|
||||
import React, { useState, forwardRef, useImperativeHandle, type Ref } from 'react'
|
||||
import { FlatList, type FlatListProps } from 'react-native'
|
||||
|
||||
// import InsetShadow from 'react-native-inset-shadow'
|
||||
|
||||
|
@ -1,8 +1,8 @@
|
||||
import React, { useRef, useImperativeHandle, forwardRef, useState, useEffect } from 'react'
|
||||
import ConfirmAlert, { ConfirmAlertType } from '@/components/common/ConfirmAlert'
|
||||
import ConfirmAlert, { type ConfirmAlertType } from '@/components/common/ConfirmAlert'
|
||||
import Text from '@/components/common/Text'
|
||||
import { View } from 'react-native'
|
||||
import Input, { InputType } from '@/components/common/Input'
|
||||
import Input, { type InputType } from '@/components/common/Input'
|
||||
import { createStyle, toast } from '@/utils/tools'
|
||||
import { useTheme } from '@/store/theme/hook'
|
||||
import { cancelTimeoutExit, getTimeoutExitTime, onTimeUpdate, startTimeoutExit, stopTimeoutExit, useTimeoutExitTimeInfo } from '@/core/player/timeoutExit'
|
||||
|
@ -1,6 +1,6 @@
|
||||
import { useTheme } from '@/store/theme/hook'
|
||||
import React, { useMemo, useRef, useImperativeHandle, forwardRef } from 'react'
|
||||
import { Pressable, PressableProps, StyleSheet, View, ViewProps } from 'react-native'
|
||||
import { Pressable, type PressableProps, StyleSheet, type View, type ViewProps } from 'react-native'
|
||||
// import { AppColors } from '@/theme'
|
||||
|
||||
|
||||
|
@ -1,10 +1,10 @@
|
||||
import React, { forwardRef, memo, useImperativeHandle, useRef, useState } from 'react'
|
||||
import { View, TouchableOpacity } from 'react-native'
|
||||
import Input, { InputType } from '@/components/common/Input'
|
||||
import Input, { type InputType } from '@/components/common/Input'
|
||||
import Text from '@/components/common/Text'
|
||||
import { Icon } from '@/components/common/Icon'
|
||||
import StatusBar from '@/components/common/StatusBar'
|
||||
import ConfirmAlert, { ConfirmAlertType } from '@/components/common/ConfirmAlert'
|
||||
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'
|
||||
|
@ -4,7 +4,7 @@ import { createStyle } from '@/utils/tools'
|
||||
import React, { useMemo } from 'react'
|
||||
import { View, FlatList } from 'react-native'
|
||||
|
||||
import ListItem, { PathItem } from './ListItem'
|
||||
import ListItem, { type PathItem } from './ListItem'
|
||||
|
||||
|
||||
export default ({ list, onSetPath, toParentDir }: {
|
||||
|
@ -2,9 +2,9 @@ import React, { useState, useRef, forwardRef, useImperativeHandle } from 'react'
|
||||
// import { StyleSheet, View, Text, StatusBar, ScrollView } from 'react-native'
|
||||
|
||||
// import { useGetter, useDispatch } from '@/store'
|
||||
import List, { ListType } from './List'
|
||||
import List, { type ListType } from './List'
|
||||
|
||||
import ConfirmAlert, { ConfirmAlertType } from '@/components/common/ConfirmAlert'
|
||||
import ConfirmAlert, { type ConfirmAlertType } from '@/components/common/ConfirmAlert'
|
||||
import { checkStoragePermissions, requestStoragePermission, toast } from '@/utils/tools'
|
||||
import { useI18n } from '@/lang'
|
||||
|
||||
|
@ -2,7 +2,7 @@ import React, { useMemo, useRef, useImperativeHandle, forwardRef, useState } fro
|
||||
import { View, TouchableWithoutFeedback } from 'react-native'
|
||||
import { useDimensions } from '@/utils/hooks'
|
||||
|
||||
import Modal, { ModalType } from '@/components/common/Modal'
|
||||
import Modal, { type ModalType } from '@/components/common/Modal'
|
||||
import { createStyle } from '@/utils/tools'
|
||||
// import { useGetter } from '@/store'
|
||||
|
||||
|
@ -1,8 +1,8 @@
|
||||
import React, { useRef, forwardRef } from 'react'
|
||||
// import { View } from 'react-native'
|
||||
|
||||
import Panel, { PanelType } from './Panel'
|
||||
import Button, { BtnType } from '@/components/common/Button'
|
||||
import Panel, { type PanelType } from './Panel'
|
||||
import Button, { type BtnType } from '@/components/common/Button'
|
||||
|
||||
|
||||
export interface DorpDownPanelProps {
|
||||
|
@ -1,7 +1,7 @@
|
||||
import { createIconSetFromIcoMoon } from 'react-native-vector-icons'
|
||||
import icoMoonConfig from '@/resources/fonts/selection.json'
|
||||
import { scaleSizeW } from '@/utils/pixelRatio'
|
||||
import { ComponentProps } from 'react'
|
||||
import { type ComponentProps } from 'react'
|
||||
import { useTheme } from '@/store/theme/hook'
|
||||
|
||||
// import IconAntDesign from 'react-native-vector-icons/AntDesign'
|
||||
|
@ -1,5 +1,5 @@
|
||||
import React, { useRef, useImperativeHandle, forwardRef, useCallback } from 'react'
|
||||
import { TextInput, View, TouchableOpacity, StyleSheet, TextInputProps } from 'react-native'
|
||||
import { TextInput, View, TouchableOpacity, StyleSheet, type TextInputProps } from 'react-native'
|
||||
import { Icon } from '@/components/common/Icon'
|
||||
import { createStyle } from '@/utils/tools'
|
||||
import { useTheme } from '@/store/theme/hook'
|
||||
|
@ -1,6 +1,6 @@
|
||||
import React, { memo } from 'react'
|
||||
|
||||
import Slider, { SliderProps as _SliderProps } from '@react-native-community/slider'
|
||||
import Slider, { type SliderProps as _SliderProps } from '@react-native-community/slider'
|
||||
import { createStyle } from '@/utils/tools'
|
||||
import { useTheme } from '@/store/theme/hook'
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
import React, { memo, useMemo } from 'react'
|
||||
import { View, Pressable, GestureResponderEvent } from 'react-native'
|
||||
import { View, Pressable, type GestureResponderEvent } from 'react-native'
|
||||
import { useLayout } from '@/utils/hooks'
|
||||
import { createStyle } from '@/utils/tools'
|
||||
import { useTheme } from '@/store/theme/hook'
|
||||
|
@ -143,7 +143,7 @@ export const getListDetailAll = async(id: string, isRefresh = false): Promise<LX
|
||||
if (pageCache) return pageCache.data
|
||||
return getListLimit(source, bangId, page)
|
||||
}
|
||||
return loadData(1).then(result => {
|
||||
return loadData(1).then(async result => {
|
||||
if (result.total <= result.limit) return result.list
|
||||
|
||||
let maxPage = Math.ceil(result.total / result.limit)
|
||||
|
@ -355,7 +355,7 @@ export const getOnlineOtherSourceLyricInfo = async({ musicInfos, onToggleSource,
|
||||
reqPromise = Promise.reject(err)
|
||||
}
|
||||
retryedSource.includes(musicInfo.source)
|
||||
return reqPromise.then((lyricInfo: LX.Music.LyricInfo) => {
|
||||
return reqPromise.then(async(lyricInfo: LX.Music.LyricInfo) => {
|
||||
return existTimeExp.test(lyricInfo.lyric) ? {
|
||||
lyricInfo,
|
||||
musicInfo,
|
||||
@ -389,7 +389,7 @@ export const handleGetOnlineLyricInfo = async({ musicInfo, onToggleSource, isRef
|
||||
} catch (err) {
|
||||
reqPromise = Promise.reject(err)
|
||||
}
|
||||
return reqPromise.then((lyricInfo: LX.Music.LyricInfo) => {
|
||||
return reqPromise.then(async(lyricInfo: LX.Music.LyricInfo) => {
|
||||
return existTimeExp.test(lyricInfo.lyric) ? {
|
||||
musicInfo,
|
||||
lyricInfo,
|
||||
|
@ -80,7 +80,7 @@ const getMusicPlayUrl = async(musicInfo: LX.Music.MusicInfo | LX.Download.ListIt
|
||||
if (global.lx.isPlayedStop || diffCurrentMusicInfo(musicInfo)) return null
|
||||
|
||||
return url
|
||||
}).catch(err => {
|
||||
}).catch(async err => {
|
||||
// console.log('err', err.message)
|
||||
if (global.lx.isPlayedStop ||
|
||||
diffCurrentMusicInfo(musicInfo) ||
|
||||
|
@ -216,7 +216,7 @@ export const getListDetailAll = async(source: LX.OnlineSource, id: string, isRef
|
||||
if (pageCache) return pageCache.data
|
||||
return getListDetailLimit(source, id, page)
|
||||
}
|
||||
return loadData(1).then(result => {
|
||||
return loadData(1).then(async result => {
|
||||
if (result.total <= result.limit) return result.list
|
||||
|
||||
let maxPage = Math.ceil(result.total / result.limit)
|
||||
|
@ -124,7 +124,7 @@ export const useLrcSet = () => {
|
||||
setLines(lines)
|
||||
}
|
||||
lrcTools.addSetLyricHook(callback)
|
||||
return () => lrcTools.removeSetLyricHook(callback)
|
||||
return () => { lrcTools.removeSetLyricHook(callback) }
|
||||
}, [])
|
||||
|
||||
return lines
|
||||
|
@ -76,7 +76,7 @@ const registerPlaybackService = async() => {
|
||||
global.app_event.setProgress(position)
|
||||
})
|
||||
|
||||
TrackPlayer.addEventListener(TPEvent.PlaybackState, info => {
|
||||
TrackPlayer.addEventListener(TPEvent.PlaybackState, async info => {
|
||||
if (global.lx.gettingUrlId || isTempId()) return
|
||||
// let currentIsPlaying = false
|
||||
|
||||
|
@ -61,7 +61,7 @@ const codeAuth = async(urlInfo: LX.Sync.UrlInfo, serverId: string, authCode: str
|
||||
|
||||
const keyAuth = async(urlInfo: LX.Sync.UrlInfo, keyInfo: LX.Sync.KeyInfo) => {
|
||||
const msg = aesEncrypt(SYNC_CODE.authMsg + await getDeviceName(), keyInfo.key)
|
||||
return request(`${urlInfo.httpProtocol}//${urlInfo.hostPath}/ah`, { headers: { i: keyInfo.clientId, m: msg } }).then(({ text, code }) => {
|
||||
return request(`${urlInfo.httpProtocol}//${urlInfo.hostPath}/ah`, { headers: { i: keyInfo.clientId, m: msg } }).then(async({ text, code }) => {
|
||||
if (code != 200) throw new Error(SYNC_CODE.authFailed)
|
||||
|
||||
let msg
|
||||
|
@ -1,7 +1,7 @@
|
||||
import React, { useEffect, useRef } from 'react'
|
||||
import { filterList, getHotComment } from './utils'
|
||||
import music from '@/utils/musicSdk'
|
||||
import List, { ListType } from './components/List'
|
||||
import List, { type ListType } from './components/List'
|
||||
const limit = 15
|
||||
|
||||
export default ({ musicInfo, onUpdateTotal }: {
|
||||
|
@ -52,6 +52,7 @@ const CommentFloor = memo(({ comment, isLast }: {
|
||||
<Text style={styles.likedCount} size={12} color={ theme['c-450'] }>{comment.likedCount}</Text>
|
||||
</View>
|
||||
)
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
}, [])
|
||||
|
||||
return (
|
||||
|
@ -1,6 +1,6 @@
|
||||
import React, { useMemo, useRef, useImperativeHandle, forwardRef, useState } from 'react'
|
||||
import { useI18n } from '@/lang'
|
||||
import Menu, { MenuType, Position } from '@/components/common/Menu'
|
||||
import Menu, { type MenuType, type Position } from '@/components/common/Menu'
|
||||
|
||||
export interface SelectInfo {
|
||||
listId: string
|
||||
|
@ -18,7 +18,7 @@ export default forwardRef<MusicListType, {}>((props, ref) => {
|
||||
const listRef = useRef<OnlineListType>(null)
|
||||
const isUnmountedRef = useRef(false)
|
||||
useImperativeHandle(ref, () => ({
|
||||
loadList(source, id) {
|
||||
async loadList(source, id) {
|
||||
const listDetailInfo = boardState.listDetailInfo
|
||||
listRef.current?.setList([])
|
||||
if (listDetailInfo.id == id && listDetailInfo.source == source && listDetailInfo.list.length) {
|
||||
|
@ -37,7 +37,7 @@ export default forwardRef<ActiveListType, ActiveListProps>(({ onShowSearchBar },
|
||||
|
||||
useEffect(() => {
|
||||
void getListPrevSelectId().then((id) => {
|
||||
void setActiveList(id)
|
||||
setActiveList(id)
|
||||
})
|
||||
}, [])
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
import React, { useMemo, useRef, useImperativeHandle, forwardRef, useState } from 'react'
|
||||
import { useI18n } from '@/lang'
|
||||
import Menu, { MenuType, Position } from '@/components/common/Menu'
|
||||
import Menu, { type MenuType, type Position } from '@/components/common/Menu'
|
||||
|
||||
export interface SelectInfo {
|
||||
musicInfo: LX.Music.MusicInfo
|
||||
|
@ -18,7 +18,7 @@ export default forwardRef<MusicListType, {}>((props, ref) => {
|
||||
const searchInfoRef = useRef<{ text: string, source: Source }>({ text: '', source: 'kw' })
|
||||
const isUnmountedRef = useRef(false)
|
||||
useImperativeHandle(ref, () => ({
|
||||
loadList(text, source) {
|
||||
async loadList(text, source) {
|
||||
// const listDetailInfo = searchMusicState.listDetailInfo
|
||||
listRef.current?.setList([], source == 'all')
|
||||
if (searchMusicState.searchText == text && searchMusicState.source == source && searchMusicState.listInfos[searchMusicState.source]!.list.length) {
|
||||
|
@ -19,7 +19,7 @@ export default forwardRef<MusicListType, {}>((props, ref) => {
|
||||
const searchInfoRef = useRef<{ text: string, source: Source }>({ text: '', source: 'kw' })
|
||||
const isUnmountedRef = useRef(false)
|
||||
useImperativeHandle(ref, () => ({
|
||||
loadList(text, source) {
|
||||
async loadList(text, source) {
|
||||
// const listDetailInfo = searchSonglistState.listDetailInfo
|
||||
listRef.current?.setList([], source == 'all')
|
||||
if (searchSonglistState.searchText == text && searchSonglistState.source == source && searchSonglistState.listInfos[searchSonglistState.source]!.list.length) {
|
||||
|
@ -31,7 +31,7 @@ const Item = ({ position, label }: {
|
||||
}) => {
|
||||
const isActive = useActive(position)
|
||||
// const [toggleCheckBox, setToggleCheckBox] = useState(false)
|
||||
return <CheckBox marginRight={8} check={isActive} label={label} onChange={() => updateSetting({ 'common.drawerLayoutPosition': position })} need />
|
||||
return <CheckBox marginRight={8} check={isActive} label={label} onChange={() => { updateSetting({ 'common.drawerLayoutPosition': position }) }} need />
|
||||
}
|
||||
|
||||
export default memo(() => {
|
||||
|
@ -21,7 +21,7 @@ const Item = ({ id, name }: {
|
||||
}) => {
|
||||
const isActive = useActive(id)
|
||||
// const [toggleCheckBox, setToggleCheckBox] = useState(false)
|
||||
return <CheckBox marginRight={8} check={isActive} label={name} onChange={() => setLanguage(id)} need />
|
||||
return <CheckBox marginRight={8} check={isActive} label={name} onChange={() => { setLanguage(id) }} need />
|
||||
}
|
||||
|
||||
export default memo(() => {
|
||||
|
@ -27,7 +27,7 @@ const Item = ({ id, name }: {
|
||||
}) => {
|
||||
const isActive = useActive(id)
|
||||
// const [toggleCheckBox, setToggleCheckBox] = useState(false)
|
||||
return <CheckBox marginBottom={3} check={isActive} label={name} onChange={() => setShareType(id)} need />
|
||||
return <CheckBox marginBottom={3} check={isActive} label={name} onChange={() => { setShareType(id) }} need />
|
||||
}
|
||||
|
||||
export default memo(() => {
|
||||
|
@ -29,7 +29,7 @@ const Item = ({ id, name, change }: {
|
||||
}) => {
|
||||
const isActive = useActive(id)
|
||||
// const [toggleCheckBox, setToggleCheckBox] = useState(false)
|
||||
return <CheckBox marginBottom={5} check={isActive} label={name} onChange={() => change(id)} need />
|
||||
return <CheckBox marginBottom={5} check={isActive} label={name} onChange={() => { change(id) }} need />
|
||||
}
|
||||
|
||||
export default memo(() => {
|
||||
|
@ -27,7 +27,7 @@ const Item = ({ id, name }: {
|
||||
}) => {
|
||||
const isActive = useActive(id)
|
||||
// const [toggleCheckBox, setToggleCheckBox] = useState(false)
|
||||
return <CheckBox marginBottom={3} check={isActive} label={name} onChange={() => setSourceNameType(id)} need />
|
||||
return <CheckBox marginBottom={3} check={isActive} label={name} onChange={() => { setSourceNameType(id) }} need />
|
||||
}
|
||||
|
||||
export default memo(() => {
|
||||
|
@ -1,12 +1,12 @@
|
||||
import React, { memo, useCallback, useEffect, useMemo, useState } from 'react'
|
||||
import { View, ImageBackground, TouchableOpacity, InteractionManager, ImageSourcePropType } from 'react-native'
|
||||
import { View, ImageBackground, TouchableOpacity, InteractionManager, type ImageSourcePropType } from 'react-native'
|
||||
import { setTheme } from '@/core/theme'
|
||||
import { useI18n } from '@/lang'
|
||||
import { useSettingValue } from '@/store/setting/hook'
|
||||
import { useTheme } from '@/store/theme/hook'
|
||||
|
||||
import SubTitle from '../components/SubTitle'
|
||||
import { BG_IMAGES, getAllThemes, LocalTheme } from '@/theme/themes'
|
||||
import { BG_IMAGES, getAllThemes, type LocalTheme } from '@/theme/themes'
|
||||
import Text from '@/components/common/Text'
|
||||
import { createStyle } from '@/utils/tools'
|
||||
import { scaleSizeH } from '@/utils/pixelRatio'
|
||||
@ -28,7 +28,7 @@ const ThemeItem = ({ id, name, color, image, setTheme }: {
|
||||
const isActive = useActive(id)
|
||||
|
||||
return (
|
||||
<TouchableOpacity style={{ ...styles.item, width: scaleSizeH(ITEM_HEIGHT) }} activeOpacity={0.5} onPress={() => setTheme(id)}>
|
||||
<TouchableOpacity style={{ ...styles.item, width: scaleSizeH(ITEM_HEIGHT) }} activeOpacity={0.5} onPress={() => { setTheme(id) }}>
|
||||
<View style={{ ...styles.colorContent, width: scaleSizeH(COLOR_ITEM_HEIGHT), borderColor: isActive ? color : 'transparent' }}>
|
||||
{
|
||||
image
|
||||
|
@ -24,7 +24,7 @@ const Item = ({ id, name }: {
|
||||
}) => {
|
||||
const isActive = useActive(id)
|
||||
// const [toggleCheckBox, setToggleCheckBox] = useState(false)
|
||||
return <CheckBox marginRight={8} check={isActive} label={name} onChange={() => setAddMusicLocationType(id)} need />
|
||||
return <CheckBox marginRight={8} check={isActive} label={name} onChange={() => { setAddMusicLocationType(id) }} need />
|
||||
}
|
||||
|
||||
|
||||
|
@ -1,7 +1,7 @@
|
||||
import React, { memo, useMemo } from 'react'
|
||||
import { View } from 'react-native'
|
||||
|
||||
import InputItem, { InputItemProps } from '../components/InputItem'
|
||||
import InputItem, { type InputItemProps } from '../components/InputItem'
|
||||
import { createStyle, toast } from '@/utils/tools'
|
||||
import { useSettingValue } from '@/store/setting/hook'
|
||||
import { useI18n } from '@/lang'
|
||||
|
@ -80,6 +80,7 @@ export default memo(({ host, setHost }: {
|
||||
return () => {
|
||||
isUnmountedRef.current = true
|
||||
}
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
}, [])
|
||||
|
||||
useEffect(() => {
|
||||
|
@ -1,6 +1,6 @@
|
||||
import React, { memo } from 'react'
|
||||
|
||||
import Button, { BtnProps } from '@/components/common/Button'
|
||||
import Button, { type BtnProps } from '@/components/common/Button'
|
||||
import Text from '@/components/common/Text'
|
||||
import { useTheme } from '@/store/theme/hook'
|
||||
import { createStyle } from '@/utils/tools'
|
||||
|
@ -55,6 +55,7 @@ export default memo(({ value, label, onChanged, ...props }: InputItemProps) => {
|
||||
setText(newValue)
|
||||
textRef.current = newValue
|
||||
}
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
}, [value])
|
||||
const handleSetSelectMode = (text: string) => {
|
||||
setText(text)
|
||||
|
@ -13,7 +13,7 @@ export default forwardRef<ListType, {}>((props, ref) => {
|
||||
const listRef = useRef<SonglistType>(null)
|
||||
const isUnmountedRef = useRef(false)
|
||||
useImperativeHandle(ref, () => ({
|
||||
loadList(source, sortId, tagId) {
|
||||
async loadList(source, sortId, tagId) {
|
||||
const listInfo = songlistState.listInfo
|
||||
listRef.current?.setList([])
|
||||
if (listInfo.tagId == tagId && listInfo.sortId == sortId && listInfo.source == source && listInfo.list.length) {
|
||||
|
@ -1,5 +1,5 @@
|
||||
import React, { useRef } from 'react'
|
||||
import MusicAddModal, { MusicAddModalType } from '@/components/MusicAddModal'
|
||||
import MusicAddModal, { type MusicAddModalType } from '@/components/MusicAddModal'
|
||||
import playerState from '@/store/player/state'
|
||||
import Btn from './Btn'
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
import React, { memo, useMemo } from 'react'
|
||||
import { View, Pressable, GestureResponderEvent } from 'react-native'
|
||||
import { View, Pressable, type GestureResponderEvent } from 'react-native'
|
||||
import { useLayout } from '@/utils/hooks'
|
||||
import { createStyle } from '@/utils/tools'
|
||||
import { useTheme } from '@/store/theme/hook'
|
||||
|
@ -1,5 +1,5 @@
|
||||
import React, { useRef } from 'react'
|
||||
import MusicAddModal, { MusicAddModalType } from '@/components/MusicAddModal'
|
||||
import MusicAddModal, { type MusicAddModalType } from '@/components/MusicAddModal'
|
||||
import playerState from '@/store/player/state'
|
||||
import Btn from './Btn'
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
import React, { memo, useRef } from 'react'
|
||||
import TimeoutExitEditModal, { TimeoutExitEditModalType, useTimeInfo } from '@/components/TimeoutExitEditModal'
|
||||
import TimeoutExitEditModal, { type TimeoutExitEditModalType, useTimeInfo } from '@/components/TimeoutExitEditModal'
|
||||
import { useTheme } from '@/store/theme/hook'
|
||||
import Btn from './Btn'
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
import React, { memo, useMemo } from 'react'
|
||||
import { View, Pressable, GestureResponderEvent } from 'react-native'
|
||||
import { View, Pressable, type GestureResponderEvent } from 'react-native'
|
||||
import { useLayout } from '@/utils/hooks'
|
||||
import { createStyle } from '@/utils/tools'
|
||||
import { useTheme } from '@/store/theme/hook'
|
||||
|
@ -18,7 +18,7 @@ export default forwardRef<MusicListType, MusicListProps>(({ componentId }, ref)
|
||||
const headerRef = useRef<HeaderType>(null)
|
||||
const isUnmountedRef = useRef(false)
|
||||
useImperativeHandle(ref, () => ({
|
||||
loadList(source, id) {
|
||||
async loadList(source, id) {
|
||||
const listDetailInfo = songlistState.listDetailInfo
|
||||
listRef.current?.setList([])
|
||||
if (listDetailInfo.id == id && listDetailInfo.source == source && listDetailInfo.list.length) {
|
||||
@ -99,6 +99,7 @@ export default forwardRef<MusicListType, MusicListProps>(({ componentId }, ref)
|
||||
})
|
||||
}
|
||||
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
const header = useMemo(() => <Header ref={headerRef} componentId={componentId} />, [])
|
||||
|
||||
return <OnlineList
|
||||
|
@ -24,6 +24,7 @@ export default ({ componentId }: { componentId: string }) => {
|
||||
return () => {
|
||||
isUnmountedRef.current = true
|
||||
}
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
}, [])
|
||||
|
||||
|
||||
|
@ -46,6 +46,7 @@ export const usePageVisible = (visibleNames: COMPONENT_IDS[], onChange: (visible
|
||||
return () => {
|
||||
global.state_event.off('componentIdsUpdated', handlecheck)
|
||||
}
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
}, [])
|
||||
}
|
||||
|
||||
@ -62,6 +63,7 @@ export const useAssertApiSupport = (source: LX.Source) => {
|
||||
return () => {
|
||||
global.state_event.off('apiSourceUpdated', handleUpdate)
|
||||
}
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
}, [])
|
||||
|
||||
return value
|
||||
|
@ -84,6 +84,7 @@ export const useListFetching = (listId: string) => {
|
||||
return () => {
|
||||
global.state_event.off('fetchingListStatusUpdated', handleUpdate)
|
||||
}
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
}, [])
|
||||
|
||||
return fetching
|
||||
|
@ -1,35 +0,0 @@
|
||||
// import { createSlice } from '@reduxjs/toolkit'
|
||||
import { NAV_MENUS } from '@/config/constant'
|
||||
// import type { PayloadAction } from '@reduxjs/toolkit'
|
||||
// import type { RootState } from '@/store'
|
||||
|
||||
// type MenuIds = (typeof NAV_MENUS)[number]['id']
|
||||
|
||||
// // Define a type for the slice state
|
||||
// interface InitState {
|
||||
// activeId: MenuIds
|
||||
// }
|
||||
|
||||
// // Define the initial state using that type
|
||||
// const initialState: InitState = {
|
||||
// activeId: 'search',
|
||||
// }
|
||||
|
||||
// // export const slice = createSlice({
|
||||
// // name: 'common',
|
||||
// // // `createSlice` will infer the state type from the `initialState` argument
|
||||
// // initialState,
|
||||
// // reducers: {
|
||||
// // setNavActive(state, action: PayloadAction<MenuIds>) {
|
||||
// // if (action.payload === state.activeId) return
|
||||
// // state.activeId = action.payload
|
||||
// // },
|
||||
// // },
|
||||
// // })
|
||||
|
||||
// export const { setNavActive } = slice.actions
|
||||
|
||||
// // Other code such as selectors can use the imported `RootState` type
|
||||
// // export const selectCount = (state: RootState) => state.counter.value
|
||||
|
||||
// export default slice.reducer
|
@ -1,5 +0,0 @@
|
||||
import common from './common'
|
||||
|
||||
export default {
|
||||
common,
|
||||
}
|
@ -1,19 +0,0 @@
|
||||
import common from './common'
|
||||
// import * as search from './search'
|
||||
// import * as player from './player'
|
||||
// import * as list from './list'
|
||||
// import * as songList from './songList'
|
||||
// import * as top from './top'
|
||||
|
||||
// export {
|
||||
// common,
|
||||
// search,
|
||||
// player,
|
||||
// list,
|
||||
// songList,
|
||||
// top,
|
||||
// }
|
||||
|
||||
export default {
|
||||
...common,
|
||||
}
|
@ -1,89 +0,0 @@
|
||||
import music from '@/utils/musicSdk'
|
||||
import { deduplicationList } from '@/utils/tools'
|
||||
|
||||
export const TYPES = {
|
||||
loading: null,
|
||||
setText: null,
|
||||
addHistory: null,
|
||||
setList: null,
|
||||
setLists: null,
|
||||
clearList: null,
|
||||
removeHistory: null,
|
||||
clearHistory: null,
|
||||
setTipList: null,
|
||||
setVisibleTipList: null,
|
||||
}
|
||||
for (const key of Object.keys(TYPES)) {
|
||||
TYPES[key] = `search__${key}`
|
||||
}
|
||||
|
||||
const sources = []
|
||||
for (const source of music.sources) {
|
||||
const musicSearch = music[source.id].musicSearch
|
||||
if (!musicSearch) continue
|
||||
sources.push(source)
|
||||
}
|
||||
|
||||
export const search = ({ page, limit }) => (dispatch, getState) => {
|
||||
// dispatch({ type: TYPES.setText, payload: text })
|
||||
const state = getState()
|
||||
const text = state.search.text
|
||||
if (!text.length) {
|
||||
dispatch({ type: TYPES.clearList })
|
||||
return Promise.resolve()
|
||||
}
|
||||
dispatch({ type: TYPES.addHistory, payload: text })
|
||||
|
||||
|
||||
if (state.common.setting.search.searchSource == 'all') {
|
||||
const task = []
|
||||
for (const source of sources) {
|
||||
if (source.id == 'all') continue
|
||||
dispatch({ type: TYPES.loading, payload: true })
|
||||
task.push(music[source.id].musicSearch.search(text, page).catch(error => {
|
||||
console.log(error)
|
||||
return {
|
||||
allPage: 1,
|
||||
limit: 30,
|
||||
list: [],
|
||||
source: source.id,
|
||||
total: 0,
|
||||
}
|
||||
}))
|
||||
}
|
||||
return Promise.all(task).then(results => dispatch({ type: TYPES.setLists, payload: { results, page } }))
|
||||
.finally(() => dispatch({ type: TYPES.loading, payload: false }))
|
||||
} else {
|
||||
dispatch({ type: TYPES.loading, payload: true })
|
||||
return music[state.common.setting.search.searchSource].musicSearch.search(text, page, limit).catch(error => {
|
||||
console.log(error)
|
||||
return {
|
||||
allPage: 1,
|
||||
limit: 30,
|
||||
list: [],
|
||||
source: state.common.setting.search.searchSource,
|
||||
total: 0,
|
||||
}
|
||||
}).then(data => dispatch({ type: TYPES.setList, payload: { page, ...data, list: deduplicationList(data.list) } }))
|
||||
.finally(() => dispatch({ type: TYPES.loading, payload: false }))
|
||||
}
|
||||
}
|
||||
|
||||
export const setText = text => ({ type: TYPES.setText, payload: text })
|
||||
export const setTipList = list => ({ type: TYPES.setTipList, payload: list })
|
||||
export const setVisibleTipList = visible => ({ type: TYPES.setVisibleTipList, payload: visible })
|
||||
|
||||
export const clearList = () => ({
|
||||
type: TYPES.clearList,
|
||||
})
|
||||
export const addHistory = text => ({
|
||||
type: TYPES.addHistory,
|
||||
payload: text,
|
||||
})
|
||||
export const removeHistory = index => ({
|
||||
type: TYPES.addHistory,
|
||||
payload: index,
|
||||
})
|
||||
export const clearHistory = () => ({
|
||||
type: TYPES.addHistory,
|
||||
})
|
@ -1,33 +0,0 @@
|
||||
import { createSelector } from 'reselect'
|
||||
|
||||
|
||||
export const text = state => state.search.text
|
||||
export const sourceList = state => state.search.sourceList
|
||||
export const aggregationListInfo = state => state.search.aggregationListInfo
|
||||
export const isEnd = state => state.search.isEnd
|
||||
export const isLoading = state => state.search.isLoading
|
||||
|
||||
export const tipList = state => state.search.tipInfo.list
|
||||
export const tipListVisible = state => state.search.tipInfo.visible
|
||||
|
||||
|
||||
export const rawSources = state => state.search.sources
|
||||
export const tempSearchSource = state => state.common.setting.search.tempSearchSource
|
||||
export const searchSource = state => state.common.setting.search.searchSource
|
||||
|
||||
|
||||
export const sources = createSelector([rawSources], sources => {
|
||||
return sources.map(source => ({ label: source.name, id: source.id }))
|
||||
})
|
||||
|
||||
|
||||
export const currentSourceName = createSelector([rawSources, searchSource], (sources, searchSource) => {
|
||||
const source = sources.find(s => s.id == searchSource)
|
||||
return source ? source.name : 'unknown'
|
||||
})
|
||||
|
||||
export const listInfo = createSelector([searchSource, sourceList, aggregationListInfo], (searchSource, sourceList, aggregationListInfo) => {
|
||||
return searchSource == 'all'
|
||||
? aggregationListInfo
|
||||
: sourceList[searchSource]
|
||||
})
|
@ -1,5 +0,0 @@
|
||||
import * as action from './action'
|
||||
import * as getter from './getter'
|
||||
|
||||
export { action, getter }
|
||||
export { default as reducer } from './reducer'
|
@ -1,248 +0,0 @@
|
||||
import { TYPES } from './action'
|
||||
|
||||
import music from '@/utils/musicSdk'
|
||||
|
||||
let historyList
|
||||
if (historyList == null) {
|
||||
historyList = []
|
||||
// electronStore_data.set('searchHistoryList', historyList)
|
||||
}
|
||||
|
||||
const sources = []
|
||||
const sourceList = {}
|
||||
for (const source of music.sources) {
|
||||
const musicSearch = music[source.id].musicSearch
|
||||
if (!musicSearch) continue
|
||||
sources.push(source)
|
||||
sourceList[source.id] = {
|
||||
page: 1,
|
||||
maxPage: 0,
|
||||
limit: 30,
|
||||
total: 0,
|
||||
list: [],
|
||||
}
|
||||
}
|
||||
|
||||
// sources.push({
|
||||
// id: 'all',
|
||||
// name: '聚合搜索',
|
||||
// })
|
||||
|
||||
const initialState = {
|
||||
text: '',
|
||||
historyList,
|
||||
sources,
|
||||
isEnd: false,
|
||||
isLoading: false,
|
||||
sourceList,
|
||||
aggregationListInfo: {
|
||||
list: [],
|
||||
page: 1,
|
||||
limit: 30,
|
||||
maxPage: 1,
|
||||
total: 0,
|
||||
},
|
||||
tipInfo: {
|
||||
list: [],
|
||||
visible: false,
|
||||
},
|
||||
}
|
||||
|
||||
|
||||
// https://blog.csdn.net/xcxy2015/article/details/77164126#comments
|
||||
const similar = (a, b) => {
|
||||
if (!a || !b) return 0
|
||||
if (a.length > b.length) { // 保证 a <= b
|
||||
const t = b
|
||||
b = a
|
||||
a = t
|
||||
}
|
||||
const al = a.length
|
||||
const bl = b.length
|
||||
const mp = [] // 一个表
|
||||
let i, j, ai, lt, tmp // ai:字符串a的第i个字符。 lt:左上角的值。 tmp:暂存新的值。
|
||||
for (i = 0; i <= bl; i++) mp[i] = i
|
||||
for (i = 1; i <= al; i++) {
|
||||
ai = a.charAt(i - 1)
|
||||
lt = mp[0]
|
||||
mp[0] = mp[0] + 1
|
||||
for (j = 1; j <= bl; j++) {
|
||||
tmp = Math.min(mp[j] + 1, mp[j - 1] + 1, lt + (ai == b.charAt(j - 1) ? 0 : 1))
|
||||
lt = mp[j]
|
||||
mp[j] = tmp
|
||||
}
|
||||
}
|
||||
return 1 - (mp[bl] / bl)
|
||||
}
|
||||
|
||||
const sortInsert = (arr, data) => {
|
||||
const key = data.num
|
||||
let left = 0
|
||||
let right = arr.length - 1
|
||||
|
||||
while (left <= right) {
|
||||
const middle = parseInt((left + right) / 2)
|
||||
if (key == arr[middle]) {
|
||||
left = middle
|
||||
break
|
||||
} else if (key < arr[middle].num) {
|
||||
right = middle - 1
|
||||
} else {
|
||||
left = middle + 1
|
||||
}
|
||||
}
|
||||
while (left > 0) {
|
||||
if (arr[left - 1].num != key) break
|
||||
left--
|
||||
}
|
||||
|
||||
arr.splice(left, 0, data)
|
||||
}
|
||||
|
||||
const handleSortList = (list, keyword) => {
|
||||
const arr = []
|
||||
for (const item of list) {
|
||||
sortInsert(arr, {
|
||||
num: similar(keyword, `${item.name} ${item.singer}`),
|
||||
data: item,
|
||||
})
|
||||
}
|
||||
return arr.map(item => item.data).reverse()
|
||||
}
|
||||
|
||||
const filterList = list => {
|
||||
const set = new Set()
|
||||
for (let i = list.length - 1; i > -1; i--) {
|
||||
const item = list[i]
|
||||
if (set.has(item.songmid)) {
|
||||
list.splice(i, 1)
|
||||
} else {
|
||||
set.add(item.songmid)
|
||||
}
|
||||
}
|
||||
return list
|
||||
}
|
||||
|
||||
const mutations = {
|
||||
[TYPES.loading](state, isLoading) {
|
||||
return {
|
||||
...state,
|
||||
isLoading,
|
||||
}
|
||||
},
|
||||
[TYPES.setText](state, text) {
|
||||
return {
|
||||
...state,
|
||||
text,
|
||||
}
|
||||
},
|
||||
[TYPES.addHistory](state, text) {
|
||||
let historyList = [...state.historyList]
|
||||
const index = historyList.indexOf(text)
|
||||
if (index > -1) historyList.splice(index, 1)
|
||||
if (historyList.length >= 15) historyList = historyList.slice(0, 14)
|
||||
historyList.unshift(text)
|
||||
return {
|
||||
...state,
|
||||
historyList,
|
||||
}
|
||||
},
|
||||
[TYPES.setList](state, datas) {
|
||||
const source = { ...state.sourceList[datas.source] }
|
||||
source.list = datas.page > 1 ? filterList([...source.list, ...datas.list]) : datas.list
|
||||
source.total = datas.total
|
||||
source.maxPage = datas.allPage
|
||||
source.page = datas.page
|
||||
state.isEnd = datas.page >= source.maxPage
|
||||
// source.limit = datas.limit
|
||||
|
||||
return {
|
||||
...state,
|
||||
sourceList: {
|
||||
...state.sourceList,
|
||||
[datas.source]: source,
|
||||
},
|
||||
}
|
||||
},
|
||||
[TYPES.setLists](state, { results, page }) {
|
||||
const pages = []
|
||||
let total = 0
|
||||
// let limit = 0
|
||||
let maxPage = 1
|
||||
const list = []
|
||||
state = { ...state }
|
||||
const aggregationListInfo = { ...state.aggregationListInfo }
|
||||
for (const source of results) {
|
||||
if (source.allPage < page) continue
|
||||
list.push(...source.list)
|
||||
pages.push(source.allPage)
|
||||
total += source.total
|
||||
// limit = Math.max(source.limit, limit)
|
||||
maxPage = Math.max(source.allPage, maxPage)
|
||||
}
|
||||
aggregationListInfo.maxPage = Math.max(...pages)
|
||||
aggregationListInfo.total = total
|
||||
// aggregationListInfo.limit = limit
|
||||
aggregationListInfo.page = page
|
||||
aggregationListInfo.maxPage = maxPage
|
||||
aggregationListInfo.list = page > 1 ? filterList([...aggregationListInfo.list, ...handleSortList(list, state.text)]) : handleSortList(list, state.text)
|
||||
aggregationListInfo.isEnd = aggregationListInfo.maxPage >= page
|
||||
return state
|
||||
},
|
||||
[TYPES.clearList](state) {
|
||||
state = { ...state }
|
||||
state.sourceList = { ...state.sourceList }
|
||||
for (const source of Object.keys(state.sourceList)) {
|
||||
state.sourceList[source] = { ...state.sourceList[source] }
|
||||
state.sourceList[source].list = []
|
||||
state.sourceList[source].page = 0
|
||||
state.sourceList[source].maxPage = 1
|
||||
state.sourceList[source].total = 0
|
||||
}
|
||||
const aggregationListInfo = { ...state.aggregationListInfo }
|
||||
aggregationListInfo.list = []
|
||||
aggregationListInfo.page = 0
|
||||
aggregationListInfo.maxPage = 1
|
||||
aggregationListInfo.total = 0
|
||||
state.text = ''
|
||||
state.isEnd = false
|
||||
return state
|
||||
},
|
||||
[TYPES.removeHistory](state, index) {
|
||||
const historyList = [...state.historyList]
|
||||
historyList.splice(index, 1)
|
||||
return {
|
||||
...state,
|
||||
historyList,
|
||||
}
|
||||
},
|
||||
[TYPES.clearHistory](state) {
|
||||
return {
|
||||
...state,
|
||||
historyList: [],
|
||||
}
|
||||
},
|
||||
[TYPES.setTipList](state, list) {
|
||||
return {
|
||||
...state,
|
||||
tipInfo: {
|
||||
...state.tipInfo,
|
||||
list,
|
||||
},
|
||||
}
|
||||
},
|
||||
[TYPES.setVisibleTipList](state, visible) {
|
||||
return {
|
||||
...state,
|
||||
tipInfo: {
|
||||
...state.tipInfo,
|
||||
visible,
|
||||
},
|
||||
}
|
||||
},
|
||||
}
|
||||
|
||||
export default (state = initialState, action) =>
|
||||
mutations[action.type]
|
||||
? mutations[action.type](state, action.payload)
|
||||
: state
|
@ -1,235 +0,0 @@
|
||||
import music from '@/utils/musicSdk'
|
||||
import { deduplicationList } from '@/utils/tools'
|
||||
|
||||
const cache = new Map()
|
||||
|
||||
const LIST_LOAD_LIMIT = 30
|
||||
|
||||
export const TYPES = {
|
||||
setTags: null,
|
||||
setList: null,
|
||||
clearList: null,
|
||||
setListDetail: null,
|
||||
setVisibleListDetail: null,
|
||||
setSelectListInfo: null,
|
||||
setListLoading: null,
|
||||
setListDetailLoading: null,
|
||||
setListEnd: null,
|
||||
setListDetailEnd: null,
|
||||
setGetListDetailFailed: null,
|
||||
clearListDetail: null,
|
||||
}
|
||||
|
||||
for (const key of Object.keys(TYPES)) {
|
||||
TYPES[key] = `list__${key}`
|
||||
}
|
||||
|
||||
export const getTags = () => (dispatch, getState) => {
|
||||
const state = getState()
|
||||
let source = state.common.setting.songList.source
|
||||
if (state.songList.tags[source]) return Promise.resolve()
|
||||
return music[source].songList.getTags().then(result => dispatch(setTags({ tags: result, source })))
|
||||
}
|
||||
export const getList = ({ page = 1, isRefresh = false }) => (dispatch, getState) => {
|
||||
const allState = getState()
|
||||
const rootState = allState.common
|
||||
let source = rootState.setting.songList.source
|
||||
let tabId = rootState.setting.songList.tagInfo.id
|
||||
let sortId = rootState.setting.songList.sortId
|
||||
|
||||
let listKey = `slist__${source}__${sortId}__${tabId}`
|
||||
let pageKey = `slist__${source}__${sortId}__${tabId}__${page}`
|
||||
|
||||
if (isRefresh && cache.has(listKey)) cache.delete(listKey)
|
||||
if (!cache.has(listKey)) cache.set(listKey, new Map())
|
||||
|
||||
const listCache = cache.get(listKey)
|
||||
if (listCache.has(pageKey)) return Promise.resolve(listCache.get(pageKey)).then(result => dispatch(setList({ result, pageKey, listKey, page })))
|
||||
|
||||
dispatch(setListEnd(false))
|
||||
dispatch(setListLoading(true))
|
||||
return music[source]?.songList.getList(sortId, tabId, page).then(result => {
|
||||
dispatch(setList({ result, pageKey, listKey, page }))
|
||||
listCache.set(pageKey, result)
|
||||
}).finally(() => {
|
||||
const state = getState().songList
|
||||
if (state.list.pageKey != pageKey) return
|
||||
dispatch(setListLoading(false))
|
||||
})
|
||||
}
|
||||
|
||||
const getListDetailLimit = ({ source, id, page }) => {
|
||||
const listKey = `sdetail__${source}__${id}`
|
||||
const prevPageKey = `sdetail__${source}__${id}__${page - 1}`
|
||||
const tempListKey = `sdetail__${source}__${id}__temp`
|
||||
|
||||
const listCache = cache.get(listKey)
|
||||
let sourcePage = 0
|
||||
if (listCache.has(prevPageKey)) {
|
||||
sourcePage = listCache.get(prevPageKey).sourcePage
|
||||
}
|
||||
return music[source]?.songList.getListDetail(id, sourcePage + 1).then(result => {
|
||||
let p = page
|
||||
if (listCache.has(tempListKey)) {
|
||||
const list = listCache.get(tempListKey)
|
||||
listCache.delete(tempListKey)
|
||||
listCache.set(`sdetail__${source}__${id}__${p}`, {
|
||||
data: {
|
||||
...result,
|
||||
list: [...list, ...result.list.splice(0, LIST_LOAD_LIMIT - list.length)],
|
||||
page: p,
|
||||
limit: LIST_LOAD_LIMIT,
|
||||
},
|
||||
sourcePage,
|
||||
})
|
||||
p++
|
||||
}
|
||||
sourcePage++
|
||||
do {
|
||||
if (result.list.length < LIST_LOAD_LIMIT && sourcePage < Math.ceil(result.total / result.limit)) {
|
||||
listCache.set(tempListKey, result.list.splice(0, LIST_LOAD_LIMIT))
|
||||
break
|
||||
}
|
||||
listCache.set(`sdetail__${source}__${id}__${p}`, {
|
||||
data: {
|
||||
...result,
|
||||
list: result.list.splice(0, LIST_LOAD_LIMIT),
|
||||
page: p,
|
||||
limit: LIST_LOAD_LIMIT,
|
||||
},
|
||||
sourcePage,
|
||||
})
|
||||
p++
|
||||
} while (result.list.length > 0)
|
||||
return listCache.get(`sdetail__${source}__${id}__${page}`).data
|
||||
})
|
||||
}
|
||||
|
||||
export const getListDetail = ({ id, page, isRefresh = false }) => (dispatch, getState) => {
|
||||
const allState = getState()
|
||||
const rootState = allState.common
|
||||
let source = rootState.setting.songList.source
|
||||
let listKey = `sdetail__${source}__${id}`
|
||||
let pageKey = `sdetail__${source}__${id}__${page}`
|
||||
|
||||
if (isRefresh && cache.has(listKey)) cache.delete(listKey)
|
||||
if (!cache.has(listKey)) cache.set(listKey, new Map())
|
||||
|
||||
dispatch(setGetListDetailFailed(false))
|
||||
const listCache = cache.get(listKey)
|
||||
if (listCache.has(pageKey)) {
|
||||
return Promise.resolve(listCache.get(pageKey).data).then(result => dispatch(setListDetail({ result, listKey, pageKey, source, id, page })))
|
||||
}
|
||||
|
||||
dispatch(setListDetailEnd(false))
|
||||
dispatch(setListDetailLoading(true))
|
||||
return getListDetailLimit({ source, id, page }).then(result => {
|
||||
dispatch(setListDetail({ result, listKey, pageKey, source, id, page }))
|
||||
// listCache.set(pageKey, result)
|
||||
}).catch(err => {
|
||||
console.log(err)
|
||||
if (page == 1) {
|
||||
dispatch(setGetListDetailFailed(true))
|
||||
}
|
||||
return Promise.reject(err)
|
||||
}).finally(() => {
|
||||
const state = getState().songList
|
||||
if (state.listDetail.pageKey != pageKey) return
|
||||
dispatch(setListDetailLoading(false))
|
||||
})
|
||||
}
|
||||
|
||||
export const getListDetailAll = ({ source, id, isRefresh = false }) => (dispatch, getState) => {
|
||||
let listKey = `sdetail__${source}__${id}`
|
||||
if (isRefresh && cache.has(listKey)) cache.delete(listKey)
|
||||
if (!cache.has(listKey)) cache.set(listKey, new Map())
|
||||
const listCache = cache.get(listKey)
|
||||
const loadData = (id, page) => {
|
||||
let pageKey = `sdetail__${source}__${id}__${page}`
|
||||
return listCache.has(pageKey)
|
||||
? Promise.resolve(listCache.get(pageKey).data)
|
||||
: getListDetailLimit({ source, id, page }).then(result => {
|
||||
// listCache.set(pageKey, result)
|
||||
return result
|
||||
})
|
||||
}
|
||||
return loadData(id, 1).then(result => {
|
||||
if (result.total <= result.limit) return result.list
|
||||
|
||||
let maxPage = Math.ceil(result.total / result.limit)
|
||||
const loadDetail = (loadPage = 2) => {
|
||||
return loadPage == maxPage
|
||||
? loadData(id, loadPage).then(result => result.list)
|
||||
: loadData(id, loadPage).then(result1 => loadDetail(++loadPage).then(result2 => [...result1.list, ...result2]))
|
||||
}
|
||||
return loadDetail().then(result2 => [...result.list, ...result2])
|
||||
}).then(list => deduplicationList(list))
|
||||
}
|
||||
|
||||
export const setVisibleListDetail = isShow => {
|
||||
return {
|
||||
type: TYPES.setVisibleListDetail,
|
||||
payload: isShow,
|
||||
}
|
||||
}
|
||||
export const setSelectListInfo = info => (dispatch, getState) => {
|
||||
dispatch({
|
||||
type: TYPES.setSelectListInfo,
|
||||
payload: info,
|
||||
})
|
||||
dispatch({
|
||||
type: TYPES.clearListDetail,
|
||||
})
|
||||
}
|
||||
export const setGetListDetailFailed = isFailed => {
|
||||
return {
|
||||
type: TYPES.setGetListDetailFailed,
|
||||
payload: isFailed,
|
||||
}
|
||||
}
|
||||
export const setTags = ({ tags, source }) => {
|
||||
return {
|
||||
type: TYPES.setTags,
|
||||
payload: { tags, source },
|
||||
}
|
||||
}
|
||||
export const setList = ({ result, pageKey, listKey, page }) => {
|
||||
return {
|
||||
type: TYPES.setList,
|
||||
payload: { result, pageKey, listKey, page },
|
||||
}
|
||||
}
|
||||
export const clearList = () => {
|
||||
return { type: TYPES.clearList }
|
||||
}
|
||||
export const setListLoading = isLoading => {
|
||||
return {
|
||||
type: TYPES.setListLoading,
|
||||
payload: isLoading,
|
||||
}
|
||||
}
|
||||
export const setListDetailLoading = isLoading => {
|
||||
return {
|
||||
type: TYPES.setListDetailLoading,
|
||||
payload: isLoading,
|
||||
}
|
||||
}
|
||||
export const setListEnd = isEnd => {
|
||||
return {
|
||||
type: TYPES.setListEnd,
|
||||
payload: isEnd,
|
||||
}
|
||||
}
|
||||
export const setListDetailEnd = isEnd => {
|
||||
return {
|
||||
type: TYPES.setListDetailEnd,
|
||||
payload: isEnd,
|
||||
}
|
||||
}
|
||||
|
||||
export const setListDetail = ({ result, pageKey, listKey, source, id, page }) => {
|
||||
return {
|
||||
type: TYPES.setListDetail,
|
||||
payload: { result, pageKey, listKey, source, id, page },
|
||||
}
|
||||
}
|
@ -1,32 +0,0 @@
|
||||
import { createSelector } from 'reselect'
|
||||
|
||||
|
||||
// sourceInfo(state, getters, rootState, { sourceNames }) {
|
||||
// return { sources: sources.map(item => ({ id: item.id, name: sourceNames[item.id] })), sortList }
|
||||
// },
|
||||
// tags: state => state.tags,
|
||||
// isVisibleListDetail: state => state.isVisibleListDetail,
|
||||
|
||||
export const rawSources = state => state.songList.sources
|
||||
|
||||
export const sortList = state => state.songList.sortList
|
||||
|
||||
export const tags = state => state.songList.tags
|
||||
|
||||
export const isVisibleListDetail = state => state.songList.isVisibleListDetail
|
||||
export const isGetListDetailFailed = state => state.songList.isGetListDetailFailed
|
||||
export const selectListInfo = state => state.songList.selectListInfo
|
||||
export const listData = state => state.songList.list
|
||||
export const listDetailData = state => state.songList.listDetail
|
||||
|
||||
export const listInfo = state => state.songList.list
|
||||
export const listDetailInfo = state => state.songList.listDetail
|
||||
|
||||
export const songListSource = state => state.common.setting.songList.source
|
||||
export const songListSortId = state => state.common.setting.songList.sortId
|
||||
export const songListTagInfo = state => state.common.setting.songList.tagInfo
|
||||
|
||||
export const sources = createSelector([rawSources], sources => {
|
||||
return sources.map(source => ({ label: source.name, id: source.id }))
|
||||
})
|
||||
|
@ -1,5 +0,0 @@
|
||||
import * as action from './action'
|
||||
import * as getter from './getter'
|
||||
|
||||
export { action, getter }
|
||||
export { default as reducer } from './reducer'
|
@ -1,191 +0,0 @@
|
||||
import { TYPES } from './action'
|
||||
import music from '@/utils/musicSdk'
|
||||
import { deduplicationList } from '@/utils/tools'
|
||||
const sortList = {}
|
||||
const sources = []
|
||||
for (const source of music.sources) {
|
||||
const songList = music[source.id].songList
|
||||
if (!songList) continue
|
||||
sortList[source.id] = songList.sortList
|
||||
sources.push(source)
|
||||
}
|
||||
// state
|
||||
const initialState = {
|
||||
sources,
|
||||
sortList,
|
||||
tags: {},
|
||||
list: {
|
||||
list: [],
|
||||
total: 0,
|
||||
page: 1,
|
||||
limit: 30,
|
||||
listKey: null,
|
||||
pageKey: null,
|
||||
isLoading: false,
|
||||
isEnd: false,
|
||||
},
|
||||
listDetail: {
|
||||
list: [],
|
||||
desc: null,
|
||||
total: 0,
|
||||
page: 1,
|
||||
limit: 30,
|
||||
info: {},
|
||||
listKey: null,
|
||||
pageKey: null,
|
||||
isLoading: false,
|
||||
isEnd: false,
|
||||
},
|
||||
selectListInfo: {},
|
||||
isVisibleListDetail: false,
|
||||
isGetListDetailFailed: false,
|
||||
}
|
||||
|
||||
sources.forEach(source => {
|
||||
initialState.tags[source.id] = null
|
||||
})
|
||||
|
||||
const mutations = {
|
||||
[TYPES.setTags](state, { tags, source }) {
|
||||
return {
|
||||
...state,
|
||||
tags: { ...state.tags, [source]: tags },
|
||||
}
|
||||
},
|
||||
[TYPES.clearList](state) {
|
||||
return {
|
||||
...state,
|
||||
list: {
|
||||
...state.list,
|
||||
list: [],
|
||||
total: 0,
|
||||
page: 1,
|
||||
pageKey: null,
|
||||
listKey: null,
|
||||
isLoading: false,
|
||||
isEnd: false,
|
||||
},
|
||||
}
|
||||
},
|
||||
[TYPES.setList](state, { result, pageKey, listKey, page }) {
|
||||
if (pageKey == state.list.pageKey && state.list.list.length) return state
|
||||
return {
|
||||
...state,
|
||||
list: {
|
||||
...state.list,
|
||||
list: listKey == state.list.listKey && page != 1 ? [...state.list.list, ...result.list] : result.list,
|
||||
total: result.total,
|
||||
limit: result.limit,
|
||||
page,
|
||||
pageKey,
|
||||
listKey,
|
||||
isEnd: page >= Math.ceil(result.total / result.limit),
|
||||
},
|
||||
}
|
||||
},
|
||||
[TYPES.setListDetail](state, { result, pageKey, listKey, source, id, page }) {
|
||||
return {
|
||||
...state,
|
||||
listDetail: {
|
||||
...state.listDetail,
|
||||
list: deduplicationList(listKey == state.listDetail.listKey && page != 1 ? [...state.listDetail.list, ...result.list] : result.list),
|
||||
id,
|
||||
source,
|
||||
total: result.total,
|
||||
limit: result.limit,
|
||||
page,
|
||||
pageKey,
|
||||
listKey,
|
||||
isEnd: page >= Math.ceil(result.total / result.limit),
|
||||
info: result.info || {
|
||||
name: state.selectListInfo.name,
|
||||
img: state.selectListInfo.img,
|
||||
desc: state.selectListInfo.desc,
|
||||
author: state.selectListInfo.author,
|
||||
play_count: state.selectListInfo.play_count,
|
||||
},
|
||||
},
|
||||
}
|
||||
},
|
||||
[TYPES.setVisibleListDetail](state, bool) {
|
||||
const newState = {
|
||||
...state,
|
||||
isVisibleListDetail: bool,
|
||||
}
|
||||
if (!bool) newState.listDetail = { ...newState.listDetail, list: [] }
|
||||
return newState
|
||||
},
|
||||
[TYPES.setSelectListInfo](state, info) {
|
||||
return {
|
||||
...state,
|
||||
selectListInfo: info,
|
||||
}
|
||||
},
|
||||
[TYPES.clearListDetail](state) {
|
||||
return {
|
||||
...state,
|
||||
listDetail: {
|
||||
...state.listDetail,
|
||||
id: null,
|
||||
source: null,
|
||||
list: [],
|
||||
desc: null,
|
||||
total: 0,
|
||||
page: 1,
|
||||
limit: 30,
|
||||
pageKey: null,
|
||||
listKey: null,
|
||||
isLoading: false,
|
||||
isEnd: false,
|
||||
info: {},
|
||||
},
|
||||
}
|
||||
},
|
||||
[TYPES.setGetListDetailFailed](state, isFailed) {
|
||||
return {
|
||||
...state,
|
||||
isGetListDetailFailed: isFailed,
|
||||
}
|
||||
},
|
||||
[TYPES.setListLoading](state, isLoading) {
|
||||
return {
|
||||
...state,
|
||||
list: {
|
||||
...state.list,
|
||||
isLoading,
|
||||
},
|
||||
}
|
||||
},
|
||||
[TYPES.setListDetailLoading](state, isLoading) {
|
||||
return {
|
||||
...state,
|
||||
listDetail: {
|
||||
...state.listDetail,
|
||||
isLoading,
|
||||
},
|
||||
}
|
||||
},
|
||||
[TYPES.setListEnd](state, isEnd) {
|
||||
return {
|
||||
...state,
|
||||
list: {
|
||||
...state.list,
|
||||
isEnd,
|
||||
},
|
||||
}
|
||||
},
|
||||
[TYPES.setListDetailEnd](state, isEnd) {
|
||||
return {
|
||||
...state,
|
||||
listDetail: {
|
||||
...state.listDetail,
|
||||
isEnd,
|
||||
},
|
||||
}
|
||||
},
|
||||
}
|
||||
|
||||
export default (state = initialState, action) => mutations[action.type]
|
||||
? mutations[action.type](state, action.payload)
|
||||
: state
|
||||
|
@ -1,161 +0,0 @@
|
||||
import music from '@/utils/musicSdk'
|
||||
import { deduplicationList } from '@/utils/tools'
|
||||
|
||||
const cache = new Map()
|
||||
const LIST_LOAD_LIMIT = 30
|
||||
|
||||
export const TYPES = {
|
||||
setBoardsList: null,
|
||||
setList: null,
|
||||
clearList: null,
|
||||
setListLoading: null,
|
||||
setListEnd: null,
|
||||
}
|
||||
|
||||
for (const key of Object.keys(TYPES)) {
|
||||
TYPES[key] = `top__${key}`
|
||||
}
|
||||
|
||||
export const getBoardsList = () => (dispatch, getState) => {
|
||||
const state = getState()
|
||||
let source = state.common.setting.leaderboard.source
|
||||
// let tabId = rootState.setting.leaderboard.tabId
|
||||
// let key = `${source}${tabId}${page}`
|
||||
// if (state.list.length && state.key == key) return true
|
||||
// commit('clearList')
|
||||
if (state.top.boards[source].length) return Promise.resolve()
|
||||
return music[source].leaderboard.getBoards().then(result => dispatch(setBoardsList({ boards: result, source })))
|
||||
}
|
||||
|
||||
const getListLimit = ({ source, tabId, bangId, page }) => {
|
||||
const listKey = `${source}__${tabId}`
|
||||
const prevPageKey = `${source}__${tabId}__${page - 1}`
|
||||
const tempListKey = `${source}__${tabId}__temp`
|
||||
|
||||
const listCache = cache.get(listKey)
|
||||
let sourcePage = 0
|
||||
if (listCache.has(prevPageKey)) {
|
||||
sourcePage = listCache.get(prevPageKey).sourcePage
|
||||
}
|
||||
return music[source].leaderboard.getList(bangId, sourcePage + 1).then(result => {
|
||||
let p = page
|
||||
if (listCache.has(tempListKey)) {
|
||||
const list = listCache.get(tempListKey)
|
||||
listCache.delete(tempListKey)
|
||||
listCache.set(`${source}__${tabId}__${p}`, {
|
||||
data: {
|
||||
...result,
|
||||
list: [...list, ...result.list.splice(0, LIST_LOAD_LIMIT - list.length)],
|
||||
page: p,
|
||||
limit: LIST_LOAD_LIMIT,
|
||||
},
|
||||
sourcePage,
|
||||
})
|
||||
p++
|
||||
}
|
||||
sourcePage++
|
||||
do {
|
||||
if (result.list.length < LIST_LOAD_LIMIT && sourcePage < Math.ceil(result.total / result.limit)) {
|
||||
listCache.set(tempListKey, result.list.splice(0, LIST_LOAD_LIMIT))
|
||||
break
|
||||
}
|
||||
listCache.set(`${source}__${tabId}__${p}`, {
|
||||
data: {
|
||||
...result,
|
||||
list: result.list.splice(0, LIST_LOAD_LIMIT),
|
||||
page: p,
|
||||
limit: LIST_LOAD_LIMIT,
|
||||
},
|
||||
sourcePage,
|
||||
})
|
||||
p++
|
||||
} while (result.list.length > 0)
|
||||
return listCache.get(`${source}__${tabId}__${page}`).data
|
||||
})
|
||||
}
|
||||
|
||||
export const getList = ({ page, isRefresh = false }) => (dispatch, getState) => {
|
||||
const state = getState()
|
||||
let tabId = state.common.setting.leaderboard.tabId
|
||||
if (tabId == null) return Promise.resolve()
|
||||
// console.log(tabId)
|
||||
const [source, bangId] = tabId.split('__')
|
||||
const listKey = `${source}__${tabId}`
|
||||
const pageKey = `${source}__${tabId}__${page}`
|
||||
|
||||
if (isRefresh && cache.has(listKey)) cache.delete(listKey)
|
||||
if (!cache.has(listKey)) cache.set(listKey, new Map())
|
||||
|
||||
const listCache = cache.get(listKey)
|
||||
if (listCache.has(pageKey)) {
|
||||
return Promise.resolve(listCache.get(pageKey).data).then(result => dispatch(setList({ result, listKey, pageKey, page })))
|
||||
}
|
||||
|
||||
dispatch(setListEnd(false))
|
||||
dispatch(setListLoading(true))
|
||||
return getListLimit({ source, tabId, bangId, page }).then(result => {
|
||||
dispatch(setList({ result, listKey, pageKey, page }))
|
||||
// listCache.set(pageKey, result)
|
||||
}).finally(() => {
|
||||
const state = getState().top
|
||||
if (state.listInfo.pageKey != pageKey) return
|
||||
dispatch(setListLoading(false))
|
||||
})
|
||||
}
|
||||
|
||||
export const getListAll = ({ id: tabId, isRefresh = false }) => (dispatch, getState) => {
|
||||
// console.log(tabId)
|
||||
const [source, bangId] = tabId.split('__')
|
||||
const listKey = `${source}__${tabId}`
|
||||
if (isRefresh && cache.has(listKey)) cache.delete(listKey)
|
||||
if (!cache.has(listKey)) cache.set(listKey, new Map())
|
||||
const listCache = cache.get(listKey)
|
||||
const loadData = (bangId, page) => {
|
||||
const pageKey = `${source}__${tabId}__${page}`
|
||||
return listCache.has(pageKey)
|
||||
? Promise.resolve(listCache.get(pageKey).data)
|
||||
: getListLimit({ source, tabId, bangId, page }).then(result => {
|
||||
// listCache.set(pageKey, result)
|
||||
return result
|
||||
})
|
||||
}
|
||||
return loadData(bangId, 1).then(result => {
|
||||
if (result.total <= result.limit) return result.list
|
||||
|
||||
let maxPage = Math.ceil(result.total / result.limit)
|
||||
const loadDetail = (loadPage = 2) => {
|
||||
return loadPage == maxPage
|
||||
? loadData(bangId, loadPage).then(result => result.list)
|
||||
: loadData(bangId, loadPage).then(result1 => loadDetail(++loadPage).then(result2 => [...result1.list, ...result2]))
|
||||
}
|
||||
return loadDetail().then(result2 => [...result.list, ...result2])
|
||||
}).then(list => deduplicationList(list))
|
||||
}
|
||||
|
||||
export const setBoardsList = ({ boards, source }) => {
|
||||
return {
|
||||
type: TYPES.setBoardsList,
|
||||
payload: { boards, source },
|
||||
}
|
||||
}
|
||||
export const setList = ({ result, pageKey, listKey, page }) => {
|
||||
return {
|
||||
type: TYPES.setList,
|
||||
payload: { result, pageKey, listKey, page },
|
||||
}
|
||||
}
|
||||
export const clearList = () => {
|
||||
return { type: TYPES.clearList }
|
||||
}
|
||||
export const setListLoading = isLoading => {
|
||||
return {
|
||||
type: TYPES.setListLoading,
|
||||
payload: isLoading,
|
||||
}
|
||||
}
|
||||
export const setListEnd = isEnd => {
|
||||
return {
|
||||
type: TYPES.setListEnd,
|
||||
payload: isEnd,
|
||||
}
|
||||
}
|
@ -1,24 +0,0 @@
|
||||
import { createSelector } from 'reselect'
|
||||
|
||||
|
||||
// sourceInfo(state, getters, rootState, { sourceNames }) {
|
||||
// return { sources: sources.map(item => ({ id: item.id, name: sourceNames[item.id] })), sortList }
|
||||
// },
|
||||
// tags: state => state.tags,
|
||||
// isVisibleListDetail: state => state.isVisibleListDetail,
|
||||
|
||||
export const rawSources = state => state.top.sources
|
||||
|
||||
export const boards = state => state.top.boards
|
||||
|
||||
export const listInfo = state => state.top.listInfo
|
||||
export const isEnd = state => state.top.isEnd
|
||||
export const isLoading = state => state.top.isLoading
|
||||
|
||||
export const sourceId = state => state.common.setting.leaderboard.source
|
||||
export const tabId = state => state.common.setting.leaderboard.tabId
|
||||
|
||||
export const sources = createSelector([rawSources], sources => {
|
||||
return sources.map(source => ({ label: source.name, id: source.id }))
|
||||
})
|
||||
|
@ -1,5 +0,0 @@
|
||||
import * as action from './action'
|
||||
import * as getter from './getter'
|
||||
|
||||
export { action, getter }
|
||||
export { default as reducer } from './reducer'
|
@ -1,84 +0,0 @@
|
||||
import { TYPES } from './action'
|
||||
import music from '@/utils/musicSdk'
|
||||
import { deduplicationList } from '@/utils/tools'
|
||||
|
||||
const sourceList = {}
|
||||
const sources = []
|
||||
for (const source of music.sources) {
|
||||
const leaderboard = music[source.id].leaderboard
|
||||
if (!leaderboard || !leaderboard.getBoards) continue
|
||||
sourceList[source.id] = []
|
||||
sources.push(source)
|
||||
}
|
||||
|
||||
// state
|
||||
const initialState = {
|
||||
sources,
|
||||
boards: sourceList,
|
||||
listInfo: {
|
||||
list: [],
|
||||
total: 0,
|
||||
page: 1,
|
||||
limit: 30,
|
||||
listKey: null,
|
||||
pageKey: null,
|
||||
},
|
||||
isLoading: false,
|
||||
isEnd: false,
|
||||
}
|
||||
|
||||
const mutations = {
|
||||
[TYPES.setBoardsList](state, { boards, source }) {
|
||||
return {
|
||||
...state,
|
||||
boards: { ...state.boards, [source]: boards.list },
|
||||
}
|
||||
},
|
||||
[TYPES.clearList](state) {
|
||||
return {
|
||||
...state,
|
||||
listInfo: {
|
||||
...state.listInfo,
|
||||
list: [],
|
||||
total: 0,
|
||||
page: 1,
|
||||
pageKey: null,
|
||||
listKey: null,
|
||||
},
|
||||
isLoading: false,
|
||||
isEnd: false,
|
||||
}
|
||||
},
|
||||
[TYPES.setList](state, { result, pageKey, listKey, page }) {
|
||||
return {
|
||||
...state,
|
||||
listInfo: {
|
||||
...state.listInfo,
|
||||
list: deduplicationList(listKey == state.listInfo.listKey && page != 1 ? [...state.listInfo.list, ...result.list] : result.list),
|
||||
total: result.total,
|
||||
limit: result.limit,
|
||||
page,
|
||||
pageKey,
|
||||
listKey,
|
||||
},
|
||||
isEnd: page >= Math.ceil(result.total / result.limit),
|
||||
}
|
||||
},
|
||||
[TYPES.setListLoading](state, isLoading) {
|
||||
return {
|
||||
...state,
|
||||
isLoading,
|
||||
}
|
||||
},
|
||||
[TYPES.setListEnd](state, isEnd) {
|
||||
return {
|
||||
...state,
|
||||
isEnd,
|
||||
}
|
||||
},
|
||||
}
|
||||
|
||||
export default (state = initialState, action) => mutations[action.type]
|
||||
? mutations[action.type](state, action.payload)
|
||||
: state
|
||||
|
@ -5,7 +5,7 @@ import settingState from '@/store/setting/state'
|
||||
import themeState from '@/store/theme/state'
|
||||
import { isUrl } from '@/utils'
|
||||
import { externalDirectoryPath } from '@/utils/fs'
|
||||
import { ImageSourcePropType } from 'react-native'
|
||||
import { type ImageSourcePropType } from 'react-native'
|
||||
|
||||
export const BG_IMAGES = {
|
||||
'china_ink.jpg': require('./images/china_ink.jpg') as ImageSourcePropType,
|
||||
|
Loading…
x
Reference in New Issue
Block a user