mirror of
https://github.com/rommapp/romm.git
synced 2026-06-28 06:46:00 +00:00
Refactor soundtrack metadata types to use RomFileAudioMetaSchema for improved consistency
This commit is contained in:
@@ -4,11 +4,12 @@ import type { Emitter } from "mitt";
|
||||
import { storeToRefs } from "pinia";
|
||||
import { computed, inject, onBeforeUnmount, onMounted, ref, watch } from "vue";
|
||||
import { useI18n } from "vue-i18n";
|
||||
import type {
|
||||
RomFileAudioMetaSchema,
|
||||
SoundtrackTrackMetaSchema,
|
||||
} from "@/__generated__";
|
||||
import VolumeControl from "@/components/common/VolumeControl.vue";
|
||||
import romApi, {
|
||||
type SoundtrackAudioMeta,
|
||||
type SoundtrackTrackMeta,
|
||||
} from "@/services/api/rom";
|
||||
import romApi from "@/services/api/rom";
|
||||
import type { DetailedRom } from "@/stores/roms";
|
||||
import useSoundtrackPlayer, {
|
||||
type PlayerMeta,
|
||||
@@ -74,7 +75,7 @@ const folderCoverUrl = computed(() => {
|
||||
return cover ? fileUrl(cover.id, cover.file_name) : null;
|
||||
});
|
||||
|
||||
const tracksMeta = ref<Map<number, SoundtrackAudioMeta>>(new Map());
|
||||
const tracksMeta = ref<Map<number, RomFileAudioMetaSchema>>(new Map());
|
||||
const isLoadingMeta = ref(false);
|
||||
let metaAbort: AbortController | null = null;
|
||||
|
||||
@@ -88,13 +89,13 @@ const activeTrack = computed(() =>
|
||||
tracks.value.find((t) => t.id === activeTrackId.value),
|
||||
);
|
||||
|
||||
const activeMeta = computed<SoundtrackAudioMeta | undefined>(() =>
|
||||
const activeMeta = computed<RomFileAudioMetaSchema | undefined>(() =>
|
||||
activeTrackId.value != null
|
||||
? tracksMeta.value.get(activeTrackId.value)
|
||||
: undefined,
|
||||
);
|
||||
|
||||
function coverUrlForMeta(m: SoundtrackAudioMeta | undefined): string | null {
|
||||
function coverUrlForMeta(m: RomFileAudioMetaSchema | undefined): string | null {
|
||||
if (m?.cover_path) return `${FRONTEND_RESOURCES_PATH}/${m.cover_path}`;
|
||||
return null;
|
||||
}
|
||||
@@ -151,8 +152,8 @@ async function loadAllMetadata() {
|
||||
romId: props.rom.id,
|
||||
signal: metaAbort.signal,
|
||||
});
|
||||
const next = new Map<number, SoundtrackAudioMeta>();
|
||||
for (const row of data as SoundtrackTrackMeta[]) {
|
||||
const next = new Map<number, RomFileAudioMetaSchema>();
|
||||
for (const row of data as SoundtrackTrackMetaSchema[]) {
|
||||
if (row.audio_meta) next.set(row.file_id, row.audio_meta);
|
||||
}
|
||||
tracksMeta.value = next;
|
||||
@@ -171,7 +172,7 @@ async function loadAllMetadata() {
|
||||
}
|
||||
}
|
||||
|
||||
function toPlayerMeta(m: SoundtrackAudioMeta | undefined): PlayerMeta {
|
||||
function toPlayerMeta(m: RomFileAudioMetaSchema | undefined): PlayerMeta {
|
||||
return {
|
||||
title: m?.title ?? undefined,
|
||||
artist: m?.artist ?? undefined,
|
||||
@@ -243,7 +244,7 @@ function onDelete(fileId: number) {
|
||||
emit("delete-track", fileId);
|
||||
}
|
||||
|
||||
function chips(meta: SoundtrackAudioMeta | undefined) {
|
||||
function chips(meta: RomFileAudioMetaSchema | undefined) {
|
||||
if (!meta) return [];
|
||||
const items: { icon: string; label: string }[] = [];
|
||||
if (meta.album) items.push({ icon: "mdi-album", label: meta.album });
|
||||
|
||||
@@ -10,6 +10,7 @@ import type {
|
||||
RomUserSchema,
|
||||
SearchRomSchema,
|
||||
SimpleRomSchema,
|
||||
SoundtrackTrackMetaSchema,
|
||||
UserNoteSchema,
|
||||
RomFiltersDict,
|
||||
} from "@/__generated__";
|
||||
@@ -635,26 +636,6 @@ async function removeSoundtrack({
|
||||
return api.delete(`/roms/${romId}/soundtracks/${fileId}`);
|
||||
}
|
||||
|
||||
export interface SoundtrackAudioMeta {
|
||||
title: string | null;
|
||||
artist: string | null;
|
||||
album: string | null;
|
||||
year: string | null;
|
||||
genre: string | null;
|
||||
track: string | null;
|
||||
disc: string | null;
|
||||
duration_seconds: number | null;
|
||||
has_embedded_cover: boolean;
|
||||
cover_path: string | null;
|
||||
}
|
||||
|
||||
export interface SoundtrackTrackMeta {
|
||||
file_id: number;
|
||||
file_name: string;
|
||||
file_size_bytes: number;
|
||||
audio_meta: SoundtrackAudioMeta | null;
|
||||
}
|
||||
|
||||
async function getSoundtrackMetadata({
|
||||
romId,
|
||||
signal,
|
||||
@@ -662,9 +643,12 @@ async function getSoundtrackMetadata({
|
||||
romId: number;
|
||||
signal?: AbortSignal;
|
||||
}) {
|
||||
return api.get<SoundtrackTrackMeta[]>(`/roms/${romId}/soundtracks/metadata`, {
|
||||
signal,
|
||||
});
|
||||
return api.get<SoundtrackTrackMetaSchema[]>(
|
||||
`/roms/${romId}/soundtracks/metadata`,
|
||||
{
|
||||
signal,
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
async function uploadManualFiles({
|
||||
|
||||
@@ -2,6 +2,7 @@ import { useLocalStorage } from "@vueuse/core";
|
||||
import { throttle } from "lodash";
|
||||
import { defineStore } from "pinia";
|
||||
import { computed, ref, shallowRef } from "vue";
|
||||
import type { RomFileAudioMetaSchema } from "@/__generated__";
|
||||
|
||||
const volumeStorage = useLocalStorage<number>("soundtrack.volume", 1);
|
||||
const mutedStorage = useLocalStorage<boolean>("soundtrack.muted", false);
|
||||
@@ -13,18 +14,24 @@ export interface PlayerTrack {
|
||||
url: string;
|
||||
}
|
||||
|
||||
export interface PlayerMeta {
|
||||
title?: string;
|
||||
artist?: string;
|
||||
album?: string;
|
||||
year?: string;
|
||||
genre?: string;
|
||||
track?: string;
|
||||
disc?: string;
|
||||
// Audio-tag fields are sourced from the generated schema; the rest (duration in
|
||||
// seconds + resolved cover URLs) are UI-specific to the player.
|
||||
type AudioTagKey =
|
||||
| "title"
|
||||
| "artist"
|
||||
| "album"
|
||||
| "year"
|
||||
| "genre"
|
||||
| "track"
|
||||
| "disc";
|
||||
|
||||
export type PlayerMeta = {
|
||||
[K in AudioTagKey]?: NonNullable<RomFileAudioMetaSchema[K]>;
|
||||
} & {
|
||||
duration?: number;
|
||||
coverUrl?: string;
|
||||
folderCoverUrl?: string;
|
||||
}
|
||||
};
|
||||
|
||||
const useSoundtrackPlayer = defineStore("soundtrackPlayer", () => {
|
||||
const track = ref<PlayerTrack | null>(null);
|
||||
|
||||
@@ -21,10 +21,11 @@ import {
|
||||
watch,
|
||||
} from "vue";
|
||||
import { useI18n } from "vue-i18n";
|
||||
import romApi, {
|
||||
type SoundtrackAudioMeta,
|
||||
type SoundtrackTrackMeta,
|
||||
} from "@/services/api/rom";
|
||||
import type {
|
||||
RomFileAudioMetaSchema,
|
||||
SoundtrackTrackMetaSchema,
|
||||
} from "@/__generated__";
|
||||
import romApi from "@/services/api/rom";
|
||||
import type { DetailedRom } from "@/stores/roms";
|
||||
import useSoundtrackPlayer, {
|
||||
type PlayerMeta,
|
||||
@@ -101,16 +102,16 @@ const folderCoverUrl = computed(() => {
|
||||
});
|
||||
|
||||
// ---------- Metadata fetch ----------
|
||||
const tracksMeta = ref<Map<number, SoundtrackAudioMeta>>(new Map());
|
||||
const tracksMeta = ref<Map<number, RomFileAudioMetaSchema>>(new Map());
|
||||
const isLoadingMeta = ref(false);
|
||||
let metaAbort: AbortController | null = null;
|
||||
|
||||
function coverUrlForMeta(m: SoundtrackAudioMeta | undefined): string | null {
|
||||
function coverUrlForMeta(m: RomFileAudioMetaSchema | undefined): string | null {
|
||||
if (m?.cover_path) return `${FRONTEND_RESOURCES_PATH}/${m.cover_path}`;
|
||||
return null;
|
||||
}
|
||||
|
||||
function toPlayerMeta(m: SoundtrackAudioMeta | undefined): PlayerMeta {
|
||||
function toPlayerMeta(m: RomFileAudioMetaSchema | undefined): PlayerMeta {
|
||||
return {
|
||||
title: m?.title ?? undefined,
|
||||
artist: m?.artist ?? undefined,
|
||||
@@ -149,8 +150,8 @@ async function loadAllMetadata() {
|
||||
romId: props.rom.id,
|
||||
signal: metaAbort.signal,
|
||||
});
|
||||
const next = new Map<number, SoundtrackAudioMeta>();
|
||||
for (const row of data as SoundtrackTrackMeta[]) {
|
||||
const next = new Map<number, RomFileAudioMetaSchema>();
|
||||
for (const row of data as SoundtrackTrackMetaSchema[]) {
|
||||
if (row.audio_meta) next.set(row.file_id, row.audio_meta);
|
||||
}
|
||||
tracksMeta.value = next;
|
||||
@@ -192,7 +193,7 @@ const activeTrack = computed(() =>
|
||||
tracks.value.find((t) => t.id === activeTrackId.value),
|
||||
);
|
||||
|
||||
const activeMeta = computed<SoundtrackAudioMeta | undefined>(() =>
|
||||
const activeMeta = computed<RomFileAudioMetaSchema | undefined>(() =>
|
||||
activeTrackId.value != null
|
||||
? tracksMeta.value.get(activeTrackId.value)
|
||||
: undefined,
|
||||
@@ -236,7 +237,7 @@ function trackDurationFor(fileId: number): number | undefined {
|
||||
// Chips shown in the now-playing header.
|
||||
type ChipItem = { icon: string; label: string; color?: string };
|
||||
|
||||
function headerChips(meta: SoundtrackAudioMeta | undefined): ChipItem[] {
|
||||
function headerChips(meta: RomFileAudioMetaSchema | undefined): ChipItem[] {
|
||||
if (!meta) return [];
|
||||
const items: ChipItem[] = [];
|
||||
if (meta.album) items.push({ icon: "mdi-album", label: meta.album });
|
||||
|
||||
Reference in New Issue
Block a user