Skip to content

Commit afcdf3b

Browse files
authored
Merge pull request #680 from MoYingJi/pr/t
feat(player): 添加播放时间格式切换功能
2 parents e00dfa1 + b0a35f5 commit afcdf3b

5 files changed

Lines changed: 115 additions & 23 deletions

File tree

src/components/Player/MainPlayer.vue

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -160,10 +160,9 @@
160160
class="time-container"
161161
vertical
162162
>
163-
<div class="time" @click="showCountDown = !showCountDown">
164-
<n-text v-if="showCountDown" depth="2">-{{ msToTime(statusStore.duration - statusStore.currentTime) }}</n-text>
165-
<n-text v-else depth="2">{{ msToTime(statusStore.currentTime) }}</n-text>
166-
<n-text depth="2">{{ msToTime(statusStore.duration) }}</n-text>
163+
<div class="time" @click="toggleTimeFormat">
164+
<n-text depth="2">{{ timeDisplay0 }}</n-text>
165+
<n-text depth="2">{{ timeDisplay1 }}</n-text>
167166
</div>
168167
<!-- 定时关闭 -->
169168
<n-tag
@@ -190,7 +189,7 @@
190189
<script setup lang="ts">
191190
import type { DropdownOption } from "naive-ui";
192191
import { useMusicStore, useStatusStore, useDataStore, useSettingStore } from "@/stores";
193-
import { msToTime, convertSecondsToTime } from "@/utils/time";
192+
import { convertSecondsToTime } from "@/utils/time";
194193
import { renderIcon, coverLoaded, copyData } from "@/utils/helper";
195194
import { toLikeSong } from "@/utils/auth";
196195
import {
@@ -202,6 +201,7 @@ import {
202201
} from "@/utils/modal";
203202
import { useSongManager } from "@/core/player/SongManager";
204203
import { usePlayerController } from "@/core/player/PlayerController";
204+
import { getTimeDisplay, TIME_FORMATS } from "@/utils/format";
205205
206206
const router = useRouter();
207207
const dataStore = useDataStore();
@@ -212,7 +212,14 @@ const settingStore = useSettingStore();
212212
const player = usePlayerController();
213213
const songManager = useSongManager();
214214
215-
const showCountDown = ref(false);
215+
const timeDisplay = getTimeDisplay(() => settingStore.timeFormatMainPlayer, statusStore);
216+
const timeDisplay0 = timeDisplay(0);
217+
const timeDisplay1 = timeDisplay(1);
218+
219+
const toggleTimeFormat = () => {
220+
const currentIndex = TIME_FORMATS.indexOf(settingStore.timeFormatMainPlayer)
221+
settingStore.timeFormatMainPlayer = TIME_FORMATS[(currentIndex + 1) % TIME_FORMATS.length];
222+
};
216223
217224
// 歌曲更多操作
218225
const songMoreOptions = computed<DropdownOption[]>(() => {

src/components/Player/PlayerControl.vue

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -80,9 +80,9 @@
8080
</div>
8181
<!-- 进度条 -->
8282
<div class="slider">
83-
<span>{{ msToTime(statusStore.currentTime) }}</span>
83+
<span @click="toggleTimeFormat">{{ timeDisplay0 }}</span>
8484
<PlayerSlider :show-tooltip="false" />
85-
<span>{{ msToTime(statusStore.duration) }}</span>
85+
<span @click="toggleTimeFormat">{{ timeDisplay1 }}</span>
8686
</div>
8787
</div>
8888
<n-flex class="right" align="center" justify="end">
@@ -95,19 +95,29 @@
9595
</template>
9696

9797
<script setup lang="ts">
98-
import { useMusicStore, useStatusStore, useDataStore } from "@/stores";
99-
import { msToTime } from "@/utils/time";
98+
import { useMusicStore, useStatusStore, useDataStore, useSettingStore } from "@/stores";
10099
import { openDownloadSong, openPlaylistAdd } from "@/utils/modal";
101100
import { toLikeSong } from "@/utils/auth";
102101
import { useSongManager } from "@/core/player/SongManager";
103102
import { usePlayerController } from "@/core/player/PlayerController";
103+
import { getTimeDisplay, TIME_FORMATS } from "@/utils/format";
104104
105105
const dataStore = useDataStore();
106106
const musicStore = useMusicStore();
107107
const statusStore = useStatusStore();
108+
const settingStore = useSettingStore();
108109
109110
const songManager = useSongManager();
110111
const player = usePlayerController();
112+
113+
const timeDisplay = getTimeDisplay(() => settingStore.timeFormatFullPlayer, statusStore);
114+
const timeDisplay0 = timeDisplay(0);
115+
const timeDisplay1 = timeDisplay(1);
116+
117+
const toggleTimeFormat = () => {
118+
const currentIndex = TIME_FORMATS.indexOf(settingStore.timeFormatFullPlayer);
119+
settingStore.timeFormatFullPlayer = TIME_FORMATS[(currentIndex + 1) % TIME_FORMATS.length];
120+
};
111121
</script>
112122

113123
<style lang="scss" scoped>

src/components/Setting/PlaySetting.vue

Lines changed: 55 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -236,6 +236,17 @@
236236
/>
237237
</n-card>
238238
</n-collapse-transition>
239+
<n-card class="set-item">
240+
<div class="label">
241+
<n-text class="name">播放器时间样式</n-text>
242+
<n-text class="tip" :depth="3">播放页面底部的时间如何显示(单击底部时间可以快速切换)</n-text>
243+
</div>
244+
<n-select
245+
v-model:value="settingStore.timeFormatFullPlayer"
246+
:options="timeFormatOptions"
247+
class="set"
248+
/>
249+
</n-card>
239250
<n-card class="set-item">
240251
<div class="label">
241252
<n-text class="name">播放器主色跟随封面</n-text>
@@ -250,13 +261,6 @@
250261
</div>
251262
<n-switch v-model:value="settingStore.countDownShow" class="set" :round="false" />
252263
</n-card>
253-
<n-card class="set-item">
254-
<div class="label">
255-
<n-text class="name">底栏歌词显示</n-text>
256-
<n-text class="tip" :depth="3">在播放时将歌手信息更改为歌词</n-text>
257-
</div>
258-
<n-switch v-model:value="settingStore.barLyricShow" class="set" :round="false" />
259-
</n-card>
260264
<n-card class="set-item">
261265
<div class="label">
262266
<n-text class="name">播放器元素自动隐藏</n-text>
@@ -271,12 +275,6 @@
271275
</div>
272276
<n-switch v-model:value="settingStore.showPlayMeta" class="set" :round="false" />
273277
</n-card>
274-
<n-card class="set-item">
275-
<div class="label">
276-
<n-text class="name">播放列表歌曲数量</n-text>
277-
</div>
278-
<n-switch v-model:value="settingStore.showPlaylistCount" class="set" :round="false" />
279-
</n-card>
280278
<n-card class="set-item">
281279
<div class="label">
282280
<n-text class="name">动态封面</n-text>
@@ -304,6 +302,35 @@
304302
/>
305303
</n-card>
306304
</div>
305+
<div class="set-list">
306+
<n-h3 prefix="bar"> 全局播放器 </n-h3>
307+
<n-card class="set-item">
308+
<div class="label">
309+
<n-text class="name">底栏时间样式</n-text>
310+
<n-text class="tip" :depth="3">
311+
全局播放器右侧的时间如何显示(单击底栏时间可以快速切换)
312+
</n-text>
313+
</div>
314+
<n-select
315+
v-model:value="settingStore.timeFormatMainPlayer"
316+
:options="timeFormatOptions"
317+
class="set"
318+
/>
319+
</n-card>
320+
<n-card class="set-item">
321+
<div class="label">
322+
<n-text class="name">播放列表歌曲数量</n-text>
323+
</div>
324+
<n-switch v-model:value="settingStore.showPlaylistCount" class="set" :round="false" />
325+
</n-card>
326+
<n-card class="set-item">
327+
<div class="label">
328+
<n-text class="name">底栏歌词显示</n-text>
329+
<n-text class="tip" :depth="3">在播放时将歌手信息更改为歌词</n-text>
330+
</div>
331+
<n-switch v-model:value="settingStore.barLyricShow" class="set" :round="false" />
332+
</n-card>
333+
</div>
307334
</div>
308335
</template>
309336

@@ -380,6 +407,21 @@ const songLevelData = {
380407
},
381408
};
382409
410+
const timeFormatOptions = [
411+
{
412+
label: "播放时间 / 总时长",
413+
value: "current-total",
414+
},
415+
{
416+
label: "剩余时间 / 总时长",
417+
value: "remaining-total",
418+
},
419+
{
420+
label: "播放时间 / 剩余时间",
421+
value: "current-remaining",
422+
},
423+
];
424+
383425
// 获取全部输出设备
384426
const getOutputDevices = async () => {
385427
const allDevices = await navigator.mediaDevices.enumerateDevices();

src/stores/setting.ts

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import { SongUnlockServer } from "@/core/player/SongManager";
44
import type { SongLevelType } from "@/types/main";
55
import { defaultAMLLDbServer } from "@/utils/meta";
66
import { CURRENT_SETTING_SCHEMA_VERSION, settingMigrations } from "./migrations/settingMigrations";
7+
import { TimeFormat } from "@/utils/format";
78

89
export interface SettingState {
910
/** Schema 版本号(可选,用于数据迁移) */
@@ -129,6 +130,10 @@ export interface SettingState {
129130
countDownShow: boolean;
130131
/** 显示歌词条 */
131132
barLyricShow: boolean;
133+
/** 全局播放器时间格式 **/
134+
timeFormatMainPlayer: TimeFormat;
135+
/** 播放页面时间格式 */
136+
timeFormatFullPlayer: TimeFormat;
132137
/** 播放器类型 */
133138
playerType: "cover" | "record";
134139
/** 背景类型 */
@@ -328,6 +333,8 @@ export const useSettingStore = defineStore("setting", {
328333
],
329334
countDownShow: true,
330335
barLyricShow: true,
336+
timeFormatMainPlayer: "current-total",
337+
timeFormatFullPlayer: "current-total",
331338
playerType: "cover",
332339
playerBackgroundType: "blur",
333340
playerBackgroundFps: 30,

src/utils/format.ts

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -353,3 +353,29 @@ export const getPlayerInfo = (song?: SongType, sep: string = "/"): string | null
353353
if (!info) return null;
354354
return `${info.name} - ${info.artist}`;
355355
};
356+
357+
// 歌曲播放时间显示类型
358+
export type TimeDisplayType = "current" | "total" | "remaining";
359+
360+
// 歌曲播放时间显示格式
361+
export const TIME_FORMATS = ["current-total", "remaining-total", "current-remaining"] as const;
362+
export type TimeFormat = typeof TIME_FORMATS[number];
363+
364+
export const displayTimeFormat = (format: TimeFormat): [TimeDisplayType, TimeDisplayType] => {
365+
switch (format) {
366+
case "current-total": return ["current", "total"];
367+
case "remaining-total": return ["remaining", "total"];
368+
case "current-remaining": return ["current", "remaining"];
369+
}
370+
};
371+
372+
export const getTimeDisplay = (
373+
format: () => TimeFormat, statusStore: { currentTime: number, duration: number }
374+
) => (index: number) => computed(() => {
375+
const display = displayTimeFormat(format())[index];
376+
switch (display) {
377+
case "current": return msToTime(statusStore.currentTime);
378+
case "total": return msToTime(statusStore.duration);
379+
case "remaining": return "-" + msToTime(statusStore.duration - statusStore.currentTime);
380+
}
381+
});

0 commit comments

Comments
 (0)