Skip to content

Commit

Permalink
Lyric manager, desktop lyric web
Browse files Browse the repository at this point in the history
  • Loading branch information
HeHang0 committed Nov 6, 2023
1 parent 431e847 commit 3e3d35a
Show file tree
Hide file tree
Showing 9 changed files with 323 additions and 101 deletions.
7 changes: 6 additions & 1 deletion web/src/components/Footer.vue
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,11 @@ const play = usePlayStore();
</span>
<span class="music-icon" @click="play.next" title="下一首"> 后 </span>
<span class="music-icon" title="桌面歌词" style="opacity: 0">
<span
class="music-icon"
@click="play.showDesktopLyric(!play.desktopLyricShow)"
title="桌面歌词"
:style="play.desktopLyricShow ? 'opacity:1' : ''">
</span>
</div>
Expand All @@ -124,6 +128,7 @@ const play = usePlayStore();
v-model="play.playStatus.progress"
:show-tooltip="false"
:max="1000"
:title="play.playStatus.progress"
@mousedown="play.playStatus.disableUpdateProgress = true"
@change="play.changeProgress" />
<span v-if="!props.full" class="music-footer-second-text">{{
Expand Down
9 changes: 4 additions & 5 deletions web/src/components/WindowHelper.vue
Original file line number Diff line number Diff line change
@@ -1,17 +1,16 @@
<script lang="ts" setup>
import { webView2Services } from '../utils/utils';
function startDrag(e: MouseEvent) {
if (e.button == 0 && e.buttons == 1)
webView2Services.specialService?.MouseDownDrag();
}
function startResize(direction: number, e?: MouseEvent) {
if (e && e.button == 0 && e.buttons == 1)
webView2Services.specialService?.ResizeWindow(direction);
}
</script>
<template>
<div v-if="webView2Services.enabled" class="music-window-helper">
<div class="music-window-helper-drag" @mousedown.stop="startDrag"></div>
<div
class="music-window-helper-drag"
style="-webkit-app-region: drag"></div>
<!-- @mousedown.stop="startDrag" -->
<div
class="music-window-helper-l"
@mousedown.stop="startResize(1, $event)"></div>
Expand Down
79 changes: 19 additions & 60 deletions web/src/components/player/Lyric.vue
Original file line number Diff line number Diff line change
@@ -1,69 +1,29 @@
<script setup lang="ts">
import { usePlayStore } from '../../stores/play';
import { Ref, onMounted, onUnmounted, ref, watch } from 'vue';
import { LyricLine } from '../../utils/type';
import {
duration2Millisecond,
scrollToElementId,
parseLyric
} from '../../utils/utils';
import { Ref, nextTick, onMounted, onUnmounted, ref } from 'vue';
import { clearArray, scrollToElementId } from '../../utils/utils';
import { useRouter } from 'vue-router';
import * as api from '../../utils/api/api';
interface Props {
pure?: boolean;
}
const props = withDefaults(defineProps<Props>(), {
pure: false
});
const play = usePlayStore();
const musicLyric: Ref<LyricLine[]> = ref([]);
const musicLyric: Ref<string[]> = ref([]);
const currentLine: Ref<number> = ref(0);
const lyricLineIdPrefix = 'lyric-line-';
const router = useRouter();
var currentLyricId = '';
function loadLyric() {
currentLine.value = 0;
if (!play.music.length && !play.music.duration) {
return;
}
if (currentLyricId == `${play.music.type}${play.music.id}`) return;
api.lyric(play.music).then(lyric => {
if (!lyric) {
musicLyric.value = [];
} else {
if (!lyric.lines) {
lyric.lines = parseLyric(
lyric.text,
play.music.length || duration2Millisecond(play.music.duration)
);
}
currentLyricId = `${play.music.type}${play.music.id}`;
musicLyric.value = lyric.lines || [];
}
});
function loadLyric(lines: string[]) {
clearArray(musicLyric.value);
musicLyric.value = lines;
}
function activeLyricLine() {
if (!play.playDetailShow) return;
for (let i = 0; i < musicLyric.value.length; i++) {
const line = musicLyric.value[i];
if (
line.progress <= play.playStatus.progress &&
line.max > play.playStatus.progress
) {
for (let j = i + 1; j < musicLyric.value.length; j++) {
if (musicLyric.value[j].progress === line.progress) continue;
else {
i = j;
break;
}
}
if (currentLine.value != i) {
currentLine.value = i;
scrollToElementId(lyricLineIdPrefix + i, true, true);
}
return;
}
function activeLyricLine(index: number, _text: string) {
if (currentLine.value != index) {
currentLine.value = index;
nextTick(() => {
scrollToElementId(lyricLineIdPrefix + index, true, true);
});
}
}
function cancelDetail() {
Expand All @@ -86,14 +46,13 @@ function toAlbum() {
router.push(`/album/${play.music.type}/${play.music.albumId}`);
}
}
const unWatchProgress = watch(() => play.playStatus.progress, activeLyricLine);
const unWatchMusicId = watch(() => play.music.id, loadLyric);
const unWatchDuration = watch(() => play.music.duration, loadLyric);
onMounted(loadLyric);
onMounted(() => {
play.subscribeLyric(loadLyric);
play.subscribeLyricLine(activeLyricLine);
});
onUnmounted(() => {
unWatchProgress();
unWatchMusicId();
unWatchDuration();
play.subscribeLyric(loadLyric, true);
play.subscribeLyricLine(activeLyricLine, true);
});
</script>
<template>
Expand Down Expand Up @@ -132,7 +91,7 @@ onUnmounted(() => {
:id="lyricLineIdPrefix + index"
:class="index == currentLine ? 'music-lyric-line-active' : ''"
class="music-lyric-line">
{{ line.text }}
{{ line }}
</div>
</div>
</div>
Expand Down
67 changes: 45 additions & 22 deletions web/src/stores/play.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,12 @@ import {
millisecond2Duration
} from '../utils/utils';
import { useTitle } from '@vueuse/core';
import { LyricChange, LyricLineChange, LyricManager } from '../utils/lyric';

const title = useTitle();

const lyricManager = new LyricManager();

export const usePlayStore = defineStore('play', {
state: () => {
return {
Expand All @@ -31,6 +34,7 @@ export const usePlayStore = defineStore('play', {
currentListShow: false,
playDetailShow: false,
selectPlaylistShow: false,
desktopLyricShow: false,
playerMode: '',
playStatus: {
currentTime: '00:00',
Expand All @@ -52,6 +56,27 @@ export const usePlayStore = defineStore('play', {
};
},
actions: {
subscribeLyric(callback: LyricChange, cancel?: boolean) {
lyricManager.subscribeLyric(callback, cancel, this.music);
},
subscribeLyricLine(callback: LyricLineChange, cancel?: boolean) {
lyricManager.subscribeLyricLine(callback, cancel, this.music);
},
closeDesktopLyric() {
this.desktopLyricShow = false;
},
showDesktopLyric(show: boolean) {
this.desktopLyricShow = show;
let title = this.music.name;
if (this.music.singer) {
title += ' - ' + this.music.singer;
}
lyricManager.showInDesktop(
title,
this.desktopLyricShow,
this.closeDesktopLyric
);
},
clearMusicList() {
this.musicList.splice(0, this.musicList.length);
this.setCurrentMusic();
Expand All @@ -62,25 +87,20 @@ export const usePlayStore = defineStore('play', {
this.pause();
},
setCurrentMusic(music?: Music, noSave?: boolean) {
if (!music || !music.id) {
music = {
id: '',
name: '',
image: '',
singer: '',
album: '',
albumId: '',
duration: '',
vip: false,
type: 'local'
};
} else {
// this.add([music]);
}
Object.keys(music).map(k => {
if ((this.music as any)[k] != (music as any)[k])
(this.music as any)[k] = (music as any)[k];
});
this.music.id = music?.id || '';
this.music.name = music?.name || '';
this.music.rawName = music?.rawName || '';
this.music.image = music?.image || '';
this.music.singer = music?.singer || '';
this.music.album = music?.album || '';
this.music.albumId = music?.albumId || '';
this.music.duration = music?.duration || '';
this.music.length = music?.length || 0;
this.music.vip = music?.vip || false;
this.music.remark = music?.remark || '';
this.music.type = music?.type || 'local';
this.music.url = music?.url || '';
this.music.lyricUrl = music?.lyricUrl || '';
!noSave && storage.setValue(StorageKey.CurrentMusic, this.music);
},
setSortType(type: SortType) {
Expand Down Expand Up @@ -290,6 +310,7 @@ export const usePlayStore = defineStore('play', {
this.addHistory([this.music]);
this.setTitle();
this.preparePlay = false;
lyricManager.updateLyric(this.music);
},
async pause() {
this.checkingStatus = true;
Expand Down Expand Up @@ -412,12 +433,13 @@ export const usePlayStore = defineStore('play', {
}
if (data.totalTime && this.playStatus.totalTime != data.totalTime) {
this.playStatus.totalTime = data.totalTime;
if (!this.music.length) {
this.music.length = duration2Millisecond(data.totalTime);
}
if (!this.music.duration) {
this.music.duration = data.totalTime;
}
if (!this.music.length) {
this.music.length = duration2Millisecond(data.totalTime);
lyricManager.updateLyric(this.music);
}
}
if (
!this.playStatus.disableUpdateVolume &&
Expand Down Expand Up @@ -446,6 +468,7 @@ export const usePlayStore = defineStore('play', {
(this.music.length * data.progress) / 1000
);
}
lyricManager.updateLyricLine(this.playStatus.progress);
}
} catch {}
},
Expand Down
7 changes: 6 additions & 1 deletion web/src/stores/setting.ts
Original file line number Diff line number Diff line change
Expand Up @@ -230,6 +230,10 @@ export const useSettingStore = defineStore('setting', {
this.setAppTheme({ id: darkModeMediaQuery.matches ? 'dark' : '' });
},
setAppTheme(appTheme?: AppTheme) {
let preferredColorScheme = 0;
if (!this.autoAppTheme) {
preferredColorScheme = appTheme?.id.includes('dark') ? 2 : 1;
}
this.appTheme.id = appTheme?.id || '';
this.appTheme.color = appTheme?.color || '';
this.appTheme.image =
Expand All @@ -239,6 +243,7 @@ export const useSettingStore = defineStore('setting', {
id: this.appTheme.id,
name: this.appTheme.name
});
musicOperate('/theme?theme=' + preferredColorScheme);
},
setCustomTheme(appTheme?: AppTheme) {
this.customTheme.id = appTheme?.id || 'custom ';
Expand Down Expand Up @@ -300,7 +305,7 @@ export const useSettingStore = defineStore('setting', {
fontEle.innerText = styleText;
},
setGpuAcceleration(_value?: boolean, noSave?: boolean) {
musicOperate('/gpu', this.pageValue.fadeIn ? '1' : undefined);
musicOperate('/gpu', this.pageValue.gpuAcceleration ? undefined : '1');
!noSave && this.saveSetting();
},
setStartup() {
Expand Down
12 changes: 5 additions & 7 deletions web/src/utils/api/api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ import {
PlatformAPI,
Playlist,
RankingType,
Lyric,
UserInfo,
LoginStatus,
MusicQuality
Expand Down Expand Up @@ -245,8 +244,8 @@ export async function parseLink(link: string): Promise<{
return null;
}

const lyricCache = new Map<string, Lyric>();
export async function lyric(music: Music): Promise<Lyric | null> {
const lyricCache = new Map<string, string>();
export async function lyric(music: Music): Promise<string> {
const cache = lyricCache.get(music.type + music.id);
if (cache) return cache;
var text = '';
Expand All @@ -264,11 +263,10 @@ export async function lyric(music: Music): Promise<Lyric | null> {
}
}
if (text) {
const lyric = { text: text };
lyricCache.set(music.type + music.id, lyric);
return lyric;
lyricCache.set(music.type + music.id, text);
return text;
}
return null;
return '';
}

export function setDownloadQuality(quality: MusicQuality) {
Expand Down
Loading

0 comments on commit 3e3d35a

Please sign in to comment.