From c0785190e045ba4502ca64dec2737559b6661eda Mon Sep 17 00:00:00 2001 From: lyswhut Date: Sat, 22 May 2021 15:56:42 +0800 Subject: [PATCH] =?UTF-8?q?=E6=96=B0=E5=A2=9E=E9=80=9A=E8=BF=87=E6=AD=8C?= =?UTF-8?q?=E5=8D=95=E9=93=BE=E6=8E=A5=E6=89=93=E5=BC=80=E6=AD=8C=E5=8D=95?= =?UTF-8?q?=E7=9A=84=E5=8A=9F=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- index.js | 2 +- publish/changeLog.md | 4 + src/lang/en_us.json | 4 + src/lang/zh_cn.json | 4 + src/screens/Home/SongList/List/MenuBar.js | 6 +- src/screens/Home/SongList/List/OpenList.js | 98 +++++++++++++++++++ src/screens/Home/SongList/List/Tag.js | 6 +- .../Home/SongList/ListDetail/Failed.js | 48 +++++++++ src/screens/Home/SongList/ListDetail/List.js | 22 +++-- src/screens/Home/SongList/ListDetail/index.js | 1 - src/store/modules/songList/action.js | 14 +++ src/store/modules/songList/getter.js | 1 + src/store/modules/songList/reducer.js | 7 ++ 13 files changed, 201 insertions(+), 16 deletions(-) create mode 100644 src/screens/Home/SongList/List/OpenList.js create mode 100644 src/screens/Home/SongList/ListDetail/Failed.js 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,