Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

chore: useLyric refactor #71

Merged
merged 11 commits into from
May 15, 2024
Merged
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion src/azusa-player-mobile
Empty file.
68 changes: 16 additions & 52 deletions src/components/lyric/LyricSearchBar.tsx
Original file line number Diff line number Diff line change
@@ -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,75 +15,43 @@ 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<NoxNetwork.NoxFetchedLyric[]>([]);
const [value, setValue] = useState<NoxNetwork.NoxFetchedLyric>({
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 (
<div>
<Autocomplete
disableClearable
onChange={onOptionSet}
value={value}
value={lrcOption}
id='LyricSearchBar'
options={options}
options={lrcOptions}
sx={{ width: 500 }}
size='small'
renderInput={(params) => <TextField {...params} label='歌词选择' />}
86 changes: 85 additions & 1 deletion src/hooks/useLyric.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,96 @@
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) =>
usedLyric.fetchAndSetLyricOptions(adhocTitle, [
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<NoxNetwork.NoxFetchedLyric[]>,
) => {
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<NoxMedia.LyricDetail>;
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,
};
};
4 changes: 4 additions & 0 deletions src/utils/Logger.ts
Original file line number Diff line number Diff line change
@@ -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));
}