diff --git a/index.js b/index.js
index cbb619c..04986f9 100644
--- a/index.js
+++ b/index.js
@@ -19,7 +19,7 @@ import { init as initMusicTools } from '@/utils/music'
import { init as initLyric } from '@/plugins/lyric'
import { init as initI18n, supportedLngs } from '@/plugins/i18n'
import { deviceLanguage, getPlayInfo } from '@/utils/tools'
-import { LIST_ID_PLAY_TEMP, LIST_ID_PLAY_LATER } from '@/config/constant'
+import { LIST_ID_PLAY_TEMP } from '@/config/constant'
console.log('starting app...')
diff --git a/publish/changeLog.md b/publish/changeLog.md
index 6e5c819..0f6538f 100644
--- a/publish/changeLog.md
+++ b/publish/changeLog.md
@@ -1,3 +1,7 @@
+### 新增
+
+- 新增通过歌单链接打开歌单的功能
+
### 优化
- 切换到播放详情歌词界面时将阻止屏幕息屏
diff --git a/src/lang/en_us.json b/src/lang/en_us.json
index c96e9cd..db29013 100644
--- a/src/lang/en_us.json
+++ b/src/lang/en_us.json
@@ -30,6 +30,10 @@
"play_detail_todo_tip": "What do you want? No, this function has not been implemented yet 😛, But you can try to locate the currently playing song by long pressing (only valid for playing songs in \"My List\")",
+ "load_failed": "Ah, loading failed 😥",
+ "songlist_open": "Import",
+ "songlist_open_input_placeholder": "Enter the playlist link or playlist ID",
+ "songlist_open_input_tip": "1. Cross-source opening of the playlist is not supported. Please confirm whether the playlist to be opened corresponds to the current playlist source\n2. If you encounter a playlist link that cannot be opened, feedback is welcome\n3, Kugou source Open with playlist ID is not supported, but Kugou code is supported",
"collect_success": "Collection success",
"collect_songlist": "Collection Songlist",
"collect_toplist": "Collection Toplist",
diff --git a/src/lang/zh_cn.json b/src/lang/zh_cn.json
index 5ead1e6..0d3df67 100644
--- a/src/lang/zh_cn.json
+++ b/src/lang/zh_cn.json
@@ -30,6 +30,10 @@
"play_detail_todo_tip": "你想干嘛?不可以的,这个功能还没有实现哦😛,不过你可以试着长按来定位当前播放的歌曲(仅对播放“我的列表”里的歌曲有效哦)",
+ "load_failed": "啊 加载失败了 😥",
+ "songlist_open": "导入",
+ "songlist_open_input_placeholder": "输入歌单链接或歌单ID",
+ "songlist_open_input_tip": "1、不支持跨源打开歌单,请确认要打开的歌单与当前歌单源是否对应\n2、若遇到无法打开的歌单链接,欢迎反馈\n3、酷狗源不支持用歌单ID打开,但支持酷狗码打开",
"collect_success": "收藏成功",
"collect_songlist": "收藏歌单",
"collect_toplist": "收藏排行榜",
diff --git a/src/screens/Home/SongList/List/MenuBar.js b/src/screens/Home/SongList/List/MenuBar.js
index 41b0578..c5349fd 100644
--- a/src/screens/Home/SongList/List/MenuBar.js
+++ b/src/screens/Home/SongList/List/MenuBar.js
@@ -1,19 +1,21 @@
import React, { useCallback, useMemo } from 'react'
import { View, Text, StyleSheet } from 'react-native'
-import { useGetter, useDispatch } from '@/store'
+// import { useGetter, useDispatch } from '@/store'
import SourceSelector from './SourceSelector'
import SortTab from './SortTab'
import Tag from './Tag'
+import OpenList from './OpenList'
// import { BorderWidths } from '@/theme'
export default () => {
- const theme = useGetter('common', 'theme')
+ // const theme = useGetter('common', 'theme')
return (
+
)
diff --git a/src/screens/Home/SongList/List/OpenList.js b/src/screens/Home/SongList/List/OpenList.js
new file mode 100644
index 0000000..616268d
--- /dev/null
+++ b/src/screens/Home/SongList/List/OpenList.js
@@ -0,0 +1,98 @@
+import React, { useCallback, memo, useMemo, useEffect, useState, useRef } from 'react'
+import { View, Text, StyleSheet, TouchableOpacity } from 'react-native'
+// import Icon from '@/components/common/Icon'
+import { useGetter, useDispatch } from '@/store'
+import { useTranslation } from '@/plugins/i18n'
+import Button from '@/components/common/Button'
+import ConfirmAlert from '@/components/common/ConfirmAlert'
+import Input from '@/components/common/Input'
+
+export default memo(() => {
+ const theme = useGetter('common', 'theme')
+ const { t } = useTranslation()
+ const [visibleAlert, setVisibleAlert] = useState(false)
+ const [text, setText] = useState('')
+ const setSelectListInfo = useDispatch('songList', 'setSelectListInfo')
+ const setVisibleListDetail = useDispatch('songList', 'setVisibleListDetail')
+ const songListSource = useGetter('songList', 'songListSource')
+
+ const handleShowMusicAddModal = () => {
+ setText('')
+ setVisibleAlert(true)
+ }
+
+ const handleCancelOpen = useCallback(() => {
+ setVisibleAlert(false)
+ }, [])
+ const handleOpen = useCallback(() => {
+ if (!text.length) return
+ setSelectListInfo({
+ play_count: null,
+ id: text,
+ author: '',
+ name: '',
+ img: null,
+ desc: '',
+ source: songListSource,
+ })
+ setVisibleListDetail(true)
+ setVisibleAlert(false)
+ }, [setSelectListInfo, setVisibleListDetail, songListSource, text])
+
+
+ return (
+ <>
+
+
+
+
+ {t('songlist_open_input_tip')}
+
+
+ >
+ )
+})
+
+const styles = StyleSheet.create({
+ button: {
+ // backgroundColor: '#ccc',
+ alignItems: 'center',
+ justifyContent: 'center',
+ paddingLeft: 12,
+ paddingRight: 12,
+ },
+ buttonText: {
+ fontSize: 14,
+ },
+
+ alertContent: {
+ flexGrow: 1,
+ flexShrink: 1,
+ flexDirection: 'column',
+ },
+ input: {
+ flexGrow: 1,
+ flexShrink: 1,
+ minWidth: 240,
+ borderRadius: 4,
+ paddingTop: 2,
+ paddingBottom: 2,
+ fontSize: 12,
+ },
+ inputTipText: {
+ marginTop: 5,
+ fontSize: 12,
+ lineHeight: 18,
+ },
+})
diff --git a/src/screens/Home/SongList/List/Tag.js b/src/screens/Home/SongList/List/Tag.js
index 9e68e7d..51172aa 100644
--- a/src/screens/Home/SongList/List/Tag.js
+++ b/src/screens/Home/SongList/List/Tag.js
@@ -91,9 +91,9 @@ const styles = StyleSheet.create({
height: 38,
lineHeight: 38,
textAlign: 'center',
- minWidth: 70,
- paddingLeft: 10,
- paddingRight: 10,
+ // minWidth: 70,
+ paddingLeft: 12,
+ paddingRight: 12,
},
container: {
diff --git a/src/screens/Home/SongList/ListDetail/Failed.js b/src/screens/Home/SongList/ListDetail/Failed.js
new file mode 100644
index 0000000..a2f8d5a
--- /dev/null
+++ b/src/screens/Home/SongList/ListDetail/Failed.js
@@ -0,0 +1,48 @@
+import React, { memo } from 'react'
+import { View, Text, StyleSheet, ImageBackground } from 'react-native'
+import { useGetter, useDispatch } from '@/store'
+import { useTranslation } from '@/plugins/i18n'
+import Button from '@/components/common/Button'
+
+const Header = memo(() => {
+ const { t } = useTranslation()
+ const theme = useGetter('common', 'theme')
+ const setVisibleListDetail = useDispatch('songList', 'setVisibleListDetail')
+ const handleBack = () => {
+ setVisibleListDetail(false)
+ }
+
+ return (
+
+ {t('load_failed')}
+
+
+ )
+})
+
+const styles = StyleSheet.create({
+ container: {
+ flex: 1,
+ alignItems: 'center',
+ justifyContent: 'center',
+ },
+ text: {
+ fontSize: 18,
+ marginBottom: '20%',
+ },
+ controlBtn: {
+ paddingTop: 12,
+ paddingBottom: 12,
+ paddingLeft: 25,
+ paddingRight: 25,
+ borderRadius: 4,
+ },
+ controlBtnText: {
+ fontSize: 14,
+ textAlign: 'center',
+ },
+})
+
+export default Header
diff --git a/src/screens/Home/SongList/ListDetail/List.js b/src/screens/Home/SongList/ListDetail/List.js
index b8af1e9..36cae31 100644
--- a/src/screens/Home/SongList/ListDetail/List.js
+++ b/src/screens/Home/SongList/ListDetail/List.js
@@ -1,6 +1,7 @@
import React, { useState, useCallback, useRef } from 'react'
// import { View, Text, StyleSheet, Animated, FlatList, ImageBackground } from 'react-native'
import ListDetailHeader from './Header'
+import Failed from './Failed'
import { useGetter, useDispatch } from '@/store'
import OnlineList from '@/components/OnlineList'
@@ -8,6 +9,7 @@ import OnlineList from '@/components/OnlineList'
export default ({ animatePlayed }) => {
const [isListRefreshing, setIsListRefreshing] = useState(false)
const isVisibleListDetail = useGetter('songList', 'isVisibleListDetail')
+ const isGetListDetailFailed = useGetter('songList', 'isGetListDetailFailed')
const selectListInfo = useGetter('songList', 'selectListInfo')
const selectListInfoRef = useRef(selectListInfo)
@@ -28,15 +30,17 @@ export default ({ animatePlayed }) => {
}, [getListDetail])
return (
- }
+ isGetListDetailFailed
+ ?
+ : }
/>
)
}
diff --git a/src/screens/Home/SongList/ListDetail/index.js b/src/screens/Home/SongList/ListDetail/index.js
index 4dc8d0a..d4ede8d 100644
--- a/src/screens/Home/SongList/ListDetail/index.js
+++ b/src/screens/Home/SongList/ListDetail/index.js
@@ -6,7 +6,6 @@ import { useGetter, useDispatch } from '@/store'
export default () => {
- // const isGetDetailFailedRef = useRef(false)
const [visible, setVisible] = useState(false)
const [animatePlayed, setAnimatPlayed] = useState(true)
const animFade = useRef(new Animated.Value(0)).current
diff --git a/src/store/modules/songList/action.js b/src/store/modules/songList/action.js
index f474470..621c506 100644
--- a/src/store/modules/songList/action.js
+++ b/src/store/modules/songList/action.js
@@ -15,6 +15,7 @@ export const TYPES = {
setListDetailLoading: null,
setListEnd: null,
setListDetailEnd: null,
+ setGetListDetailFailed: null,
}
for (const key of Object.keys(TYPES)) {
@@ -112,6 +113,7 @@ export const getListDetail = ({ id, page, isRefresh = false }) => (dispatch, get
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 })))
@@ -122,6 +124,12 @@ export const getListDetail = ({ id, page, isRefresh = false }) => (dispatch, get
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
@@ -169,6 +177,12 @@ export const setSelectListInfo = info => {
payload: info,
}
}
+export const setGetListDetailFailed = isFailed => {
+ return {
+ type: TYPES.setGetListDetailFailed,
+ payload: isFailed,
+ }
+}
export const setTags = ({ tags, source }) => {
return {
type: TYPES.setTags,
diff --git a/src/store/modules/songList/getter.js b/src/store/modules/songList/getter.js
index 3d57ea0..5d67026 100644
--- a/src/store/modules/songList/getter.js
+++ b/src/store/modules/songList/getter.js
@@ -14,6 +14,7 @@ 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
diff --git a/src/store/modules/songList/reducer.js b/src/store/modules/songList/reducer.js
index 3923e0e..19d63ae 100644
--- a/src/store/modules/songList/reducer.js
+++ b/src/store/modules/songList/reducer.js
@@ -37,6 +37,7 @@ const initialState = {
},
selectListInfo: {},
isVisibleListDetail: false,
+ isGetListDetailFailed: false,
}
sources.forEach(source => {
@@ -146,6 +147,12 @@ const mutations = {
},
}
},
+ [TYPES.setGetListDetailFailed](state, isFailed) {
+ return {
+ ...state,
+ isGetListDetailFailed: isFailed,
+ }
+ },
[TYPES.setListLoading](state, isLoading) {
return {
...state,