add extra song information to player
This commit is contained in:
@@ -8,6 +8,7 @@
|
|||||||
} from "@lucide/svelte";
|
} from "@lucide/svelte";
|
||||||
import { player } from "$lib/player/store.svelte";
|
import { player } from "$lib/player/store.svelte";
|
||||||
import { type SongType, trackFromSongRow } from "$lib/player/types";
|
import { type SongType, trackFromSongRow } from "$lib/player/types";
|
||||||
|
import { songTypeNumberLabel } from "$lib/utils/amq";
|
||||||
import { Button } from "./ui/button";
|
import { Button } from "./ui/button";
|
||||||
|
|
||||||
type SongEntryProps = {
|
type SongEntryProps = {
|
||||||
@@ -18,9 +19,9 @@
|
|||||||
songName: string;
|
songName: string;
|
||||||
artistName: string | null;
|
artistName: string | null;
|
||||||
fileName?: string | null;
|
fileName?: string | null;
|
||||||
globalPercent: number | null;
|
globalPercent: number;
|
||||||
dub: boolean | null;
|
dub: boolean;
|
||||||
rebroadcast: boolean | null;
|
rebroadcast: boolean;
|
||||||
};
|
};
|
||||||
|
|
||||||
let {
|
let {
|
||||||
@@ -36,14 +37,7 @@
|
|||||||
rebroadcast,
|
rebroadcast,
|
||||||
}: SongEntryProps = $props();
|
}: SongEntryProps = $props();
|
||||||
|
|
||||||
const typeLabelMap: Record<number, string> = {
|
const displayTypeNumber = $derived(songTypeNumberLabel(type, number));
|
||||||
1: "OP",
|
|
||||||
2: "ED",
|
|
||||||
3: "INS",
|
|
||||||
};
|
|
||||||
|
|
||||||
const typeLabel = $derived(typeLabelMap[type] ?? `T${type}`);
|
|
||||||
const displayTypeNumber = $derived(`${typeLabel}${number || ""}`);
|
|
||||||
|
|
||||||
const artistDisplay = $derived.by(
|
const artistDisplay = $derived.by(
|
||||||
() => artistName?.trim() || "Unknown Artist",
|
() => artistName?.trim() || "Unknown Artist",
|
||||||
@@ -60,6 +54,7 @@
|
|||||||
fileName,
|
fileName,
|
||||||
dub,
|
dub,
|
||||||
rebroadcast,
|
rebroadcast,
|
||||||
|
globalPercent,
|
||||||
}),
|
}),
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|||||||
@@ -2,12 +2,22 @@
|
|||||||
import { Disc, Volume1, Volume2, VolumeX } from "@lucide/svelte";
|
import { Disc, Volume1, Volume2, VolumeX } from "@lucide/svelte";
|
||||||
|
|
||||||
import { player } from "$lib/player/store.svelte";
|
import { player } from "$lib/player/store.svelte";
|
||||||
|
import { songTypeNumberLabel } from "$lib/utils/amq";
|
||||||
import Controls from "./Controls.svelte";
|
import Controls from "./Controls.svelte";
|
||||||
import { getAudioContext } from "./ctx.svelte";
|
import { getAudioContext } from "./ctx.svelte";
|
||||||
import Queue from "./Queue.svelte";
|
import Queue from "./Queue.svelte";
|
||||||
import { formatTime } from "./utils";
|
import { formatTime } from "./utils";
|
||||||
|
|
||||||
const audio = getAudioContext();
|
const audio = getAudioContext();
|
||||||
|
|
||||||
|
const displayTypeNumber = $derived(
|
||||||
|
player.currentTrack
|
||||||
|
? songTypeNumberLabel(
|
||||||
|
player.currentTrack.type,
|
||||||
|
player.currentTrack.number,
|
||||||
|
)
|
||||||
|
: "",
|
||||||
|
);
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<div
|
<div
|
||||||
@@ -16,15 +26,20 @@
|
|||||||
{#if player.currentTrack}
|
{#if player.currentTrack}
|
||||||
<div class="p-6 space-y-4 shrink-0">
|
<div class="p-6 space-y-4 shrink-0">
|
||||||
<!-- Track Info -->
|
<!-- Track Info -->
|
||||||
<div class="space-y-1.5 text-center">
|
<div class="space-y-1.5">
|
||||||
<h2 class="text-xl font-bold leading-tight line-clamp-2">
|
<h2 class="text-lg font-bold leading-tight">
|
||||||
{player.currentTrack.title}
|
{player.currentTrack.animeName}
|
||||||
|
<span class="tag">{displayTypeNumber}</span>
|
||||||
</h2>
|
</h2>
|
||||||
<p class="text-muted-foreground font-medium text-lg line-clamp-1">
|
<p class="text-foreground/80 font-medium text-l">
|
||||||
{player.currentTrack.artist}
|
{player.currentTrack.title}
|
||||||
|
<span class="text-muted-foreground"> · </span>
|
||||||
|
<span class="text-muted-foreground"
|
||||||
|
>{player.currentTrack.globalPercent}%</span
|
||||||
|
>
|
||||||
</p>
|
</p>
|
||||||
<p class="text-xs text-muted-foreground/80">
|
<p class="text-sm text-muted-foreground">
|
||||||
{player.currentTrack.album || player.currentTrack.animeName || ""}
|
{player.currentTrack.artist}
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|||||||
@@ -2,6 +2,7 @@
|
|||||||
import { Disc } from "@lucide/svelte";
|
import { Disc } from "@lucide/svelte";
|
||||||
import * as Drawer from "$lib/components/ui/drawer";
|
import * as Drawer from "$lib/components/ui/drawer";
|
||||||
import { player } from "$lib/player/store.svelte";
|
import { player } from "$lib/player/store.svelte";
|
||||||
|
import { songTypeNumberLabel } from "$lib/utils/amq";
|
||||||
import Controls from "./Controls.svelte";
|
import Controls from "./Controls.svelte";
|
||||||
import { getAudioContext } from "./ctx.svelte";
|
import { getAudioContext } from "./ctx.svelte";
|
||||||
import Queue from "./Queue.svelte";
|
import Queue from "./Queue.svelte";
|
||||||
@@ -9,6 +10,15 @@
|
|||||||
|
|
||||||
const audio = getAudioContext();
|
const audio = getAudioContext();
|
||||||
let open = $state(false);
|
let open = $state(false);
|
||||||
|
|
||||||
|
const displayTypeNumber = $derived(
|
||||||
|
player.currentTrack
|
||||||
|
? songTypeNumberLabel(
|
||||||
|
player.currentTrack.type,
|
||||||
|
player.currentTrack.number,
|
||||||
|
)
|
||||||
|
: "",
|
||||||
|
);
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<div class="z-50 border-t bg-background/95 backdrop-blur shadow-2xl">
|
<div class="z-50 border-t bg-background/95 backdrop-blur shadow-2xl">
|
||||||
@@ -19,19 +29,17 @@
|
|||||||
class="flex items-center gap-3 overflow-hidden flex-1 text-left bg-transparent border-none p-0 cursor-pointer"
|
class="flex items-center gap-3 overflow-hidden flex-1 text-left bg-transparent border-none p-0 cursor-pointer"
|
||||||
onclick={() => (open = true)}
|
onclick={() => (open = true)}
|
||||||
>
|
>
|
||||||
<!-- Placeholder Art -->
|
|
||||||
<div
|
|
||||||
class="h-10 w-10 rounded bg-muted flex items-center justify-center shrink-0"
|
|
||||||
>
|
|
||||||
<Disc class="h-6 w-6 text-muted-foreground" />
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="flex flex-col overflow-hidden">
|
<div class="flex flex-col overflow-hidden">
|
||||||
<div class="text-sm font-medium truncate leading-tight">
|
<div class="text-sm font-medium truncate leading-tight">
|
||||||
{player.currentTrack?.title || "Unknown Title"}
|
{player.currentTrack?.animeName || "Unknown"}
|
||||||
|
<span class="tag">{displayTypeNumber}</span>
|
||||||
</div>
|
</div>
|
||||||
<div class="text-xs text-muted-foreground truncate leading-tight">
|
<div class="text-xs text-muted-foreground truncate leading-tight">
|
||||||
{player.currentTrack?.artist || "Unknown Artist"}
|
{player.currentTrack?.title || "Unknown Title"}
|
||||||
|
<span class="text-muted-foreground"> · </span>
|
||||||
|
<span class="text-muted-foreground"
|
||||||
|
>{player.currentTrack?.globalPercent}%</span
|
||||||
|
>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</button>
|
</button>
|
||||||
@@ -59,14 +67,19 @@
|
|||||||
<div class="mx-auto w-full max-w-xl flex-1 flex flex-col p-4 gap-4">
|
<div class="mx-auto w-full max-w-xl flex-1 flex flex-col p-4 gap-4">
|
||||||
<!-- Track Info -->
|
<!-- Track Info -->
|
||||||
<div class="text-center space-y-1">
|
<div class="text-center space-y-1">
|
||||||
<h2 class="text-xl font-bold leading-tight line-clamp-2">
|
<h2 class="text-xl font-bold leading-tight">
|
||||||
{player.currentTrack?.title}
|
{player.currentTrack?.animeName}
|
||||||
|
<span class="tag">{displayTypeNumber}</span>
|
||||||
</h2>
|
</h2>
|
||||||
<p class="text-muted-foreground font-medium text-lg line-clamp-1">
|
<p class="text-foreground/80 font-medium text-lg line-clamp-1">
|
||||||
{player.currentTrack?.artist}
|
{player.currentTrack?.title}
|
||||||
|
<span class="text-muted-foreground"> · </span>
|
||||||
|
<span class="text-muted-foreground"
|
||||||
|
>{player.currentTrack?.globalPercent}%</span
|
||||||
|
>
|
||||||
</p>
|
</p>
|
||||||
<p class="text-xs text-muted-foreground/80 mt-1">
|
<p class="text-sm text-muted-foreground">
|
||||||
{player.currentTrack?.album || player.currentTrack?.animeName}
|
{player.currentTrack?.artist}
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@@ -87,7 +100,7 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- Main Controls -->
|
<!-- Main Controls -->
|
||||||
<div class="flex justify-center py-4">
|
<div class="flex justify-center">
|
||||||
<Controls />
|
<Controls />
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|||||||
@@ -1,7 +1,8 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { onMount, setContext } from "svelte";
|
import { onMount, setContext } from "svelte";
|
||||||
import { player } from "$lib/player/store.svelte";
|
import { player } from "$lib/player/store.svelte";
|
||||||
import { AudioContext, setAudioContext } from "./ctx.svelte";
|
import { songTypeNumberLabel } from "$lib/utils/amq";
|
||||||
|
import { AudioContext } from "./ctx.svelte";
|
||||||
import PlayerDesktop from "./PlayerDesktop.svelte";
|
import PlayerDesktop from "./PlayerDesktop.svelte";
|
||||||
import PlayerMobile from "./PlayerMobile.svelte";
|
import PlayerMobile from "./PlayerMobile.svelte";
|
||||||
|
|
||||||
@@ -13,8 +14,6 @@
|
|||||||
|
|
||||||
import { loadState, saveState } from "$lib/player/persist";
|
import { loadState, saveState } from "$lib/player/persist";
|
||||||
|
|
||||||
// ... existing imports ...
|
|
||||||
|
|
||||||
onMount(() => {
|
onMount(() => {
|
||||||
audioCtx.setElement(audioEl);
|
audioCtx.setElement(audioEl);
|
||||||
|
|
||||||
@@ -24,16 +23,34 @@
|
|||||||
player.init(saved);
|
player.init(saved);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Setup MediaSession
|
// Setup MediaSession actions
|
||||||
// ...
|
if ("mediaSession" in navigator) {
|
||||||
|
navigator.mediaSession.setActionHandler("play", () => audioCtx.play());
|
||||||
|
navigator.mediaSession.setActionHandler("pause", () => audioCtx.pause());
|
||||||
|
navigator.mediaSession.setActionHandler("previoustrack", () =>
|
||||||
|
player.prev(),
|
||||||
|
);
|
||||||
|
navigator.mediaSession.setActionHandler("nexttrack", () => player.next());
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
// ... existing effect for persistence ...
|
// Update MediaSession metadata when track changes
|
||||||
|
$effect(() => {
|
||||||
|
const track = player.currentTrack;
|
||||||
|
if ("mediaSession" in navigator) {
|
||||||
|
if (track) {
|
||||||
|
const typeLabel = songTypeNumberLabel(track.type, track.number);
|
||||||
|
navigator.mediaSession.metadata = new MediaMetadata({
|
||||||
|
title: `${track.animeName} (${typeLabel}) — ${track.title}`,
|
||||||
|
artist: track.artist,
|
||||||
|
album: track.animeName ?? "",
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
navigator.mediaSession.metadata = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
// Update MediaSession metadata
|
|
||||||
// ...
|
|
||||||
|
|
||||||
// ... existing effect for playback ...
|
|
||||||
$effect(() => {
|
$effect(() => {
|
||||||
const track = player.currentTrack;
|
const track = player.currentTrack;
|
||||||
if (audioEl) {
|
if (audioEl) {
|
||||||
|
|||||||
@@ -3,6 +3,7 @@
|
|||||||
import { Button } from "$lib/components/ui/button";
|
import { Button } from "$lib/components/ui/button";
|
||||||
import { player } from "$lib/player/store.svelte";
|
import { player } from "$lib/player/store.svelte";
|
||||||
import type { Track } from "$lib/player/types";
|
import type { Track } from "$lib/player/types";
|
||||||
|
import { songTypeNumberLabel } from "$lib/utils/amq";
|
||||||
|
|
||||||
function onRemove(id: number) {
|
function onRemove(id: number) {
|
||||||
player.remove(id);
|
player.remove(id);
|
||||||
@@ -106,20 +107,32 @@
|
|||||||
|
|
||||||
<div class="flex-1 min-w-0">
|
<div class="flex-1 min-w-0">
|
||||||
<div
|
<div
|
||||||
class="font-medium truncate"
|
class="font-medium"
|
||||||
class:text-primary={player.currentId === track.id}
|
class:text-primary={player.currentId === track.id}
|
||||||
>
|
>
|
||||||
{track.title}
|
{track.animeName}
|
||||||
|
<span class="tag"
|
||||||
|
>{songTypeNumberLabel(
|
||||||
|
track.type,
|
||||||
|
track.number,
|
||||||
|
)}</span
|
||||||
|
>
|
||||||
|
<span class="text-muted-foreground font-normal"
|
||||||
|
>{track.globalPercent}%</span
|
||||||
|
>
|
||||||
</div>
|
</div>
|
||||||
<div class="text-xs text-muted-foreground truncate">
|
<div class="text-xs text-foreground/80">
|
||||||
{track.artist}
|
{track.title} —
|
||||||
|
<span class="text-muted-foreground"
|
||||||
|
>{track.artist}</span
|
||||||
|
>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<Button
|
<Button
|
||||||
variant="ghost"
|
variant="ghost"
|
||||||
size="icon"
|
size="icon"
|
||||||
class="h-6 w-6 opacity-0 group-hover:opacity-100 transition-opacity"
|
class="h-6 w-6 opacity-50 group-hover:opacity-100 transition-opacity"
|
||||||
onclick={(e) => {
|
onclick={(e) => {
|
||||||
e.stopPropagation();
|
e.stopPropagation();
|
||||||
onRemove(track.id);
|
onRemove(track.id);
|
||||||
|
|||||||
@@ -37,7 +37,7 @@ export const songs = sqliteTable(
|
|||||||
fileName: text("file_name"),
|
fileName: text("file_name"),
|
||||||
fileName480: text("file_name_480"),
|
fileName480: text("file_name_480"),
|
||||||
fileName720: text("file_name_720"),
|
fileName720: text("file_name_720"),
|
||||||
globalPercent: integer("global_percent"),
|
globalPercent: integer("global_percent").notNull(),
|
||||||
meanVolume: real("mean_volume"),
|
meanVolume: real("mean_volume"),
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -18,11 +18,12 @@ export type Track = {
|
|||||||
|
|
||||||
/** Optional extra context for rendering/debugging */
|
/** Optional extra context for rendering/debugging */
|
||||||
animeName?: string;
|
animeName?: string;
|
||||||
type?: SongType;
|
type: SongType;
|
||||||
number?: number;
|
number: number;
|
||||||
fileName?: string | null;
|
fileName?: string | null;
|
||||||
dub?: boolean | null;
|
dub: boolean;
|
||||||
rebroadcast?: boolean | null;
|
rebroadcast: boolean;
|
||||||
|
globalPercent: number;
|
||||||
};
|
};
|
||||||
|
|
||||||
export type SongRowLike = {
|
export type SongRowLike = {
|
||||||
@@ -33,8 +34,9 @@ export type SongRowLike = {
|
|||||||
songName: string;
|
songName: string;
|
||||||
artistName: string | null;
|
artistName: string | null;
|
||||||
fileName?: string | null;
|
fileName?: string | null;
|
||||||
dub: boolean | null;
|
dub: boolean;
|
||||||
rebroadcast: boolean | null;
|
rebroadcast: boolean;
|
||||||
|
globalPercent: number;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -61,5 +63,6 @@ export function trackFromSongRow(row: SongRowLike): Track | null {
|
|||||||
fileName,
|
fileName,
|
||||||
dub: row.dub,
|
dub: row.dub,
|
||||||
rebroadcast: row.rebroadcast,
|
rebroadcast: row.rebroadcast,
|
||||||
|
globalPercent: row.globalPercent,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,20 +1,5 @@
|
|||||||
export const SongTypeMap: Record<string, number> = {
|
import { AmqSongLinkTypeMapReverse } from "$lib/types/amq";
|
||||||
OP: 1,
|
|
||||||
ED: 2,
|
|
||||||
INS: 3,
|
|
||||||
};
|
|
||||||
|
|
||||||
// Map number back to string for displaying in UI
|
export function songTypeNumberLabel(type: number, number: number) {
|
||||||
export const SongTypeReverseMap: Record<number, string> = {
|
return `${AmqSongLinkTypeMapReverse[type as keyof typeof AmqSongLinkTypeMapReverse] ?? `T${type}`}${number ? number : ""}`;
|
||||||
1: "OP",
|
}
|
||||||
2: "ED",
|
|
||||||
3: "INS",
|
|
||||||
};
|
|
||||||
|
|
||||||
export const SongCategoryMap: Record<number, string> = {
|
|
||||||
0: "None",
|
|
||||||
1: "Instrumental",
|
|
||||||
2: "Chanting",
|
|
||||||
3: "Character",
|
|
||||||
4: "Standard",
|
|
||||||
};
|
|
||||||
|
|||||||
@@ -74,6 +74,9 @@
|
|||||||
songName: s.songName,
|
songName: s.songName,
|
||||||
artistName: s.artistName,
|
artistName: s.artistName,
|
||||||
fileName: s.fileName ?? null,
|
fileName: s.fileName ?? null,
|
||||||
|
dub: Boolean(s.dub),
|
||||||
|
rebroadcast: Boolean(s.rebroadcast),
|
||||||
|
globalPercent: s.globalPercent,
|
||||||
}),
|
}),
|
||||||
)
|
)
|
||||||
.filter((t) => t !== null);
|
.filter((t) => t !== null);
|
||||||
@@ -98,6 +101,9 @@
|
|||||||
songName: s.songName,
|
songName: s.songName,
|
||||||
artistName: s.artistName,
|
artistName: s.artistName,
|
||||||
fileName: s.fileName ?? null,
|
fileName: s.fileName ?? null,
|
||||||
|
dub: Boolean(s.dub),
|
||||||
|
rebroadcast: Boolean(s.rebroadcast),
|
||||||
|
globalPercent: s.globalPercent,
|
||||||
}),
|
}),
|
||||||
)
|
)
|
||||||
.filter((t) => t !== null);
|
.filter((t) => t !== null);
|
||||||
@@ -157,8 +163,7 @@
|
|||||||
class="rounded border px-3 py-2 text-sm"
|
class="rounded border px-3 py-2 text-sm"
|
||||||
placeholder="Type to search by name…"
|
placeholder="Type to search by name…"
|
||||||
value={params.q}
|
value={params.q}
|
||||||
oninput={(e) =>
|
oninput={(e) => (params.q = (e.currentTarget as HTMLInputElement).value)}
|
||||||
(params.q = (e.currentTarget as HTMLInputElement).value)}
|
|
||||||
autocomplete="off"
|
autocomplete="off"
|
||||||
spellcheck={false}
|
spellcheck={false}
|
||||||
/>
|
/>
|
||||||
@@ -176,10 +181,7 @@
|
|||||||
<li class="rounded border px-3 py-2">
|
<li class="rounded border px-3 py-2">
|
||||||
<div class="flex flex-wrap items-center justify-between gap-3">
|
<div class="flex flex-wrap items-center justify-between gap-3">
|
||||||
<div class="min-w-0">
|
<div class="min-w-0">
|
||||||
<a
|
<a class="font-medium hover:underline" href={animeHref(a.annId)}>
|
||||||
class="font-medium hover:underline"
|
|
||||||
href={animeHref(a.annId)}
|
|
||||||
>
|
|
||||||
{a.mainName}
|
{a.mainName}
|
||||||
</a>
|
</a>
|
||||||
<div class="text-sm text-muted-foreground">
|
<div class="text-sm text-muted-foreground">
|
||||||
@@ -196,8 +198,7 @@
|
|||||||
type="button"
|
type="button"
|
||||||
class="btn-icon"
|
class="btn-icon"
|
||||||
onclick={() => void playAllNextForAnime(a)}
|
onclick={() => void playAllNextForAnime(a)}
|
||||||
disabled={a.opCount + a.edCount + a.insertCount ===
|
disabled={a.opCount + a.edCount + a.insertCount === 0}
|
||||||
0}
|
|
||||||
title="Play all next"
|
title="Play all next"
|
||||||
aria-label="Play all next"
|
aria-label="Play all next"
|
||||||
>
|
>
|
||||||
@@ -208,8 +209,7 @@
|
|||||||
type="button"
|
type="button"
|
||||||
class="btn-icon"
|
class="btn-icon"
|
||||||
onclick={() => void queueAllForAnime(a)}
|
onclick={() => void queueAllForAnime(a)}
|
||||||
disabled={a.opCount + a.edCount + a.insertCount ===
|
disabled={a.opCount + a.edCount + a.insertCount === 0}
|
||||||
0}
|
|
||||||
title="Queue all"
|
title="Queue all"
|
||||||
aria-label="Queue all"
|
aria-label="Queue all"
|
||||||
>
|
>
|
||||||
|
|||||||
@@ -38,6 +38,7 @@
|
|||||||
fileName: s.fileName ?? null,
|
fileName: s.fileName ?? null,
|
||||||
dub: Boolean(s.dub),
|
dub: Boolean(s.dub),
|
||||||
rebroadcast: Boolean(s.rebroadcast),
|
rebroadcast: Boolean(s.rebroadcast),
|
||||||
|
globalPercent: s.globalPercent,
|
||||||
}),
|
}),
|
||||||
)
|
)
|
||||||
.filter((t) => t !== null);
|
.filter((t) => t !== null);
|
||||||
|
|||||||
@@ -64,6 +64,7 @@
|
|||||||
fileName: r.fileName,
|
fileName: r.fileName,
|
||||||
dub: Boolean(r.dub),
|
dub: Boolean(r.dub),
|
||||||
rebroadcast: Boolean(r.rebroadcast),
|
rebroadcast: Boolean(r.rebroadcast),
|
||||||
|
globalPercent: r.globalPercent,
|
||||||
}),
|
}),
|
||||||
)
|
)
|
||||||
.filter((t) => t !== null),
|
.filter((t) => t !== null),
|
||||||
|
|||||||
@@ -51,6 +51,7 @@
|
|||||||
fileName: r.fileName,
|
fileName: r.fileName,
|
||||||
dub: Boolean(r.dub),
|
dub: Boolean(r.dub),
|
||||||
rebroadcast: Boolean(r.rebroadcast),
|
rebroadcast: Boolean(r.rebroadcast),
|
||||||
|
globalPercent: r.globalPercent,
|
||||||
}),
|
}),
|
||||||
)
|
)
|
||||||
.filter((t) => t !== null),
|
.filter((t) => t !== null),
|
||||||
|
|||||||
Reference in New Issue
Block a user