添加是否显示歌词翻译设置

This commit is contained in:
lyswhut 2021-06-13 16:39:29 +08:00
parent 2bad0b0ef5
commit dd3e9e06c0
17 changed files with 117 additions and 26 deletions

View File

@ -16,7 +16,7 @@ import { action as commonAction } from '@/store/modules/common'
import { action as playerAction } from '@/store/modules/player' import { action as playerAction } from '@/store/modules/player'
import { action as listAction } from '@/store/modules/list' import { action as listAction } from '@/store/modules/list'
import { init as initMusicTools } from '@/utils/music' import { init as initMusicTools } from '@/utils/music'
import { init as initLyric } from '@/plugins/lyric' import { init as initLyric, toggleTranslation } from '@/plugins/lyric'
import { init as initI18n, supportedLngs } from '@/plugins/i18n' import { init as initI18n, supportedLngs } from '@/plugins/i18n'
import { deviceLanguage, getPlayInfo, toast } from '@/utils/tools' import { deviceLanguage, getPlayInfo, toast } from '@/utils/tools'
import { LIST_ID_PLAY_TEMP } from '@/config/constant' import { LIST_ID_PLAY_TEMP } from '@/config/constant'
@ -39,7 +39,10 @@ const init = () => {
initLyric(), initLyric(),
registerPlaybackService(), registerPlaybackService(),
]).then(() => { ]).then(() => {
let lang = store.getState().common.setting.langId let setting = store.getState().common.setting
toggleTranslation(setting.player.isShowTranslation)
let lang = setting.langId
let needSetLang = false let needSetLang = false
if (!supportedLngs.includes(lang)) { if (!supportedLngs.includes(lang)) {
if (typeof deviceLanguage == 'string' && supportedLngs.includes(deviceLanguage)) { if (typeof deviceLanguage == 'string' && supportedLngs.includes(deviceLanguage)) {

12
package-lock.json generated
View File

@ -1,6 +1,6 @@
{ {
"name": "lx-music-mobile", "name": "lx-music-mobile",
"version": "0.4.1", "version": "0.4.2",
"lockfileVersion": 1, "lockfileVersion": 1,
"requires": true, "requires": true,
"dependencies": { "dependencies": {
@ -6834,9 +6834,9 @@
"dev": true "dev": true
}, },
"lrc-file-parser": { "lrc-file-parser": {
"version": "1.0.7", "version": "1.1.0",
"resolved": "https://registry.npmjs.org/lrc-file-parser/-/lrc-file-parser-1.0.7.tgz", "resolved": "https://registry.npmjs.org/lrc-file-parser/-/lrc-file-parser-1.1.0.tgz",
"integrity": "sha512-YaPa3xMMlN+cLXyINorMlWkXfO5U+AWpPywHiyVaVLgvRnI7xjArOyLpKH/I8XHmIPmdtJQfxFxT3K3hdCS91Q==" "integrity": "sha512-2C6j7lk2UpUae5+OnnQxXZ81ekg+LPWylAYzpCws3MFPSBqh4U3aA0cfLmjpIyDpKmS4hfNINfJZtt2jFX9peg=="
}, },
"lru-cache": { "lru-cache": {
"version": "6.0.0", "version": "6.0.0",
@ -8645,8 +8645,8 @@
"integrity": "sha512-Ls9qiNZzW/OLFoI25wfjjAcrf2DZ975hn2vr6U9gyuxi2nooVbzQeFoQS5vQcbCt9QX5NY8ASEEAtlLdIa6KVg==" "integrity": "sha512-Ls9qiNZzW/OLFoI25wfjjAcrf2DZ975hn2vr6U9gyuxi2nooVbzQeFoQS5vQcbCt9QX5NY8ASEEAtlLdIa6KVg=="
}, },
"react-native-track-player": { "react-native-track-player": {
"version": "git+https://github.com/lyswhut/react-native-track-player.git#8c8acfa6f73c52b92fe8ed51d75aa60deba71ae7", "version": "git+https://github.com/lyswhut/react-native-track-player.git#1dcfd07d31553bf5e1d32b9981445060f30f0160",
"from": "git+https://github.com/lyswhut/react-native-track-player.git#8c8acfa6f73c52b92fe8ed51d75aa60deba71ae7" "from": "git+https://github.com/lyswhut/react-native-track-player.git#1dcfd07d31553bf5e1d32b9981445060f30f0160"
}, },
"react-native-vector-icons": { "react-native-vector-icons": {
"version": "8.1.0", "version": "8.1.0",

View File

@ -45,7 +45,7 @@
"events": "^3.3.0", "events": "^3.3.0",
"i18next": "^20.3.1", "i18next": "^20.3.1",
"js-htmlencode": "^0.3.0", "js-htmlencode": "^0.3.0",
"lrc-file-parser": "^1.0.7", "lrc-file-parser": "^1.1.0",
"pako": "^2.0.3", "pako": "^2.0.3",
"process": "^0.11.10", "process": "^0.11.10",
"prop-types": "^15.7.2", "prop-types": "^15.7.2",

View File

@ -2,6 +2,7 @@
- 新增“其他应用播放声音时,自动暂停播放”设置,默认开启 - 新增“其他应用播放声音时,自动暂停播放”设置,默认开启
- 新增“添加歌曲到列表时的位置”设置,可选项为列表的“顶部”与“底部” - 新增“添加歌曲到列表时的位置”设置,可选项为列表的“顶部”与“底部”
- 新增“显示歌词翻译设置”,默认关闭
### 变更 ### 变更

View File

@ -3,7 +3,7 @@
// const { isMac } = require('./utils') // const { isMac } = require('./utils')
const defaultSetting = { const defaultSetting = {
version: '1.5', version: '1.6',
player: { player: {
togglePlayMethod: 'listLoop', togglePlayMethod: 'listLoop',
highQuality: false, highQuality: false,
@ -12,6 +12,7 @@ const defaultSetting = {
timeoutExit: '', timeoutExit: '',
timeoutExitPlayed: true, timeoutExitPlayed: true,
isHandleAudioFocus: true, isHandleAudioFocus: true,
isShowLyricTranslation: false,
}, },
list: { list: {
isShowSource: true, isShowSource: true,

View File

@ -112,6 +112,7 @@
"setting_play_lyric_transition": "Show lyrics translation", "setting_play_lyric_transition": "Show lyrics translation",
"setting_play_quality": "Play 320K quality songs first (if supported)", "setting_play_quality": "Play 320K quality songs first (if supported)",
"setting_play_save_play_time": "Remember playback progress", "setting_play_save_play_time": "Remember playback progress",
"setting_play_show_translation": "Show lyrics translation",
"setting_version": "Software Update", "setting_version": "Software Update",
"setting_version_show_ver_modal": "Open the update window 🚀", "setting_version_show_ver_modal": "Open the update window 🚀",
"singer": "Artist: {{name}}", "singer": "Artist: {{name}}",

View File

@ -113,6 +113,7 @@
"setting_play_lyric_transition": "显示歌词翻译", "setting_play_lyric_transition": "显示歌词翻译",
"setting_play_quality": "优先播放320K品质的歌曲如果支持", "setting_play_quality": "优先播放320K品质的歌曲如果支持",
"setting_play_save_play_time": "记住播放进度", "setting_play_save_play_time": "记住播放进度",
"setting_play_show_translation": "显示歌词翻译",
"setting_version": "软件更新", "setting_version": "软件更新",
"setting_version_show_ver_modal": "打开更新窗口 🚀", "setting_version_show_ver_modal": "打开更新窗口 🚀",
"singer": "艺术家:{{name}}", "singer": "艺术家:{{name}}",

View File

@ -10,6 +10,9 @@ const lrcTools = {
playHooks: [], playHooks: [],
setLyricHooks: [], setLyricHooks: [],
isPlay: false, isPlay: false,
isShowTranslation: false,
lyricText: '',
translationText: '',
init() { init() {
if (this.isInited) return if (this.isInited) return
this.isInited = true this.isInited = true
@ -51,9 +54,16 @@ export const init = async() => {
lrcTools.init() lrcTools.init()
} }
export const setLyric = lyric => { export const setLyric = (lyric, translation) => {
lrcTools.isPlay = false lrcTools.isPlay = false
lrcTools.lrc.setLyric(lyric) lrcTools.lyricText = lyric
lrcTools.translationText = translation
lrcTools.lrc.setLyric(lrcTools.lyricText, lrcTools.isShowTranslation ? lrcTools.translationText : '')
}
export const toggleTranslation = isShow => {
lrcTools.isShowTranslation = isShow
if (!lrcTools.lyricText) return
lrcTools.lrc.setLyric(lrcTools.lyricText, isShow ? lrcTools.translationText : '')
} }
export const play = time => { export const play = time => {
// console.log(time) // console.log(time)

View File

@ -18,7 +18,7 @@ export default memo(() => {
} }
return ( return (
<View style={{ marginTop: 5 }}> <View style={{ marginTop: 15 }}>
<CheckBoxItem check={isHandleAudioFocus} label={t('setting_play_handle_audio_focus')} onChange={handleSetAudioFocus} /> <CheckBoxItem check={isHandleAudioFocus} label={t('setting_play_handle_audio_focus')} onChange={handleSetAudioFocus} />
</View> </View>
) )

View File

@ -13,7 +13,7 @@ export default memo(() => {
return ( return (
<View style={{ marginTop: 5, marginBottom: 10 }}> <View style={{ marginTop: 5 }}>
<CheckBoxItem check={isPlayHighQuality} label={t('setting_play_quality')} onChange={setIsPlayHighQuality} /> <CheckBoxItem check={isPlayHighQuality} label={t('setting_play_quality')} onChange={setIsPlayHighQuality} />
</View> </View>
) )

View File

@ -0,0 +1,20 @@
import React, { memo } from 'react'
import { View } from 'react-native'
import { useGetter, useDispatch } from '@/store'
import CheckBoxItem from '../components/CheckBoxItem'
import { useTranslation } from '@/plugins/i18n'
export default memo(() => {
const { t } = useTranslation()
const isShowLyricTranslation = useGetter('common', 'isShowLyricTranslation')
const setIsShowLyricTranslation = useDispatch('common', 'setIsShowLyricTranslation')
return (
<View style={{ marginTop: 15 }}>
<CheckBoxItem check={isShowLyricTranslation} onChange={setIsShowLyricTranslation} label={t('setting_play_show_translation')} />
</View>
)
})

View File

@ -7,6 +7,7 @@ import {
import Section from '../components/Section' import Section from '../components/Section'
import IsPlayHighQuality from './IsPlayHighQuality' import IsPlayHighQuality from './IsPlayHighQuality'
import IsHandleAudioFocus from './IsHandleAudioFocus' import IsHandleAudioFocus from './IsHandleAudioFocus'
import IsShowLyricTranslation from './IsShowLyricTranslation'
import MaxCache from './MaxCache' import MaxCache from './MaxCache'
import { useTranslation } from '@/plugins/i18n' import { useTranslation } from '@/plugins/i18n'
@ -43,6 +44,7 @@ export default memo(() => {
<Section title={t('setting_play')}> <Section title={t('setting_play')}>
<IsPlayHighQuality /> <IsPlayHighQuality />
<IsHandleAudioFocus /> <IsHandleAudioFocus />
<IsShowLyricTranslation />
<MaxCache /> <MaxCache />
{/* <View style={{ marginLeft: 15, marginBottom: 15 }}> {/* <View style={{ marginLeft: 15, marginBottom: 15 }}>
<Text>播放歌曲切换方式</Text> <Text>播放歌曲切换方式</Text>

View File

@ -6,11 +6,18 @@ import { useLrcPlay, useLrcSet } from '@/plugins/lyric'
import { log } from '@/utils/log' import { log } from '@/utils/log'
import { toast } from '@/utils/tools' import { toast } from '@/utils/tools'
const LrcLine = memo(({ text, line, activeLine }) => { const LrcLine = memo(({ lrc, line, activeLine }) => {
const theme = useGetter('common', 'theme') const theme = useGetter('common', 'theme')
return ( return (
<Text style={{ ...styles.line, color: activeLine == line ? theme.secondary : theme.normal30 }}>{text}</Text> <View style={styles.line}>
<Text style={{ ...styles.lineText, color: activeLine == line ? theme.secondary : theme.normal30 }}>{lrc.text}</Text>
{
lrc.translation
? <Text style={{ ...styles.lineTranslationText, color: activeLine == line ? theme.secondary : theme.normal30 }}>{lrc.translation}</Text>
: null
}
</View>
) )
}, (prevProps, nextProps) => { }, (prevProps, nextProps) => {
return prevProps.text == nextProps.text && return prevProps.text == nextProps.text &&
@ -111,7 +118,7 @@ export default memo(() => {
const handleRenderItem = ({ item, index }) => { const handleRenderItem = ({ item, index }) => {
return ( return (
<LrcLine text={item.text} line={index} activeLine={line} /> <LrcLine lrc={item} line={index} activeLine={line} />
) )
} }
@ -148,12 +155,23 @@ const styles = StyleSheet.create({
paddingTop: '80%', paddingTop: '80%',
}, },
line: { line: {
borderRadius: 4, paddingTop: 8,
textAlign: 'center', paddingBottom: 8,
fontSize: 16,
lineHeight: 22,
paddingTop: 5,
paddingBottom: 5,
// opacity: 0, // opacity: 0,
}, },
lineText: {
textAlign: 'center',
fontSize: 16,
lineHeight: 20,
// paddingTop: 5,
// paddingBottom: 5,
// opacity: 0,
},
lineTranslationText: {
textAlign: 'center',
fontSize: 13,
lineHeight: 17,
paddingTop: 5,
// paddingBottom: 5,
},
}) })

View File

@ -34,6 +34,7 @@ export const TYPES = {
setTimeoutExit: null, setTimeoutExit: null,
setIsHandleAudioFocus: null, setIsHandleAudioFocus: null,
setAddMusicLocationType: null, setAddMusicLocationType: null,
setIsShowLyricTranslation: null,
} }
for (const key of Object.keys(TYPES)) { for (const key of Object.keys(TYPES)) {
TYPES[key] = `common__${key}` TYPES[key] = `common__${key}`
@ -280,3 +281,13 @@ export const setAddMusicLocationType = type => async(dispatch, getState) => {
await setData(settingKey, common.setting) await setData(settingKey, common.setting)
} }
export const setIsShowLyricTranslation = flag => async(dispatch, getState) => {
dispatch(playerAction.toggleTranslation(flag))
dispatch({
type: TYPES.setIsShowLyricTranslation,
payload: flag,
})
const { common } = getState()
await setData(settingKey, common.setting)
}

View File

@ -44,6 +44,7 @@ export const sourceNameType = state => state.common.setting.sourceNameType
export const timeoutExit = state => state.common.setting.player.timeoutExit export const timeoutExit = state => state.common.setting.player.timeoutExit
export const timeoutExitPlayed = state => state.common.setting.player.timeoutExitPlayed export const timeoutExitPlayed = state => state.common.setting.player.timeoutExitPlayed
export const isShowLyricTranslation = state => state.common.setting.player.isShowTranslation
export const activeApiSourceId = state => state.common.setting.apiSource export const activeApiSourceId = state => state.common.setting.apiSource

View File

@ -274,6 +274,18 @@ const mutations = {
}, },
} }
}, },
[TYPES.setIsShowLyricTranslation](state, isShowTranslation) {
return {
...state,
setting: {
...state.setting,
player: {
...state.setting.player,
isShowTranslation,
},
},
}
},
[TYPES.setVersionInfo](state, versionInfo) { [TYPES.setVersionInfo](state, versionInfo) {
return { return {
...state, ...state,

View File

@ -17,7 +17,7 @@ import {
import { getRandom } from '@/utils' import { getRandom } from '@/utils'
import { getMusicUrl, saveMusicUrl, getLyric, saveLyric, assertApiSupport, savePlayInfo, saveList } from '@/utils/tools' import { getMusicUrl, saveMusicUrl, getLyric, saveLyric, assertApiSupport, savePlayInfo, saveList } from '@/utils/tools'
import { playInfo as playInfoGetter } from './getter' import { playInfo as playInfoGetter } from './getter'
import { play as lrcPlay, setLyric, pause as lrcPause } from '@/plugins/lyric' import { play as lrcPlay, setLyric, pause as lrcPause, toggleTranslation as lrcToggleTranslation } from '@/plugins/lyric'
import { action as listAction } from '@/store/modules/list' import { action as listAction } from '@/store/modules/list'
import { LIST_ID_PLAY_LATER } from '@/config/constant' import { LIST_ID_PLAY_LATER } from '@/config/constant'
// import { defaultList } from '../list/getter' // import { defaultList } from '../list/getter'
@ -135,8 +135,8 @@ const handlePlayMusic = async({ getState, dispatch, playMusicInfo, musicInfo, is
}) })
} }
dispatch(getLrc(musicInfo)).then(({ lyric, tlyric }) => { dispatch(getLrc(musicInfo)).then(({ lyric, tlyric }) => {
setLyric(lyric)
const player = getState().player const player = getState().player
setLyric(lyric, tlyric)
if (player.status == STATUS.playing && !player.isGettingUrl) { if (player.status == STATUS.playing && !player.isGettingUrl) {
getPosition().then(position => { getPosition().then(position => {
lrcPlay(position * 1000) lrcPlay(position * 1000)
@ -199,8 +199,8 @@ const handlePlayMusic = async({ getState, dispatch, playMusicInfo, musicInfo, is
} }
dispatch(getLrc(musicInfo)).then(({ lyric, tlyric }) => { dispatch(getLrc(musicInfo)).then(({ lyric, tlyric }) => {
if (playMusicId != id) return if (playMusicId != id) return
setLyric(lyric)
const player = getState().player const player = getState().player
setLyric(lyric, tlyric)
if (player.status == STATUS.playing && !player.isGettingUrl) { if (player.status == STATUS.playing && !player.isGettingUrl) {
getPosition().then(position => { getPosition().then(position => {
lrcPlay(position * 1000) lrcPlay(position * 1000)
@ -742,6 +742,16 @@ export const setListInfo = listInfo => ({
payload: listInfo, payload: listInfo,
}) })
export const toggleTranslation = isShow => async(dispatch, getState) => {
lrcToggleTranslation(isShow)
const player = getState().player
if (player.status == STATUS.playing && !player.isGettingUrl) {
getPosition().then(position => {
lrcPlay(position * 1000)
})
}
}
export const checkPlayList = listIds => async(dispatch, getState) => { export const checkPlayList = listIds => async(dispatch, getState) => {
const { player, list: listState } = getState() const { player, list: listState } = getState()
if (!_playMusicInfo || !listIds.some(id => player.listInfo.id === id)) return if (!_playMusicInfo || !listIds.some(id => player.listInfo.id === id)) return