Files
lx-music-mobile-mod/src/store/modules/songList/action.js
2021-05-17 11:54:14 +08:00

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 },
}
}