mirror of
https://github.com/ikun0014/lx-music-mobile.git
synced 2025-07-04 05:02:11 +08:00
新增我的列表中已收藏的在线列表的更新功能
This commit is contained in:
parent
114f220da9
commit
dc26be3651
@ -20,7 +20,7 @@
|
|||||||
|
|
||||||
"list_rename": "Rename",
|
"list_rename": "Rename",
|
||||||
"list_rename_title": "Rename List",
|
"list_rename_title": "Rename List",
|
||||||
"list_sync": "Sync list",
|
"list_sync": "Update",
|
||||||
"change_position": "Change Position",
|
"change_position": "Change Position",
|
||||||
"change_position_tip": "Please enter a new position",
|
"change_position_tip": "Please enter a new position",
|
||||||
"change_position_list_title": "Change the position of the list",
|
"change_position_list_title": "Change the position of the list",
|
||||||
|
@ -20,7 +20,7 @@
|
|||||||
|
|
||||||
"list_rename": "重命名",
|
"list_rename": "重命名",
|
||||||
"list_rename_title": "重命名列表",
|
"list_rename_title": "重命名列表",
|
||||||
"list_sync": "同步列表",
|
"list_sync": "更新",
|
||||||
"change_position": "调整位置",
|
"change_position": "调整位置",
|
||||||
"change_position_tip": "请输入新的位置",
|
"change_position_tip": "请输入新的位置",
|
||||||
"change_position_list_title": "调整列表位置",
|
"change_position_list_title": "调整列表位置",
|
||||||
|
@ -12,21 +12,22 @@ import ConfirmAlert from '@/components/common/ConfirmAlert'
|
|||||||
import Input from '@/components/common/Input'
|
import Input from '@/components/common/Input'
|
||||||
import { getListScrollPosition, saveListScrollPosition } from '@/utils/tools'
|
import { getListScrollPosition, saveListScrollPosition } from '@/utils/tools'
|
||||||
import { LIST_SCROLL_POSITION_KEY } from '@/config/constant'
|
import { LIST_SCROLL_POSITION_KEY } from '@/config/constant'
|
||||||
|
import musicSdk from '@/utils/music'
|
||||||
|
|
||||||
const ListItem = ({ onPress, name, id, showMenu, activeId }) => {
|
const ListItem = ({ onPress, name, id, showMenu, activeId, loading, index }) => {
|
||||||
const theme = useGetter('common', 'theme')
|
const theme = useGetter('common', 'theme')
|
||||||
const moreButtonRef = useRef()
|
const moreButtonRef = useRef()
|
||||||
const handleShowMenu = useCallback(() => {
|
const handleShowMenu = useCallback(() => {
|
||||||
if (moreButtonRef.current && moreButtonRef.current.measure) {
|
if (moreButtonRef.current && moreButtonRef.current.measure) {
|
||||||
moreButtonRef.current.measure((fx, fy, width, height, px, py) => {
|
moreButtonRef.current.measure((fx, fy, width, height, px, py) => {
|
||||||
// console.log(fx, fy, width, height, px, py)
|
// console.log(fx, fy, width, height, px, py)
|
||||||
showMenu(id, name, { x: Math.ceil(px), y: Math.ceil(py), w: Math.ceil(width), h: Math.ceil(height) })
|
showMenu(id, name, index, { x: Math.ceil(px), y: Math.ceil(py), w: Math.ceil(width), h: Math.ceil(height) })
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}, [showMenu, id, name])
|
}, [showMenu, id, name, index])
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<View style={{ ...styles.listItem, borderBottomColor: theme.secondary45 }}>
|
<View style={{ ...styles.listItem, borderBottomColor: theme.secondary45, opacity: loading ? 0.5 : 1 }}>
|
||||||
<TouchableOpacity style={styles.listName} onPress={onPress}>
|
<TouchableOpacity style={styles.listName} onPress={onPress}>
|
||||||
<Text numberOfLines={1} style={{ color: theme.normal }}>{name}</Text>
|
<Text numberOfLines={1} style={{ color: theme.normal }}>{name}</Text>
|
||||||
</TouchableOpacity>
|
</TouchableOpacity>
|
||||||
@ -37,7 +38,7 @@ const ListItem = ({ onPress, name, id, showMenu, activeId }) => {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
const List = memo(({ setVisiblePanel, currentList, activeListIdRef }) => {
|
const List = memo(({ setVisiblePanel, currentList, activeListIdRef, handleCancelMultiSelect }) => {
|
||||||
const theme = useGetter('common', 'theme')
|
const theme = useGetter('common', 'theme')
|
||||||
const defaultList = useGetter('list', 'defaultList')
|
const defaultList = useGetter('list', 'defaultList')
|
||||||
const loveList = useGetter('list', 'loveList')
|
const loveList = useGetter('list', 'loveList')
|
||||||
@ -49,12 +50,17 @@ const List = memo(({ setVisiblePanel, currentList, activeListIdRef }) => {
|
|||||||
const removeUserList = useDispatch('list', 'removeUserList')
|
const removeUserList = useDispatch('list', 'removeUserList')
|
||||||
const [visibleMenu, setVisibleMenu] = useState(false)
|
const [visibleMenu, setVisibleMenu] = useState(false)
|
||||||
// const activeListId = useGetter('common', 'prevSelectListId')
|
// const activeListId = useGetter('common', 'prevSelectListId')
|
||||||
|
const [selectedListIndex, setSelectedListIndex] = useState(-1)
|
||||||
const selectedListRef = useRef({})
|
const selectedListRef = useRef({})
|
||||||
const { t } = useTranslation()
|
const { t } = useTranslation()
|
||||||
const [buttonPosition, setButtonPosition] = useState({ w: 0, h: 0, x: 0, y: 0 })
|
const [buttonPosition, setButtonPosition] = useState({ w: 0, h: 0, x: 0, y: 0 })
|
||||||
const [visibleRename, setVisibleRename] = useState(false)
|
const [visibleRename, setVisibleRename] = useState(false)
|
||||||
const [listNameText, setListNameText] = useState('')
|
const [listNameText, setListNameText] = useState('')
|
||||||
const scrollViewRef = useRef()
|
const scrollViewRef = useRef()
|
||||||
|
const setList = useDispatch('list', 'setList')
|
||||||
|
const getBoardListAll = useDispatch('top', 'getListAll')
|
||||||
|
const getListDetailAll = useDispatch('songList', 'getListDetailAll')
|
||||||
|
const [fetchingListStatus, setFetchingListStatus] = useState({})
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
userListRef.current = userList
|
userListRef.current = userList
|
||||||
@ -70,29 +76,46 @@ const List = memo(({ setVisiblePanel, currentList, activeListIdRef }) => {
|
|||||||
removeUserList(id)
|
removeUserList(id)
|
||||||
}, [activeListIdRef, userList, removeUserList, setPrevSelectListId])
|
}, [activeListIdRef, userList, removeUserList, setPrevSelectListId])
|
||||||
|
|
||||||
const showMenu = useCallback((id, name, position) => {
|
|
||||||
// console.log(position)
|
|
||||||
if (id == 'default' || id == 'love') return
|
|
||||||
setButtonPosition({ ...position })
|
|
||||||
selectedListRef.current.id = id
|
|
||||||
selectedListRef.current.name = name
|
|
||||||
setVisibleMenu(true)
|
|
||||||
}, [setButtonPosition])
|
|
||||||
const hideMenu = useCallback(() => {
|
const hideMenu = useCallback(() => {
|
||||||
setVisibleMenu(false)
|
setVisibleMenu(false)
|
||||||
}, [setVisibleMenu])
|
}, [setVisibleMenu])
|
||||||
|
const fetchList = useCallback((id, source, sourceListId) => {
|
||||||
|
setFetchingListStatus(fetchingListStatus => ({ ...fetchingListStatus, [id]: true }))
|
||||||
|
// console.log(sourceListId)
|
||||||
|
let promise
|
||||||
|
if (/board__/.test(sourceListId)) {
|
||||||
|
const id = sourceListId.replace(/board__/, '')
|
||||||
|
promise = getBoardListAll(id)
|
||||||
|
} else {
|
||||||
|
promise = getListDetailAll({ source, id: sourceListId })
|
||||||
|
}
|
||||||
|
return promise.finally(() => {
|
||||||
|
setFetchingListStatus(fetchingListStatus => ({ ...fetchingListStatus, [id]: false }))
|
||||||
|
})
|
||||||
|
}, [getBoardListAll, getListDetailAll])
|
||||||
|
const handleSyncSourceList = useCallback(async index => {
|
||||||
|
const targetListInfo = userList[index]
|
||||||
|
const list = await fetchList(targetListInfo.id, targetListInfo.source, targetListInfo.sourceListId)
|
||||||
|
// console.log(targetListInfo.list.length, list.length)
|
||||||
|
handleCancelMultiSelect()
|
||||||
|
setList({
|
||||||
|
...targetListInfo,
|
||||||
|
list,
|
||||||
|
})
|
||||||
|
}, [fetchList, handleCancelMultiSelect, setList, userList])
|
||||||
const handleMenuPress = useCallback(({ action }) => {
|
const handleMenuPress = useCallback(({ action }) => {
|
||||||
switch (action) {
|
switch (action) {
|
||||||
case 'rename':
|
case 'rename':
|
||||||
setListNameText(selectedListRef.current.name)
|
setListNameText(selectedListRef.current.name)
|
||||||
setVisibleRename(true)
|
setVisibleRename(true)
|
||||||
break
|
break
|
||||||
// case 'sync':
|
case 'sync':
|
||||||
|
handleSyncSourceList(selectedListRef.current.index)
|
||||||
|
break
|
||||||
|
// case 'changePosition':
|
||||||
|
|
||||||
// break
|
// break
|
||||||
case 'changePosition':
|
|
||||||
|
|
||||||
break
|
|
||||||
case 'remove':
|
case 'remove':
|
||||||
handleRemoveList(selectedListRef.current.id)
|
handleRemoveList(selectedListRef.current.id)
|
||||||
break
|
break
|
||||||
@ -100,16 +123,19 @@ const List = memo(({ setVisiblePanel, currentList, activeListIdRef }) => {
|
|||||||
default:
|
default:
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
}, [handleRemoveList])
|
}, [handleRemoveList, handleSyncSourceList])
|
||||||
|
|
||||||
const menus = useMemo(() => {
|
const menus = useMemo(() => {
|
||||||
|
if (selectedListIndex == -1) return []
|
||||||
|
const source = userList[selectedListIndex].source
|
||||||
|
|
||||||
return [
|
return [
|
||||||
{ action: 'rename', label: t('list_rename') },
|
{ action: 'rename', label: t('list_rename') },
|
||||||
// { action: 'sync', label: t('list_sync') },
|
{ action: 'sync', label: t('list_sync'), disabled: !source || !musicSdk[source].songList },
|
||||||
// { action: 'changePosition', label: t('change_position') },
|
// { action: 'changePosition', label: t('change_position') },
|
||||||
{ action: 'remove', label: t('list_remove') },
|
{ action: 'remove', label: t('list_remove') },
|
||||||
]
|
]
|
||||||
}, [t])
|
}, [selectedListIndex, userList, t])
|
||||||
|
|
||||||
const handleCancelRename = useCallback(() => {
|
const handleCancelRename = useCallback(() => {
|
||||||
setVisibleRename(false)
|
setVisibleRename(false)
|
||||||
@ -135,7 +161,16 @@ const List = memo(({ setVisiblePanel, currentList, activeListIdRef }) => {
|
|||||||
const offset = getListScrollPosition(LIST_SCROLL_POSITION_KEY)
|
const offset = getListScrollPosition(LIST_SCROLL_POSITION_KEY)
|
||||||
scrollViewRef.current.scrollTo({ x: 0, y: offset, animated: false })
|
scrollViewRef.current.scrollTo({ x: 0, y: offset, animated: false })
|
||||||
})
|
})
|
||||||
|
const showMenu = useCallback((id, name, index, position) => {
|
||||||
|
// console.log(position)
|
||||||
|
if (id == 'default' || id == 'love') return
|
||||||
|
setButtonPosition({ ...position })
|
||||||
|
selectedListRef.current.id = id
|
||||||
|
selectedListRef.current.name = name
|
||||||
|
selectedListRef.current.index = index
|
||||||
|
setSelectedListIndex(index)
|
||||||
|
setVisibleMenu(true)
|
||||||
|
}, [])
|
||||||
return (
|
return (
|
||||||
<View style={{ ...styles.container, borderTopColor: theme.secondary10 }}>
|
<View style={{ ...styles.container, borderTopColor: theme.secondary10 }}>
|
||||||
<ScrollView style={{ flexShrink: 1, flexGrow: 0 }} onScroll={handleScroll} ref={scrollViewRef} keyboardShouldPersistTaps={'always'}>
|
<ScrollView style={{ flexShrink: 1, flexGrow: 0 }} onScroll={handleScroll} ref={scrollViewRef} keyboardShouldPersistTaps={'always'}>
|
||||||
@ -150,7 +185,7 @@ const List = memo(({ setVisiblePanel, currentList, activeListIdRef }) => {
|
|||||||
<Text numberOfLines={1} style={{ color: theme.normal }}>{loveList.name}</Text>
|
<Text numberOfLines={1} style={{ color: theme.normal }}>{loveList.name}</Text>
|
||||||
</TouchableOpacity>
|
</TouchableOpacity>
|
||||||
</View>
|
</View>
|
||||||
{userList.map(({ id, name }) => <ListItem key={id} name={name} id={id} onPress={() => handleToggleList({ id, name })} activeId={currentList.id} showMenu={showMenu} />)}
|
{userList.map(({ id, name }, index) => <ListItem key={id} name={name} id={id} index={index} loading={fetchingListStatus[id]} onPress={() => handleToggleList({ id, name })} activeId={currentList.id} showMenu={showMenu} />)}
|
||||||
</View>
|
</View>
|
||||||
</ScrollView>
|
</ScrollView>
|
||||||
<Menu menus={menus} buttonPosition={buttonPosition} onPress={handleMenuPress} visible={visibleMenu} hideMenu={hideMenu} />
|
<Menu menus={menus} buttonPosition={buttonPosition} onPress={handleMenuPress} visible={visibleMenu} hideMenu={hideMenu} />
|
||||||
@ -174,7 +209,7 @@ const List = memo(({ setVisiblePanel, currentList, activeListIdRef }) => {
|
|||||||
})
|
})
|
||||||
|
|
||||||
|
|
||||||
export default memo(({ currentList, activeListIdRef }) => {
|
export default memo(({ currentList, activeListIdRef, handleCancelMultiSelect }) => {
|
||||||
const theme = useGetter('common', 'theme')
|
const theme = useGetter('common', 'theme')
|
||||||
const [visiblePanel, setVisiblePanel] = useState(false)
|
const [visiblePanel, setVisiblePanel] = useState(false)
|
||||||
|
|
||||||
@ -182,9 +217,12 @@ export default memo(({ currentList, activeListIdRef }) => {
|
|||||||
<DorpDownPanel
|
<DorpDownPanel
|
||||||
visible={visiblePanel}
|
visible={visiblePanel}
|
||||||
setVisible={setVisiblePanel}
|
setVisible={setVisiblePanel}
|
||||||
PanelContent={<List setVisiblePanel={setVisiblePanel} currentList={currentList} activeListIdRef={activeListIdRef} />}
|
PanelContent={<List setVisiblePanel={setVisiblePanel} currentList={currentList} activeListIdRef={activeListIdRef} handleCancelMultiSelect={handleCancelMultiSelect} />}
|
||||||
>
|
>
|
||||||
<Text style={{ ...styles.sourceMenu, color: theme.secondary }}>{currentList.name}</Text>
|
<View style={styles.currentList}>
|
||||||
|
<Text style={{ ...styles.sourceMenu, color: theme.secondary, flex: 1 }}>{currentList.name}</Text>
|
||||||
|
{/* <TouchableOpacity style={styles.createList}><Icon style={{ color: theme.secondary30, fontSize: 24 }} name="playlist-plus" /></TouchableOpacity> */}
|
||||||
|
</View>
|
||||||
</DorpDownPanel>
|
</DorpDownPanel>
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
@ -224,6 +262,16 @@ const styles = StyleSheet.create({
|
|||||||
alignItems: 'center',
|
alignItems: 'center',
|
||||||
},
|
},
|
||||||
|
|
||||||
|
currentList: {
|
||||||
|
flexDirection: 'row',
|
||||||
|
},
|
||||||
|
createList: {
|
||||||
|
width: 38,
|
||||||
|
justifyContent: 'center',
|
||||||
|
alignItems: 'center',
|
||||||
|
// backgroundColor: 'rgba(0,0,0,0.2)',
|
||||||
|
},
|
||||||
|
|
||||||
|
|
||||||
renameContent: {
|
renameContent: {
|
||||||
flexGrow: 1,
|
flexGrow: 1,
|
||||||
|
@ -301,7 +301,7 @@ const List = () => {
|
|||||||
<View style={styles.container}>
|
<View style={styles.container}>
|
||||||
{listComponent}
|
{listComponent}
|
||||||
<View style={{ backgroundColor: theme.secondary45 }}>
|
<View style={{ backgroundColor: theme.secondary45 }}>
|
||||||
<MyList currentList={currentList} activeListIdRef={activeListIdRef} />
|
<MyList currentList={currentList} activeListIdRef={activeListIdRef} handleCancelMultiSelect={handleCancelMultiSelect} />
|
||||||
<ExitMultipleModeBar
|
<ExitMultipleModeBar
|
||||||
multipleMode={isMultiSelectMode}
|
multipleMode={isMultiSelectMode}
|
||||||
onCancel={handleCancelMultiSelect}
|
onCancel={handleCancelMultiSelect}
|
||||||
|
@ -16,6 +16,7 @@ export default memo(() => {
|
|||||||
const createUserList = useDispatch('list', 'createUserList')
|
const createUserList = useDispatch('list', 'createUserList')
|
||||||
const { t } = useTranslation()
|
const { t } = useTranslation()
|
||||||
const theme = useGetter('common', 'theme')
|
const theme = useGetter('common', 'theme')
|
||||||
|
const songListSource = useGetter('songList', 'songListSource')
|
||||||
|
|
||||||
const handlePlayAll = useCallback(async() => {
|
const handlePlayAll = useCallback(async() => {
|
||||||
if (!listDetailData.info.name) return
|
if (!listDetailData.info.name) return
|
||||||
@ -32,9 +33,9 @@ export default memo(() => {
|
|||||||
|
|
||||||
const handleCollection = useCallback(async() => {
|
const handleCollection = useCallback(async() => {
|
||||||
if (!listDetailData.info.name) return
|
if (!listDetailData.info.name) return
|
||||||
const list = await getListDetailAll(selectListInfo.id)
|
const list = await getListDetailAll({ id: selectListInfo.id, source: songListSource })
|
||||||
createUserList({
|
createUserList({
|
||||||
name: listDetailData.info.name,
|
name: listDetailData.info.name || `${listDetailData.source}-list`,
|
||||||
id: `${listDetailData.source}__${listDetailData.id}`,
|
id: `${listDetailData.source}__${listDetailData.id}`,
|
||||||
list,
|
list,
|
||||||
source: listDetailData.source,
|
source: listDetailData.source,
|
||||||
@ -42,7 +43,7 @@ export default memo(() => {
|
|||||||
isShowToast: true,
|
isShowToast: true,
|
||||||
})
|
})
|
||||||
toast(t('collect_success'))
|
toast(t('collect_success'))
|
||||||
}, [listDetailData, getListDetailAll, selectListInfo.id, createUserList, t])
|
}, [listDetailData, getListDetailAll, selectListInfo, songListSource, createUserList, t])
|
||||||
|
|
||||||
const handleBack = () => setVisibleListDetail(false)
|
const handleBack = () => setVisibleListDetail(false)
|
||||||
|
|
||||||
|
@ -176,7 +176,7 @@ export const updateMusicInfo = ({ id, index, data }) => (dispatch, getState) =>
|
|||||||
saveList(global.allList[id])
|
saveList(global.allList[id])
|
||||||
}
|
}
|
||||||
|
|
||||||
export const createUserList = ({ name, id = `userlist_${Date.now()}`, source, sourceListId, list }) => async(dispatch, getState) => {
|
export const createUserList = ({ name, id = `userlist_${Date.now()}`, list = [], source, sourceListId }) => async(dispatch, getState) => {
|
||||||
dispatch({
|
dispatch({
|
||||||
type: TYPES.createUserList,
|
type: TYPES.createUserList,
|
||||||
payload: { name, id, source, sourceListId },
|
payload: { name, id, source, sourceListId },
|
||||||
|
@ -137,11 +137,9 @@ export const getListDetail = ({ id, page, isRefresh = false }) => (dispatch, get
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
export const getListDetailAll = id => (dispatch, getState) => {
|
export const getListDetailAll = ({ source, id }) => (dispatch, getState) => {
|
||||||
const allState = getState()
|
|
||||||
const rootState = allState.common
|
|
||||||
let source = rootState.setting.songList.source
|
|
||||||
let listKey = `sdetail__${source}__${id}`
|
let listKey = `sdetail__${source}__${id}`
|
||||||
|
if (!cache.has(listKey)) cache.set(listKey, new Map())
|
||||||
const listCache = cache.get(listKey)
|
const listCache = cache.get(listKey)
|
||||||
const loadData = (id, page) => {
|
const loadData = (id, page) => {
|
||||||
let pageKey = `sdetail__${source}__${id}__${page}`
|
let pageKey = `sdetail__${source}__${id}__${page}`
|
||||||
|
Loading…
x
Reference in New Issue
Block a user