diff --git a/publish/changeLog.md b/publish/changeLog.md index 1ceb3af..d2590fe 100644 --- a/publish/changeLog.md +++ b/publish/changeLog.md @@ -2,6 +2,7 @@ - 同步功能新增对列表位置调整的支持(若你使用同步功能,请务必升级到此版本以上,不然会有问题) - 新增播放详情页歌词字体大小调整设置,可在详情页右上角的按钮进行调整 +- 新增同步服务地址历史列表功能 ### 优化 diff --git a/src/config/index.js b/src/config/index.js index 8eed688..0254d37 100644 --- a/src/config/index.js +++ b/src/config/index.js @@ -19,6 +19,7 @@ export const storageDataPrefix = { playInfo: '@play_info', syncAuthKey: '@sync_auth_key', syncHost: '@sync_host', + syncHostHistory: '@sync_host_history', } export const ITEM_HEIGHT = 60 diff --git a/src/lang/en_us.json b/src/lang/en_us.json index c266185..dc7fab0 100644 --- a/src/lang/en_us.json +++ b/src/lang/en_us.json @@ -69,7 +69,7 @@ "loading": "Loading...", "move_to": "Move to...", "name": "Name: {{name}}", - "nav__my_list": "My list", + "nav_my_list": "My list", "parent_dir_name": "Parent directory", "pause": "Pause", "play": "Play", @@ -83,7 +83,7 @@ "play_prev": "Previous song", "play_single": "Disable song switching", "play_single_loop": "Single loop playback", - "player__setting_lrc_font_size": "Lyric font size setting", + "player_setting_lrc_font_size": "Lyric font size setting", "quality_high_quality": "HQ", "quality_lossless": "SQ", "setting_about": "About LX Music", @@ -169,6 +169,8 @@ "setting_sync_code_input_tip": "Please enter the connection code", "setting_sync_code_label": "You need to enter the connection code for the first connection", "setting_sync_enbale": "Enable sync", + "setting_sync_history": "History address", + "setting_sync_history_empty": "Nothing here", "setting_sync_host_label": "Synchronization service IP address", "setting_sync_host_tip": "Please enter the synchronization service IP address", "setting_sync_port_label": "Synchronization service port number", @@ -178,7 +180,6 @@ "setting_version": "Software Update", "setting_version_show_ver_modal": "Open the update window 🚀", "singer": "Artist: {{name}}", - "songlist__tags": "Playlist category", "songlist_hot": "Hot", "songlist_hot_collect": "Hot Collect", "songlist_new": "New", @@ -187,6 +188,7 @@ "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", "songlist_recommend": "Recommend", "songlist_rise": "Rise", + "songlist_tags": "Playlist category", "source_alias_all": "Aggregated", "source_alias_bd": "BD Music", "source_alias_kg": "KG Music", diff --git a/src/lang/zh_cn.json b/src/lang/zh_cn.json index 1e8e2cd..4fe8e75 100644 --- a/src/lang/zh_cn.json +++ b/src/lang/zh_cn.json @@ -70,7 +70,7 @@ "loading": "加载中...", "move_to": "移动到...", "name": "歌曲名:{{name}}", - "nav__my_list": "我的列表", + "nav_my_list": "我的列表", "parent_dir_name": "父级目录", "pause": "暂停", "play": "播放", @@ -84,7 +84,7 @@ "play_prev": "上一曲", "play_single": "禁用歌曲切换", "play_single_loop": "单曲循环播放", - "player__setting_lrc_font_size": "歌词字体大小设置", + "player_setting_lrc_font_size": "歌词字体大小设置", "quality_high_quality": "高品质", "quality_lossless": "无损", "setting_about": "关于洛雪音乐", @@ -170,6 +170,9 @@ "setting_sync_code_input_tip": "请输入连接码", "setting_sync_code_label": "首次连接需要输入连接码", "setting_sync_enbale": "启用同步", + "setting_sync_history": "历史地址", + "setting_sync_history_empty": "这里啥也没有😮", + "setting_sync_history_title": "连接历史", "setting_sync_host_label": "同步服务IP地址", "setting_sync_host_tip": "请输入同步服务IP地址", "setting_sync_port_label": "同步服务端口号", @@ -179,7 +182,6 @@ "setting_version": "软件更新", "setting_version_show_ver_modal": "打开更新窗口 🚀", "singer": "艺术家:{{name}}", - "songlist__tags": "歌单类别", "songlist_hot": "最热", "songlist_hot_collect": "热藏", "songlist_new": "最新", @@ -188,6 +190,7 @@ "songlist_open_input_tip": "1、不支持跨源打开歌单,请确认要打开的歌单与当前歌单源是否对应\n2、若遇到无法打开的歌单链接,欢迎反馈\n3、酷狗源不支持用歌单ID打开,但支持酷狗码打开", "songlist_recommend": "推荐", "songlist_rise": "飙升", + "songlist_tags": "歌单类别", "source_alias_all": "聚合大会", "source_alias_bd": "小杜音乐", "source_alias_kg": "小枸音乐", diff --git a/src/screens/Home/List/components/MyList.js b/src/screens/Home/List/components/MyList.js index 41c4a35..006157e 100644 --- a/src/screens/Home/List/components/MyList.js +++ b/src/screens/Home/List/components/MyList.js @@ -387,7 +387,7 @@ export default memo(({ currentList, handleCancelMultiSelect, showListSearchBar } - + diff --git a/src/screens/Home/Setting/Sync/History.js b/src/screens/Home/Setting/Sync/History.js new file mode 100644 index 0000000..b806473 --- /dev/null +++ b/src/screens/Home/Setting/Sync/History.js @@ -0,0 +1,143 @@ +import React, { memo, useRef, useState, useEffect, useCallback } from 'react' +import { StyleSheet, View, Text, TouchableOpacity, ScrollView } from 'react-native' +import { useGetter } from '@/store' +// import { gzip, ungzip } from 'pako' +import Icon from '@/components/common/Icon' + +import Button from '../components/Button' +import { useTranslation } from '@/plugins/i18n' +import { getSyncHostHistory, removeSyncHostHistory, setSyncHost } from '@/utils/tools' +import Popup from '@/components/common/Popup' +import { BorderWidths } from '@/theme' + +const HistoryListItem = ({ item, index, remove, setHostInfo }) => { + const theme = useGetter('common', 'theme') + const handleSetHost = () => { + setHostInfo({ + host: item.host, + port: item.port, + }) + setSyncHost({ + host: item.host, + port: item.port, + }) + } + const handleRemove = () => { + remove(index) + } + + return ( + + + {item.host} + {item.port} + + + + + + ) +} +const HistoryList = ({ visible, setHostInfo }) => { + const [list, setList] = useState([]) + const isUnmountedRef = useRef(true) + const theme = useGetter('common', 'theme') + const { t } = useTranslation() + + const getHistory = () => { + getSyncHostHistory().then(historyList => { + if (isUnmountedRef.current) return + setList([...historyList]) + }) + } + + useEffect(() => { + if (!visible) return + getHistory() + }, [visible]) + + useEffect(() => { + isUnmountedRef.current = false + return () => { + isUnmountedRef.current = true + } + }, []) + + const handleRemove = useCallback((index) => { + removeSyncHostHistory(index) + const newList = [...list] + newList.splice(index, 1) + setList(newList) + }, [list]) + + return ( + + { + list.length + ? list.map((item, index) => ) + : {t('setting_sync_history_empty')} + } + + ) +} + +export default memo(({ setHostInfo, isWaiting }) => { + const { t } = useTranslation() + const [visible, setVisible] = useState(false) + const isEnableSync = useGetter('common', 'isEnableSync') + + const showPopup = () => { + setVisible(true) + } + + const hidePopup = () => { + setVisible(false) + } + + return ( + <> + + + + + + + + ) +}) + +const styles = StyleSheet.create({ + cacheSize: { + marginBottom: 5, + }, + btn: { + flexDirection: 'row', + marginLeft: 25, + marginBottom: 15, + }, + tipText: { + fontSize: 14, + textAlign: 'center', + marginTop: 15, + }, + list: { + flexShrink: 1, + flexGrow: 0, + paddingLeft: 10, + paddingRight: 10, + }, + listItem: { + flexDirection: 'row', + alignItems: 'center', + paddingTop: 5, + paddingBottom: 5, + borderBottomWidth: BorderWidths.normal, + }, + listName: { + flex: 1, + }, +}) diff --git a/src/screens/Home/Setting/Sync/IsEnable.js b/src/screens/Home/Setting/Sync/IsEnable.js index 1257158..6b4ddcf 100644 --- a/src/screens/Home/Setting/Sync/IsEnable.js +++ b/src/screens/Home/Setting/Sync/IsEnable.js @@ -8,7 +8,7 @@ import ConfirmAlert from '@/components/common/ConfirmAlert' import Input from '@/components/common/Input' import { useTranslation } from '@/plugins/i18n' import { connect, disconnect, SYNC_CODE } from '@/plugins/sync' -import { getSyncHost, setSyncHost, toast } from '@/utils/tools' +import { getSyncHost, setSyncHost, toast, addSyncHostHistory } from '@/utils/tools' import InputItem from '../components/InputItem' import { getWIFIIPV4Address } from '@/utils/utils' @@ -66,13 +66,11 @@ const PortInput = memo(({ setPort, port, disabled }) => { }) -export default memo(() => { +export default memo(({ hostInfo, setHostInfo, isWaiting, setIsWaiting }) => { const { t } = useTranslation() const setIsEnableSync = useDispatch('common', 'setIsEnableSync') const syncStatus = useGetter('common', 'syncStatus') const isEnableSync = useGetter('common', 'isEnableSync') - const [isWaiting, setIsWaiting] = useState(global.isSyncEnableing) - const [hostInfo, setHostInfo] = useState({ host: '', port: '' }) const isUnmountedRef = useRef(true) const theme = useGetter('common', 'theme') const [address, setAddress] = useState('') @@ -110,13 +108,15 @@ export default memo(() => { const handleSetEnableSync = useCallback(flag => { setIsEnableSync(flag) + if (flag) addSyncHostHistory(hostInfo.host, hostInfo.port) + global.isSyncEnableing = true setIsWaiting(true) ;(flag ? connect() : disconnect()).finally(() => { global.isSyncEnableing = false setIsWaiting(false) }) - }, [setIsEnableSync]) + }, [hostInfo, setIsEnableSync, setIsWaiting]) const setHost = useCallback(host => { diff --git a/src/screens/Home/Setting/Sync/index.js b/src/screens/Home/Setting/Sync/index.js index ecb3d42..da56827 100644 --- a/src/screens/Home/Setting/Sync/index.js +++ b/src/screens/Home/Setting/Sync/index.js @@ -1,17 +1,21 @@ -import React, { memo } from 'react' +import React, { memo, useState } from 'react' import Section from '../components/Section' import IsEnable from './IsEnable' +import History from './History' // import SyncHost from './SyncHost' import { useTranslation } from '@/plugins/i18n' export default memo(() => { const { t } = useTranslation() + const [hostInfo, setHostInfo] = useState({ host: '', port: '' }) + const [isWaiting, setIsWaiting] = useState(global.isSyncEnableing) + return (
- - {/* */} + +
) }) diff --git a/src/screens/Home/SongList/Tag.js b/src/screens/Home/SongList/Tag.js index fe49419..0b254f2 100644 --- a/src/screens/Home/SongList/Tag.js +++ b/src/screens/Home/SongList/Tag.js @@ -81,7 +81,7 @@ export default memo(() => { setVisiblePanel(false)} - title={t('songlist__tags')} + title={t('songlist_tags')} > diff --git a/src/screens/PlayDetail/Landscape/components/Header.js b/src/screens/PlayDetail/Landscape/components/Header.js index 2638369..211b55f 100644 --- a/src/screens/PlayDetail/Landscape/components/Header.js +++ b/src/screens/PlayDetail/Landscape/components/Header.js @@ -64,7 +64,7 @@ const Setting = ({ visible, hide }) => { visible={visible} hide={hide} position='left' - title={t('player__setting_lrc_font_size')} + title={t('player_setting_lrc_font_size')} >
diff --git a/src/screens/PlayDetail/Portrait/components/Header.js b/src/screens/PlayDetail/Portrait/components/Header.js index eadf819..695f76f 100644 --- a/src/screens/PlayDetail/Portrait/components/Header.js +++ b/src/screens/PlayDetail/Portrait/components/Header.js @@ -62,7 +62,7 @@ const Setting = ({ visible, hide }) => { diff --git a/src/utils/tools.js b/src/utils/tools.js index 2b58df9..84c9894 100644 --- a/src/utils/tools.js +++ b/src/utils/tools.js @@ -10,6 +10,7 @@ const playInfoStorageKey = storageDataPrefix.playInfo const listPositionPrefix = storageDataPrefix.listPosition const syncAuthKeyPrefix = storageDataPrefix.syncAuthKey const syncHostPrefix = storageDataPrefix.syncHost +const syncHostHistoryPrefix = storageDataPrefix.syncHostHistory const listPrefix = storageDataPrefix.list const listSortPrefix = storageDataPrefix.listSort const defaultListKey = listPrefix + 'default' @@ -232,7 +233,6 @@ export const getSyncHost = async() => { } return { ...syncHostInfo } } - export const setSyncHost = async({ host, port }) => { // let hostInfo = await getData(syncHostPrefix) || {} // hostInfo.host = host @@ -241,6 +241,24 @@ export const setSyncHost = async({ host, port }) => { syncHostInfo.port = port await setData(syncHostPrefix, syncHostInfo) } +let syncHostHistory +export const getSyncHostHistory = async() => { + if (syncHostHistory === undefined) { + syncHostHistory = await getData(syncHostHistoryPrefix) || [] + } + return syncHostHistory +} +export const addSyncHostHistory = async(host, port) => { + let syncHostHistory = await getSyncHostHistory() + if (syncHostHistory.some(h => h.host == host && h.port == port)) return + syncHostHistory.unshift({ host, port }) + if (syncHostHistory.length > 20) syncHostHistory = syncHostHistory.slice(0, 20) // 最多存储20个 + await setData(syncHostHistoryPrefix, syncHostHistory) +} +export const removeSyncHostHistory = async index => { + syncHostHistory.splice(index, 1) + await setData(syncHostHistoryPrefix, syncHostHistory) +} export const exitApp = BackHandler.exitApp