mirror of
https://github.com/ikun0014/lx-music-mobile.git
synced 2025-07-15 17:42:08 +08:00
218 lines
6.5 KiB
JavaScript
218 lines
6.5 KiB
JavaScript
import music from '@/utils/music'
|
|
|
|
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,
|
|
}
|
|
|
|
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())
|
|
|
|
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)
|
|
}).finally(() => {
|
|
const state = getState().songList
|
|
if (state.listDetail.pageKey != pageKey) return
|
|
dispatch(setListDetailLoading(false))
|
|
})
|
|
}
|
|
|
|
export const getListDetailAll = id => (dispatch, getState) => {
|
|
const allState = getState()
|
|
const rootState = allState.common
|
|
let source = rootState.setting.songList.source
|
|
let listKey = `sdetail__${source}__${id}`
|
|
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])
|
|
})
|
|
}
|
|
|
|
export const setVisibleListDetail = isShow => {
|
|
return {
|
|
type: TYPES.setVisibleListDetail,
|
|
payload: isShow,
|
|
}
|
|
}
|
|
export const setSelectListInfo = info => {
|
|
return {
|
|
type: TYPES.setSelectListInfo,
|
|
payload: info,
|
|
}
|
|
}
|
|
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 },
|
|
}
|
|
}
|