From 3ef0500240125efd26d1df3c27d346cd87102cf5 Mon Sep 17 00:00:00 2001 From: lovegaoshi <106490582+lovegaoshi@users.noreply.github.com> Date: Tue, 14 May 2024 16:35:16 -0700 Subject: [PATCH 01/11] feat: cached lrc --- src/components/lyric/LyricSearchBar.tsx | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/src/components/lyric/LyricSearchBar.tsx b/src/components/lyric/LyricSearchBar.tsx index dc64e81..63f3024 100644 --- a/src/components/lyric/LyricSearchBar.tsx +++ b/src/components/lyric/LyricSearchBar.tsx @@ -1,4 +1,4 @@ -import React, { useState, useEffect } from 'react'; +import React, { useState, useEffect, useRef } from 'react'; import TextField from '@mui/material/TextField'; import Autocomplete from '@mui/material/Autocomplete'; @@ -20,6 +20,7 @@ export default function LyricSearchBar({ }: Props) { const setLyricMapping = useNoxSetting((state) => state.setLyricMapping); const lyricMapping = useNoxSetting((state) => state.lyricMapping); + const cachedLrc = useRef(['', '']); const [options, setOptions] = useState([]); const [value, setValue] = useState({ key: '', @@ -49,7 +50,9 @@ export default function LyricSearchBar({ } function initLyric() { const detail = lyricMapping.get(currentAudio.id); - if (undefined !== detail) { + if (detail !== undefined) { + if (cachedLrc.current[0] === detail.lyricKey) + setLyric(cachedLrc.current[1]!); setLyricOffset(detail.lyricOffset); const index = options.findIndex((v) => v.songMid === detail.lyricKey); if (index !== -1) { @@ -72,15 +75,16 @@ export default function LyricSearchBar({ const onOptionSet = (_: any, newValue?: NoxNetwork.NoxFetchedLyric) => { if (newValue === undefined) return; setValue(newValue); - searchLyric(newValue.songMid, newValue.source).then(setLyric); + searchLyric(newValue.songMid, newValue.source).then((v) => { + setLyric(v); + cachedLrc.current = [newValue.key, v]; + }); setLyricMapping({ songId: currentAudio.id, lyricKey: newValue.key, }); }; - // //console.log("SearchBarValue:", options) - return (
Date: Tue, 14 May 2024 16:37:56 -0700 Subject: [PATCH 02/11] feat: cached lrc --- src/components/lyric/LyricSearchBar.tsx | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/src/components/lyric/LyricSearchBar.tsx b/src/components/lyric/LyricSearchBar.tsx index 63f3024..3a04cd6 100644 --- a/src/components/lyric/LyricSearchBar.tsx +++ b/src/components/lyric/LyricSearchBar.tsx @@ -6,12 +6,15 @@ import { useNoxSetting } from '@APM/stores/useApp'; import { searchLyricOptions, searchLyric } from '@APM/utils/LyricFetch'; import { LrcSource } from '@enums/LyricFetch'; +let cachedLrc = ['', '']; + interface Props { searchKey: string; currentAudio: NoxMedia.Song; setLyric: (v: string) => void; setLyricOffset: (v: number) => void; } + export default function LyricSearchBar({ searchKey, currentAudio, @@ -20,7 +23,6 @@ export default function LyricSearchBar({ }: Props) { const setLyricMapping = useNoxSetting((state) => state.setLyricMapping); const lyricMapping = useNoxSetting((state) => state.lyricMapping); - const cachedLrc = useRef(['', '']); const [options, setOptions] = useState([]); const [value, setValue] = useState({ key: '', @@ -51,8 +53,7 @@ export default function LyricSearchBar({ function initLyric() { const detail = lyricMapping.get(currentAudio.id); if (detail !== undefined) { - if (cachedLrc.current[0] === detail.lyricKey) - setLyric(cachedLrc.current[1]!); + if (cachedLrc[0] === detail.lyricKey) setLyric(cachedLrc[1]!); setLyricOffset(detail.lyricOffset); const index = options.findIndex((v) => v.songMid === detail.lyricKey); if (index !== -1) { @@ -77,7 +78,7 @@ export default function LyricSearchBar({ setValue(newValue); searchLyric(newValue.songMid, newValue.source).then((v) => { setLyric(v); - cachedLrc.current = [newValue.key, v]; + cachedLrc = [newValue.key, v]; }); setLyricMapping({ songId: currentAudio.id, From 9731a62aa58c7ed195fc5e929b330382ba845119 Mon Sep 17 00:00:00 2001 From: lovegaoshi <106490582+lovegaoshi@users.noreply.github.com> Date: Wed, 15 May 2024 09:39:55 -0700 Subject: [PATCH 03/11] chore: dep upgrade --- package.json | 2 +- src/azusa-player-mobile | 2 +- src/components/lyric/LyricSearchBar.tsx | 2 +- yarn.lock | 10 +++++----- 4 files changed, 8 insertions(+), 8 deletions(-) diff --git a/package.json b/package.json index a10becc..2d7bc0d 100644 --- a/package.json +++ b/package.json @@ -96,7 +96,7 @@ "he": "^1.2.0", "i18next": "^23.11.4", "libmuse": "git+https://github.com/lovegaoshi/muse.git#apm-release", - "material-ui-confirm": "^3.0.14", + "material-ui-confirm": "^3.0.15", "md5": "^2.3.0", "notistack": "^3.0.1", "octokit": "^4.0.2", diff --git a/src/azusa-player-mobile b/src/azusa-player-mobile index 547a8c3..7a6e943 160000 --- a/src/azusa-player-mobile +++ b/src/azusa-player-mobile @@ -1 +1 @@ -Subproject commit 547a8c3a6e0f1c9923ac2be9a9612effb09ecb18 +Subproject commit 7a6e943d2f896993ba21e6847d09f7c2bee8cd52 diff --git a/src/components/lyric/LyricSearchBar.tsx b/src/components/lyric/LyricSearchBar.tsx index 3a04cd6..42d1ba3 100644 --- a/src/components/lyric/LyricSearchBar.tsx +++ b/src/components/lyric/LyricSearchBar.tsx @@ -1,4 +1,4 @@ -import React, { useState, useEffect, useRef } from 'react'; +import React, { useState, useEffect } from 'react'; import TextField from '@mui/material/TextField'; import Autocomplete from '@mui/material/Autocomplete'; diff --git a/yarn.lock b/yarn.lock index cd694ad..7b4a928 100644 --- a/yarn.lock +++ b/yarn.lock @@ -8919,14 +8919,14 @@ __metadata: languageName: node linkType: hard -"material-ui-confirm@npm:^3.0.14": - version: 3.0.14 - resolution: "material-ui-confirm@npm:3.0.14" +"material-ui-confirm@npm:^3.0.15": + version: 3.0.15 + resolution: "material-ui-confirm@npm:3.0.15" peerDependencies: "@mui/material": ">= 5.0.0" react: ^17.0.0 || ^18.0.0 react-dom: ^17.0.0 || ^18.0.0 - checksum: 10c0/8b7fb9ea9b00beb55fae1726112ee389cff82a1a41b8bd6635b9bf413ed562e417d3092137c547d80a6c270070db19d24ac2ff41cb98bc4fa9c9c8ba68f6d6b3 + checksum: 10c0/d0f7bd20e90ff6f733d36815c06e8a8fc177bb010a7e7b4557dcc23fb2d3549bc998f31f52d4c3120fec16daed911ba594678e2c5fe7fc1309f048a5d97c7c84 languageName: node linkType: hard @@ -9644,7 +9644,7 @@ __metadata: i18next: "npm:^23.11.4" libmuse: "git+https://github.com/lovegaoshi/muse.git#apm-release" lodash: "npm:^4.17.21" - material-ui-confirm: "npm:^3.0.14" + material-ui-confirm: "npm:^3.0.15" md5: "npm:^2.3.0" mini-css-extract-plugin: "npm:^2.9.0" node-sass: "npm:^9.0.0" From b4ff231d171dfbf3160e73a0623dbff3d4846b1f Mon Sep 17 00:00:00 2001 From: lovegaoshi <106490582+lovegaoshi@users.noreply.github.com> Date: Wed, 15 May 2024 10:10:50 -0700 Subject: [PATCH 04/11] Update azusa-player-mobile --- src/azusa-player-mobile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/azusa-player-mobile b/src/azusa-player-mobile index 7a6e943..587b511 160000 --- a/src/azusa-player-mobile +++ b/src/azusa-player-mobile @@ -1 +1 @@ -Subproject commit 7a6e943d2f896993ba21e6847d09f7c2bee8cd52 +Subproject commit 587b5118cc3555a9bb0966cc50214a7dee588ce1 From 1e47649cfe94d4df6933904b03899767789141f6 Mon Sep 17 00:00:00 2001 From: lovegaoshi <106490582+lovegaoshi@users.noreply.github.com> Date: Wed, 15 May 2024 10:14:39 -0700 Subject: [PATCH 05/11] chore: refactor useLyric --- src/components/lyric/LyricSearchBar.tsx | 14 ++++---------- src/hooks/useLyric.ts | 12 ++++++++++++ 2 files changed, 16 insertions(+), 10 deletions(-) create mode 100644 src/hooks/useLyric.ts diff --git a/src/components/lyric/LyricSearchBar.tsx b/src/components/lyric/LyricSearchBar.tsx index 42d1ba3..aa94bdd 100644 --- a/src/components/lyric/LyricSearchBar.tsx +++ b/src/components/lyric/LyricSearchBar.tsx @@ -4,7 +4,7 @@ import Autocomplete from '@mui/material/Autocomplete'; import { useNoxSetting } from '@APM/stores/useApp'; import { searchLyricOptions, searchLyric } from '@APM/utils/LyricFetch'; -import { LrcSource } from '@enums/LyricFetch'; +import useLyric from '@hooks/useLyric'; let cachedLrc = ['', '']; @@ -21,6 +21,7 @@ export default function LyricSearchBar({ setLyric, setLyricOffset, }: Props) { + const { fetchAndSetLyricOptions } = useLyric(currentAudio); const setLyricMapping = useNoxSetting((state) => state.setLyricMapping); const lyricMapping = useNoxSetting((state) => state.lyricMapping); const [options, setOptions] = useState([]); @@ -34,15 +35,8 @@ export default function LyricSearchBar({ useEffect(() => { (async () => { if (searchKey === '') return; - const resolvedOptions = await Promise.all([ - searchLyricOptions({ searchKey }), - searchLyricOptions({ - searchKey, - source: LrcSource.BiliBili, - song: currentAudio, - }), - ]); - setOptions(resolvedOptions.flat()); + const resolvedOptions = await fetchAndSetLyricOptions(searchKey); + setOptions(resolvedOptions); })(); }, [searchKey]); diff --git a/src/hooks/useLyric.ts b/src/hooks/useLyric.ts new file mode 100644 index 0000000..50ff4d2 --- /dev/null +++ b/src/hooks/useLyric.ts @@ -0,0 +1,12 @@ +import useLyric from '@APM/hooks/useLyric'; +import { LrcSource } from '@enums/LyricFetch'; + +export default (song: NoxMedia.Song) => { + const usedLyric = useLyric(song); + const fetchAndSetLyricOptions = (adhocTitle = song.name) => + usedLyric.fetchAndSetLyricOptions(adhocTitle, [ + LrcSource.QQ, + LrcSource.BiliBili, + ]); + return { ...usedLyric, fetchAndSetLyricOptions }; +}; From 868e28f0b65cbcec72e247f2371cd6c964736dff Mon Sep 17 00:00:00 2001 From: lovegaoshi <106490582+lovegaoshi@users.noreply.github.com> Date: Wed, 15 May 2024 12:40:36 -0700 Subject: [PATCH 06/11] chore: refactor useLyric --- src/azusa-player-mobile | 2 +- src/components/lyric/LyricControl.tsx | 0 src/components/lyric/LyricSearchBar.tsx | 68 +++++-------------- src/hooks/useLyric.ts | 86 ++++++++++++++++++++++++- src/utils/Logger.ts | 4 ++ 5 files changed, 106 insertions(+), 54 deletions(-) create mode 100644 src/components/lyric/LyricControl.tsx diff --git a/src/azusa-player-mobile b/src/azusa-player-mobile index 587b511..ee788fe 160000 --- a/src/azusa-player-mobile +++ b/src/azusa-player-mobile @@ -1 +1 @@ -Subproject commit 587b5118cc3555a9bb0966cc50214a7dee588ce1 +Subproject commit ee788fec4a3ba883a6aba58cca836db657db6964 diff --git a/src/components/lyric/LyricControl.tsx b/src/components/lyric/LyricControl.tsx new file mode 100644 index 0000000..e69de29 diff --git a/src/components/lyric/LyricSearchBar.tsx b/src/components/lyric/LyricSearchBar.tsx index aa94bdd..ab1fc31 100644 --- a/src/components/lyric/LyricSearchBar.tsx +++ b/src/components/lyric/LyricSearchBar.tsx @@ -1,13 +1,9 @@ -import React, { useState, useEffect } from 'react'; +import React, { useEffect } from 'react'; import TextField from '@mui/material/TextField'; import Autocomplete from '@mui/material/Autocomplete'; -import { useNoxSetting } from '@APM/stores/useApp'; -import { searchLyricOptions, searchLyric } from '@APM/utils/LyricFetch'; import useLyric from '@hooks/useLyric'; -let cachedLrc = ['', '']; - interface Props { searchKey: string; currentAudio: NoxMedia.Song; @@ -19,65 +15,33 @@ export default function LyricSearchBar({ searchKey, currentAudio, setLyric, - setLyricOffset, }: Props) { - const { fetchAndSetLyricOptions } = useLyric(currentAudio); - const setLyricMapping = useNoxSetting((state) => state.setLyricMapping); - const lyricMapping = useNoxSetting((state) => state.lyricMapping); - const [options, setOptions] = useState([]); - const [value, setValue] = useState({ - key: '', - songMid: '', - label: '', - }); + const { + fetchAndSetLyricOptions, + initTrackLrcLoad, + lrcOptions, + lrcOption, + searchAndSetCurrentLyric, + } = useLyric(currentAudio); // Initializes options useEffect(() => { - (async () => { + (() => { if (searchKey === '') return; - const resolvedOptions = await fetchAndSetLyricOptions(searchKey); - setOptions(resolvedOptions); + fetchAndSetLyricOptions(searchKey); })(); }, [searchKey]); useEffect(() => { - if (options.length === 0) { + if (lrcOptions.length === 0) { return; } - function initLyric() { - const detail = lyricMapping.get(currentAudio.id); - if (detail !== undefined) { - if (cachedLrc[0] === detail.lyricKey) setLyric(cachedLrc[1]!); - setLyricOffset(detail.lyricOffset); - const index = options.findIndex((v) => v.songMid === detail.lyricKey); - if (index !== -1) { - onOptionSet({}, options[index]); - return; - } - - options.unshift({ - key: detail.lyricKey, - songMid: detail.lyricKey, - label: detail.songId, - }); - setOptions(options); - } - onOptionSet({}, options[0]); - } - initLyric(); - }, [options]); + initTrackLrcLoad(); + }, [lrcOptions]); const onOptionSet = (_: any, newValue?: NoxNetwork.NoxFetchedLyric) => { if (newValue === undefined) return; - setValue(newValue); - searchLyric(newValue.songMid, newValue.source).then((v) => { - setLyric(v); - cachedLrc = [newValue.key, v]; - }); - setLyricMapping({ - songId: currentAudio.id, - lyricKey: newValue.key, - }); + searchAndSetCurrentLyric(0, [newValue]); }; return ( @@ -85,9 +49,9 @@ export default function LyricSearchBar({ } diff --git a/src/hooks/useLyric.ts b/src/hooks/useLyric.ts index 50ff4d2..82e530d 100644 --- a/src/hooks/useLyric.ts +++ b/src/hooks/useLyric.ts @@ -1,6 +1,10 @@ import useLyric from '@APM/hooks/useLyric'; import { LrcSource } from '@enums/LyricFetch'; +// HACK: instead of a local lrc cache, just use a simple global var cache...? +// TODO: make a proper cache +let cachedLrc = ['', '']; + export default (song: NoxMedia.Song) => { const usedLyric = useLyric(song); const fetchAndSetLyricOptions = (adhocTitle = song.name) => @@ -8,5 +12,85 @@ export default (song: NoxMedia.Song) => { LrcSource.QQ, LrcSource.BiliBili, ]); - return { ...usedLyric, fetchAndSetLyricOptions }; + + const getLrcFromLocal = async (song?: NoxMedia.Song) => { + const lrcDetail = usedLyric.getLrcFromLocal(song); + if (lrcDetail === undefined) return; + const localLrc = + cachedLrc[0] === lrcDetail.lyricKey ? cachedLrc[1]! : lrcDetail.lyric; + console.log(localLrc); + return { + lrcDetail, + localLrc, + }; + }; + + const loadLocalLrc = async ( + lyricPromise: Promise, + ) => { + const localLrcColle = getLrcFromLocal(song); + return usedLyric.loadLocalLrc(getLrcFromLocal(song), async () => + searchAndSetCurrentLyric( + undefined, + await lyricPromise, + (await localLrcColle)?.lrcDetail, + ), + ); + }; + + const updateLyricMapping = ({ + resolvedLrc, + newLrcDetail = {}, + song, + lrc, + currentTimeOffset, + }: { + resolvedLrc?: NoxNetwork.NoxFetchedLyric; + newLrcDetail?: Partial; + lrc: string; + song: NoxMedia.Song; + currentTimeOffset: number; + }) => { + if (resolvedLrc) { + const lyricDeatail: NoxMedia.LyricDetail = { + songId: song.id, + lyricKey: resolvedLrc.key, + lyricOffset: currentTimeOffset, + ...newLrcDetail, + // TODO: do not store this in ChromeStorage that can be synced + lyric: '', + source: resolvedLrc.source, + }; + cachedLrc = [lyricDeatail.lyricKey, lrc]; + usedLyric.setLyricMapping(lyricDeatail); + } + }; + + const searchAndSetCurrentLyric = ( + index = 0, + resolvedLrcOptions = usedLyric.lrcOptions, + resolvedLyric?: NoxMedia.LyricDetail, + mSong = song, + ) => + usedLyric.searchAndSetCurrentLyric( + updateLyricMapping, + index, + resolvedLrcOptions, + resolvedLyric, + mSong, + ); + + const initTrackLrcLoad = () => + usedLyric.initTrackLrcLoad( + fetchAndSetLyricOptions, + loadLocalLrc, + searchAndSetCurrentLyric, + ); + + return { + ...usedLyric, + fetchAndSetLyricOptions, + initTrackLrcLoad, + searchAndSetCurrentLyric, + }; }; diff --git a/src/utils/Logger.ts b/src/utils/Logger.ts index 4d172fc..e8d4d47 100644 --- a/src/utils/Logger.ts +++ b/src/utils/Logger.ts @@ -18,6 +18,10 @@ class Logger { console.info(this.generateMessage(message)); } + log(message: unknown) { + this.info(message); + } + notice(message: unknown) { console.warn(this.generateMessage(message)); } From d8f9327fc816e3cd54ab6600732d6ad8ca4f2d29 Mon Sep 17 00:00:00 2001 From: lovegaoshi <106490582+lovegaoshi@users.noreply.github.com> Date: Wed, 15 May 2024 12:55:36 -0700 Subject: [PATCH 07/11] chore: refactor useLyric --- src/components/App/App.tsx | 1 - src/components/lyric/Lyric.tsx | 10 ++++------ src/components/lyric/LyricOverlay.tsx | 6 ++---- src/components/lyric/LyricSearchBar.tsx | 10 ++-------- src/stores/useApp.ts | 11 ++--------- src/types | 1 - src/utils/types/NoxMedia.d.ts | 8 ++++++++ 7 files changed, 18 insertions(+), 29 deletions(-) delete mode 120000 src/types create mode 100644 src/utils/types/NoxMedia.d.ts diff --git a/src/components/App/App.tsx b/src/components/App/App.tsx index 25b1cd4..7154dd2 100644 --- a/src/components/App/App.tsx +++ b/src/components/App/App.tsx @@ -72,7 +72,6 @@ export default function Player({ songList }: Props) { setShowLyric(false)} /> )} diff --git a/src/components/lyric/Lyric.tsx b/src/components/lyric/Lyric.tsx index 8e4cc7b..31fb9ce 100644 --- a/src/components/lyric/Lyric.tsx +++ b/src/components/lyric/Lyric.tsx @@ -26,8 +26,7 @@ const styles = () => ({ }); interface Props { - currentAudio: NoxMedia.Song; - currentTime: number; + currentAudio: NoxMediaChrome.RJKMAudio; } interface LineRenderer { @@ -49,7 +48,7 @@ export default withStyles(styles)((props: Props) => { // HACK: how to do this..? // @ts-ignore - const { classes, currentTime, currentAudio } = props; + const { classes, currentAudio } = props; const audioName = getName(currentAudio); useEffect(() => { @@ -94,6 +93,7 @@ export default withStyles(styles)((props: Props) => { // //console.log(+currentTime * 1000 + +lyricOffset) const className = ScrollBar().root; + console.log('rerender'); return ( @@ -141,8 +141,6 @@ export default withStyles(styles)((props: Props) => { @@ -153,7 +151,7 @@ export default withStyles(styles)((props: Props) => { style={mStyles.lrc} lrc={lyric} lineRenderer={lineRenderer} - currentMillisecond={+currentTime * 1000 + +lyricOffset} // Add offset value to adapt lrc time + currentMillisecond={+currentAudio.currentTime * 1000 + +lyricOffset} // Add offset value to adapt lrc time recoverAutoScrollInterval={5000} /> diff --git a/src/components/lyric/LyricOverlay.tsx b/src/components/lyric/LyricOverlay.tsx index 10d500b..4120da4 100644 --- a/src/components/lyric/LyricOverlay.tsx +++ b/src/components/lyric/LyricOverlay.tsx @@ -17,15 +17,13 @@ const Transition = React.forwardRef(function Transition( }); interface Props { - currentAudio: NoxMedia.Song; + currentAudio: NoxMediaChrome.RJKMAudio; showLyric: boolean; - currentTime: number; closeLyric?: () => void; } export default function LyricOverlay({ currentAudio, showLyric, - currentTime, closeLyric = () => {}, }: Props) { return ( @@ -60,7 +58,7 @@ export default function LyricOverlay({ > - +
diff --git a/src/components/lyric/LyricSearchBar.tsx b/src/components/lyric/LyricSearchBar.tsx index ab1fc31..fd829d2 100644 --- a/src/components/lyric/LyricSearchBar.tsx +++ b/src/components/lyric/LyricSearchBar.tsx @@ -7,15 +7,9 @@ import useLyric from '@hooks/useLyric'; interface Props { searchKey: string; currentAudio: NoxMedia.Song; - setLyric: (v: string) => void; - setLyricOffset: (v: number) => void; } -export default function LyricSearchBar({ - searchKey, - currentAudio, - setLyric, -}: Props) { +export default function LyricSearchBar({ searchKey, currentAudio }: Props) { const { fetchAndSetLyricOptions, initTrackLrcLoad, @@ -36,7 +30,7 @@ export default function LyricSearchBar({ if (lrcOptions.length === 0) { return; } - initTrackLrcLoad(); + // initTrackLrcLoad(); }, [lrcOptions]); const onOptionSet = (_: any, newValue?: NoxNetwork.NoxFetchedLyric) => { diff --git a/src/stores/useApp.ts b/src/stores/useApp.ts index a9afe47..a097388 100644 --- a/src/stores/useApp.ts +++ b/src/stores/useApp.ts @@ -6,16 +6,9 @@ import { Skin } from '@styles/skins/template'; export * from '@APM/stores/useApp'; -// this is a special audio intance that is passed from react-music-player -// TODO: fill in the types -// it extends NoxMedia.Song -interface RJKMAudio extends NoxMedia.Song { - [key: string]: any; -} - interface NoxApp { - currentAudio?: RJKMAudio; - setCurrentAudio: (a: RJKMAudio) => void; + currentAudio?: NoxMediaChrome.RJKMAudio; + setCurrentAudio: (a: NoxMediaChrome.RJKMAudio) => void; currentAudioInst?: ReactJkMusicPlayerInstance; setCurrentAudioInst: (a: ReactJkMusicPlayerInstance) => void; // This is here instead of being replaced by currentPlayingList, diff --git a/src/types b/src/types deleted file mode 120000 index 3be798c..0000000 --- a/src/types +++ /dev/null @@ -1 +0,0 @@ -../src/azusa-player-mobile/src/types/ \ No newline at end of file diff --git a/src/utils/types/NoxMedia.d.ts b/src/utils/types/NoxMedia.d.ts new file mode 100644 index 0000000..4a7ea1f --- /dev/null +++ b/src/utils/types/NoxMedia.d.ts @@ -0,0 +1,8 @@ +namespace NoxMediaChrome { + // this is a special audio intance that is passed from react-music-player + // TODO: fill in the types + // it extends NoxMedia.Song + export interface RJKMAudio extends NoxMedia.Song { + [key: string]: any; + } +} From 2a08b4fc63012e63c340d79059d73f85d222c350 Mon Sep 17 00:00:00 2001 From: lovegaoshi <106490582+lovegaoshi@users.noreply.github.com> Date: Wed, 15 May 2024 12:59:02 -0700 Subject: [PATCH 08/11] chore: wdyr --- package.json | 1 + src/popup/index.tsx | 1 + src/popup/wdyr.ts | 9 +++++++++ yarn.lock | 14 +++++++++++++- 4 files changed, 24 insertions(+), 1 deletion(-) create mode 100644 src/popup/wdyr.ts diff --git a/package.json b/package.json index 2d7bc0d..0fe826f 100644 --- a/package.json +++ b/package.json @@ -26,6 +26,7 @@ "@types/uuid": "^9.0.8", "@typescript-eslint/eslint-plugin": "^7.9.0", "@typescript-eslint/parser": "^7.9.0", + "@welldone-software/why-did-you-render": "^8.0.1", "babel-loader": "^9.1.3", "clean-webpack-plugin": "^4.0.0", "copy-webpack-plugin": "12.0.2", diff --git a/src/popup/index.tsx b/src/popup/index.tsx index e47f1cd..d2b9efb 100644 --- a/src/popup/index.tsx +++ b/src/popup/index.tsx @@ -1,3 +1,4 @@ +import './wdyr'; // <--- first import import '../css/popup.css'; import React from 'react'; import { createRoot } from 'react-dom/client'; diff --git a/src/popup/wdyr.ts b/src/popup/wdyr.ts new file mode 100644 index 0000000..00e8b6e --- /dev/null +++ b/src/popup/wdyr.ts @@ -0,0 +1,9 @@ +/// +import React from 'react'; + +if (process.env.DEV === 'dev') { + const whyDidYouRender = require('@welldone-software/why-did-you-render'); + whyDidYouRender(React, { + trackAllPureComponents: true, + }); +} diff --git a/yarn.lock b/yarn.lock index 7b4a928..6d4d2f0 100644 --- a/yarn.lock +++ b/yarn.lock @@ -3569,6 +3569,17 @@ __metadata: languageName: node linkType: hard +"@welldone-software/why-did-you-render@npm:^8.0.1": + version: 8.0.1 + resolution: "@welldone-software/why-did-you-render@npm:8.0.1" + dependencies: + lodash: "npm:^4" + peerDependencies: + react: ^18 + checksum: 10c0/dec9ec4fcdb146e4830dff212262f9a9ce5752651055db3cec13f5a49fa6e2f5d61be6728ee01dd6d32e79525d433247f0ec1878401811600424c745a785908f + languageName: node + linkType: hard + "@xtuc/ieee754@npm:^1.2.0": version: 1.2.0 resolution: "@xtuc/ieee754@npm:1.2.0" @@ -8772,7 +8783,7 @@ __metadata: languageName: node linkType: hard -"lodash@npm:^4.17.11, lodash@npm:^4.17.15, lodash@npm:^4.17.20, lodash@npm:^4.17.21": +"lodash@npm:^4, lodash@npm:^4.17.11, lodash@npm:^4.17.15, lodash@npm:^4.17.20, lodash@npm:^4.17.21": version: 4.17.21 resolution: "lodash@npm:4.17.21" checksum: 10c0/d8cbea072bb08655bb4c989da418994b073a608dffa608b09ac04b43a791b12aeae7cd7ad919aa4c925f33b48490b5cfe6c1f71d827956071dae2e7bb3a6b74c @@ -9606,6 +9617,7 @@ __metadata: "@types/uuid": "npm:^9.0.8" "@typescript-eslint/eslint-plugin": "npm:^7.9.0" "@typescript-eslint/parser": "npm:^7.9.0" + "@welldone-software/why-did-you-render": "npm:^8.0.1" axios: "npm:^1.6.8" babel-loader: "npm:^9.1.3" base-64: "npm:^1.0.0" From e937b0844962c0b753901d884cfe8f36b30a9ad5 Mon Sep 17 00:00:00 2001 From: lovegaoshi <106490582+lovegaoshi@users.noreply.github.com> Date: Wed, 15 May 2024 13:46:28 -0700 Subject: [PATCH 09/11] chore: refactor useLyric --- src/components/lyric/Lyric.tsx | 88 +++++++++++++++---------- src/components/lyric/LyricSearchBar.tsx | 18 ++--- src/hooks/usePlayback.ts | 11 +++- src/stores/useApp.ts | 4 ++ 4 files changed, 75 insertions(+), 46 deletions(-) diff --git a/src/components/lyric/Lyric.tsx b/src/components/lyric/Lyric.tsx index 31fb9ce..332ab6b 100644 --- a/src/components/lyric/Lyric.tsx +++ b/src/components/lyric/Lyric.tsx @@ -9,6 +9,7 @@ import { useNoxSetting } from '@APM/stores/useApp'; import { useDebouncedValue } from '@APM/hooks'; import useApp from '@stores/useApp'; import LyricSearchBar from './LyricSearchBar'; +import useLyric from '@hooks/useLyric'; const styles = () => ({ inputOffset: { @@ -38,11 +39,53 @@ interface LineRenderer { active: boolean; } +interface LrcViewProps { + lyricOffset: number; + lrc: string; + className: string; +} + +const LrcView = ({ lyricOffset, lrc, className }: LrcViewProps) => { + const currentProgress = useApp((state) => state.currentProgress); + const { colorTheme } = useApp((state) => state.playerStyle); + + const lineRenderer = useCallback( + ({ line: { content }, active }: LineRenderer) => { + // //console.log(content) + return ( +
+ {content} +
+ ); + }, + [], + ); + + return ( + + ); +}; + export default withStyles(styles)((props: Props) => { const setLyricMapping = useNoxSetting((state) => state.setLyricMapping); const { colorTheme, ScrollBar } = useApp((state) => state.playerStyle); - const [lyricOffset, setLyricOffset] = useState(0); - const [lyric, setLyric] = useState(''); const [songTitle, setSongTitle] = useState(''); const debouncedSongTitle = useDebouncedValue(songTitle, 1000); @@ -50,6 +93,7 @@ export default withStyles(styles)((props: Props) => { // @ts-ignore const { classes, currentAudio } = props; const audioName = getName(currentAudio); + const usedLyric = useLyric(currentAudio); useEffect(() => { // console.log('Lrc changed to %s', extractedName) @@ -61,39 +105,15 @@ export default withStyles(styles)((props: Props) => { e: React.ChangeEvent, ) => { const lyricOffset = Number(e.target.value); - setLyricOffset(lyricOffset); + usedLyric.setCurrentTimeOffset(lyricOffset); setLyricMapping({ songId: currentAudio.id, lyricOffset, - lyric, + lyric: usedLyric.lrc, }); }; - const lineRenderer = useCallback( - ({ line: { content }, active }: LineRenderer) => { - // //console.log(content) - return ( -
- {content} -
- ); - }, - [], - ); - - // //console.log(+currentTime * 1000 + +lyricOffset) const className = ScrollBar().root; - console.log('rerender'); return ( @@ -119,7 +139,7 @@ export default withStyles(styles)((props: Props) => { InputProps={{ className: classes.inputOffset, }} - value={lyricOffset} + value={usedLyric.currentTimeOffset} onChange={onLrcOffsetChange} /> { - diff --git a/src/components/lyric/LyricSearchBar.tsx b/src/components/lyric/LyricSearchBar.tsx index fd829d2..d7a9695 100644 --- a/src/components/lyric/LyricSearchBar.tsx +++ b/src/components/lyric/LyricSearchBar.tsx @@ -2,21 +2,24 @@ import React, { useEffect } from 'react'; import TextField from '@mui/material/TextField'; import Autocomplete from '@mui/material/Autocomplete'; -import useLyric from '@hooks/useLyric'; - interface Props { searchKey: string; currentAudio: NoxMedia.Song; + usedLyric: any; } -export default function LyricSearchBar({ searchKey, currentAudio }: Props) { +export default function LyricSearchBar({ + searchKey, + currentAudio, + usedLyric, +}: Props) { const { fetchAndSetLyricOptions, initTrackLrcLoad, lrcOptions, lrcOption, searchAndSetCurrentLyric, - } = useLyric(currentAudio); + } = usedLyric; // Initializes options useEffect(() => { @@ -27,11 +30,8 @@ export default function LyricSearchBar({ searchKey, currentAudio }: Props) { }, [searchKey]); useEffect(() => { - if (lrcOptions.length === 0) { - return; - } - // initTrackLrcLoad(); - }, [lrcOptions]); + initTrackLrcLoad(); + }, [currentAudio]); const onOptionSet = (_: any, newValue?: NoxNetwork.NoxFetchedLyric) => { if (newValue === undefined) return; diff --git a/src/hooks/usePlayback.ts b/src/hooks/usePlayback.ts index 422921f..373e120 100644 --- a/src/hooks/usePlayback.ts +++ b/src/hooks/usePlayback.ts @@ -32,6 +32,7 @@ export default () => { const setCurrentAudio = useApp((state) => state.setCurrentAudio); const currentAudioInst = useApp((state) => state.currentAudioInst); const setCurrentAudioInst = useApp((state) => state.setCurrentAudioInst); + const setCurrentProgress = useApp((state) => state.setCurrentProgress); const playingList = useApp((state) => state.playingList); const setplayingList = useApp((state) => state.setplayingList); const params = useApp((state) => state.params); @@ -171,6 +172,11 @@ export default () => { // console.log('audioListChange:', audioLists) const onAudioProgress = (audioInfo: any) => { + // HACK + if (showLyric) { + setCurrentProgress(audioInfo.currentTime); + } + return; // this is updated every 0.1sec or so. disabling this seems to make playing >3000 songs list // a tinny bit faster; the other slowing part is audioTimeUpdate's setState in JKmusicplayer. // its probably because with a huge songlist, updating musicplayer state recreatign it somehow and its very slow @@ -194,8 +200,9 @@ export default () => { }) .catch((err) => console.error(err)); }; - - const onCoverClick = () => setShowLyric(!showLyric); + // TODO: fix this + // @ts-expect-error + const onCoverClick = () => setShowLyric((v) => !v); const processExtendsContent = (extendsContent: any) => setparams({ ...params, extendsContent }); diff --git a/src/stores/useApp.ts b/src/stores/useApp.ts index a097388..b305ba4 100644 --- a/src/stores/useApp.ts +++ b/src/stores/useApp.ts @@ -11,6 +11,8 @@ interface NoxApp { setCurrentAudio: (a: NoxMediaChrome.RJKMAudio) => void; currentAudioInst?: ReactJkMusicPlayerInstance; setCurrentAudioInst: (a: ReactJkMusicPlayerInstance) => void; + currentProgress: number; + setCurrentProgress: (a: number) => void; // This is here instead of being replaced by currentPlayingList, // bc react-music-player needs it... playingList: NoxMedia.Song[]; @@ -37,6 +39,8 @@ export default create((set, _get) => { return { setCurrentAudio: (a) => set({ currentAudio: a }), setCurrentAudioInst: (a) => set({ currentAudioInst: a }), + currentProgress: 0, + setCurrentProgress: (a) => set({ currentProgress: a }), setplayingList: (a) => set({ playingList: a }), playingList: [], setparams: (a) => set({ params: a }), From 8e4e14835fdc9ea15cffcdf28699db51a20c1d3c Mon Sep 17 00:00:00 2001 From: lovegaoshi <106490582+lovegaoshi@users.noreply.github.com> Date: Wed, 15 May 2024 13:52:59 -0700 Subject: [PATCH 10/11] chore: refactor useLyric --- changelog.txt | 1 + src/azusa-player-mobile | 2 +- src/components/lyric/Lyric.tsx | 24 ++++++++---------------- src/components/lyric/LyricSearchBar.tsx | 24 +++--------------------- 4 files changed, 13 insertions(+), 38 deletions(-) diff --git a/changelog.txt b/changelog.txt index 9d7ca65..8d4b7b4 100644 --- a/changelog.txt +++ b/changelog.txt @@ -7,6 +7,7 @@ 3.1.9: github同步 +歌词性能提升 3.1.8: b站字幕歌词 diff --git a/src/azusa-player-mobile b/src/azusa-player-mobile index ee788fe..7750ac2 160000 --- a/src/azusa-player-mobile +++ b/src/azusa-player-mobile @@ -1 +1 @@ -Subproject commit ee788fec4a3ba883a6aba58cca836db657db6964 +Subproject commit 7750ac2884dd9a63b5b5315acb0594ff9c9e4919 diff --git a/src/components/lyric/Lyric.tsx b/src/components/lyric/Lyric.tsx index 332ab6b..33a65aa 100644 --- a/src/components/lyric/Lyric.tsx +++ b/src/components/lyric/Lyric.tsx @@ -5,7 +5,6 @@ import { withStyles } from '@mui/styles'; import Grid from '@mui/material/Grid'; import { getName } from '@APM/utils/re'; -import { useNoxSetting } from '@APM/stores/useApp'; import { useDebouncedValue } from '@APM/hooks'; import useApp from '@stores/useApp'; import LyricSearchBar from './LyricSearchBar'; @@ -84,7 +83,6 @@ const LrcView = ({ lyricOffset, lrc, className }: LrcViewProps) => { }; export default withStyles(styles)((props: Props) => { - const setLyricMapping = useNoxSetting((state) => state.setLyricMapping); const { colorTheme, ScrollBar } = useApp((state) => state.playerStyle); const [songTitle, setSongTitle] = useState(''); const debouncedSongTitle = useDebouncedValue(songTitle, 1000); @@ -101,17 +99,15 @@ export default withStyles(styles)((props: Props) => { setSongTitle(audioName); }, [audioName]); + useEffect(() => { + if (debouncedSongTitle.length > 0) { + usedLyric.fetchAndSetLyricOptions(debouncedSongTitle); + } + }, [debouncedSongTitle]); + const onLrcOffsetChange = ( e: React.ChangeEvent, - ) => { - const lyricOffset = Number(e.target.value); - usedLyric.setCurrentTimeOffset(lyricOffset); - setLyricMapping({ - songId: currentAudio.id, - lyricOffset, - lyric: usedLyric.lrc, - }); - }; + ) => usedLyric.onLrcOffsetChange(Number(e.target.value)); const className = ScrollBar().root; @@ -158,11 +154,7 @@ export default withStyles(styles)((props: Props) => { - + diff --git a/src/components/lyric/LyricSearchBar.tsx b/src/components/lyric/LyricSearchBar.tsx index d7a9695..7e98982 100644 --- a/src/components/lyric/LyricSearchBar.tsx +++ b/src/components/lyric/LyricSearchBar.tsx @@ -3,31 +3,13 @@ import TextField from '@mui/material/TextField'; import Autocomplete from '@mui/material/Autocomplete'; interface Props { - searchKey: string; currentAudio: NoxMedia.Song; usedLyric: any; } -export default function LyricSearchBar({ - searchKey, - currentAudio, - usedLyric, -}: Props) { - const { - fetchAndSetLyricOptions, - initTrackLrcLoad, - lrcOptions, - lrcOption, - searchAndSetCurrentLyric, - } = usedLyric; - - // Initializes options - useEffect(() => { - (() => { - if (searchKey === '') return; - fetchAndSetLyricOptions(searchKey); - })(); - }, [searchKey]); +export default function LyricSearchBar({ currentAudio, usedLyric }: Props) { + const { initTrackLrcLoad, lrcOptions, lrcOption, searchAndSetCurrentLyric } = + usedLyric; useEffect(() => { initTrackLrcLoad(); From a59be43b75f24eecf622f3e57ed2e8c5834602a4 Mon Sep 17 00:00:00 2001 From: lovegaoshi <106490582+lovegaoshi@users.noreply.github.com> Date: Wed, 15 May 2024 14:03:21 -0700 Subject: [PATCH 11/11] Delete LyricControl.tsx --- src/components/lyric/LyricControl.tsx | 0 1 file changed, 0 insertions(+), 0 deletions(-) delete mode 100644 src/components/lyric/LyricControl.tsx diff --git a/src/components/lyric/LyricControl.tsx b/src/components/lyric/LyricControl.tsx deleted file mode 100644 index e69de29..0000000