mirror of
https://github.com/moku-project/Moku.git
synced 2026-06-13 09:19:56 -05:00
Fix: CSS Issues
This commit is contained in:
@@ -27,7 +27,7 @@
|
|||||||
{#if store.toasts.length}
|
{#if store.toasts.length}
|
||||||
<div class="toaster" aria-live="polite">
|
<div class="toaster" aria-live="polite">
|
||||||
{#each store.toasts as t (t.id)}
|
{#each store.toasts as t (t.id)}
|
||||||
<div
|
<button
|
||||||
class="toast toast-{t.kind}"
|
class="toast toast-{t.kind}"
|
||||||
role="alert"
|
role="alert"
|
||||||
onclick={() => dismissToast(t.id)}
|
onclick={() => dismissToast(t.id)}
|
||||||
@@ -43,7 +43,7 @@
|
|||||||
<p class="title">{t.title}</p>
|
<p class="title">{t.title}</p>
|
||||||
{#if t.body}<p class="sub">{t.body}</p>{/if}
|
{#if t.body}<p class="sub">{t.body}</p>{/if}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</button>
|
||||||
{/each}
|
{/each}
|
||||||
</div>
|
</div>
|
||||||
{/if}
|
{/if}
|
||||||
@@ -76,6 +76,10 @@
|
|||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
animation: slideIn 0.2s cubic-bezier(0.16, 1, 0.3, 1) both;
|
animation: slideIn 0.2s cubic-bezier(0.16, 1, 0.3, 1) both;
|
||||||
transition: opacity 0.15s ease, transform 0.15s ease;
|
transition: opacity 0.15s ease, transform 0.15s ease;
|
||||||
|
font-family: inherit;
|
||||||
|
font-size: inherit;
|
||||||
|
color: inherit;
|
||||||
|
text-align: left;
|
||||||
}
|
}
|
||||||
|
|
||||||
.toast:hover { opacity: 0.85; transform: translateX(-2px); }
|
.toast:hover { opacity: 0.85; transform: translateX(-2px); }
|
||||||
|
|||||||
@@ -284,7 +284,7 @@
|
|||||||
.header { display: flex; align-items: center; gap: var(--sp-4); padding: var(--sp-4) var(--sp-6); border-bottom: 1px solid var(--border-dim); flex-shrink: 0; }
|
.header { display: flex; align-items: center; gap: var(--sp-4); padding: var(--sp-4) var(--sp-6); border-bottom: 1px solid var(--border-dim); flex-shrink: 0; }
|
||||||
.header-right { display: flex; align-items: center; gap: var(--sp-2); margin-left: auto; }
|
.header-right { display: flex; align-items: center; gap: var(--sp-2); margin-left: auto; }
|
||||||
.heading { font-family: var(--font-ui); font-size: var(--text-xs); font-weight: var(--weight-normal); color: var(--text-faint); letter-spacing: var(--tracking-wider); text-transform: uppercase; }
|
.heading { font-family: var(--font-ui); font-size: var(--text-xs); font-weight: var(--weight-normal); color: var(--text-faint); letter-spacing: var(--tracking-wider); text-transform: uppercase; }
|
||||||
.header-actions { display: flex; gap: var(--sp-1); }
|
|
||||||
.icon-btn { display: flex; align-items: center; justify-content: center; width: 28px; height: 28px; border-radius: var(--radius-md); color: var(--text-muted); transition: color var(--t-base), background var(--t-base); }
|
.icon-btn { display: flex; align-items: center; justify-content: center; width: 28px; height: 28px; border-radius: var(--radius-md); color: var(--text-muted); transition: color var(--t-base), background var(--t-base); }
|
||||||
.icon-btn:hover:not(:disabled) { color: var(--text-primary); background: var(--bg-raised); }
|
.icon-btn:hover:not(:disabled) { color: var(--text-primary); background: var(--bg-raised); }
|
||||||
.icon-btn:disabled { opacity: 0.4; }
|
.icon-btn:disabled { opacity: 0.4; }
|
||||||
|
|||||||
@@ -921,9 +921,9 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
{#if showResumeBanner}
|
{#if showResumeBanner}
|
||||||
<div class="resume-banner" class:fading={resumeFading} role="status" onclick={() => { resumeVisible = false; resumeFading = false; }}>
|
<button class="resume-banner" class:fading={resumeFading} onclick={() => { resumeVisible = false; resumeFading = false; }}>
|
||||||
<span>Bookmark at page {resumePage}</span>
|
<span>Bookmark at page {resumePage}</span>
|
||||||
</div>
|
</button>
|
||||||
{/if}
|
{/if}
|
||||||
|
|
||||||
<div
|
<div
|
||||||
@@ -1193,7 +1193,7 @@
|
|||||||
.slider-tooltip { position: absolute; bottom: calc(100% + 2px); transform: translateX(-50%); background: var(--bg-raised); border: 1px solid var(--border-base); border-radius: var(--radius-sm); padding: 2px 6px; font-family: var(--font-ui); font-size: var(--text-2xs); color: var(--text-secondary); white-space: nowrap; pointer-events: none; z-index: 10; letter-spacing: var(--tracking-wide); }
|
.slider-tooltip { position: absolute; bottom: calc(100% + 2px); transform: translateX(-50%); background: var(--bg-raised); border: 1px solid var(--border-base); border-radius: var(--radius-sm); padding: 2px 6px; font-family: var(--font-ui); font-size: var(--text-2xs); color: var(--text-secondary); white-space: nowrap; pointer-events: none; z-index: 10; letter-spacing: var(--tracking-wide); }
|
||||||
.slider-wrap:hover .slider-track-bg, .slider-wrap.dragging .slider-track-bg { height: 5px; }
|
.slider-wrap:hover .slider-track-bg, .slider-wrap.dragging .slider-track-bg { height: 5px; }
|
||||||
|
|
||||||
.resume-banner { position: fixed; top: 48px; left: 50%; display: flex; align-items: center; gap: var(--sp-2); background: var(--bg-raised); border: 1px solid var(--border-base); border-radius: var(--radius-lg); padding: 6px var(--sp-3); font-family: var(--font-ui); font-size: var(--text-xs); color: var(--text-secondary); z-index: 20; box-shadow: 0 4px 16px rgba(0,0,0,0.4); animation: bannerIn 0.2s cubic-bezier(0.16,1,0.3,1) both; white-space: nowrap; cursor: pointer; }
|
.resume-banner { position: fixed; top: 48px; left: 50%; display: flex; align-items: center; gap: var(--sp-2); background: var(--bg-raised); border: 1px solid var(--border-base); border-radius: var(--radius-lg); padding: 6px var(--sp-3); font-family: var(--font-ui); font-size: var(--text-xs); color: var(--text-secondary); z-index: 20; box-shadow: 0 4px 16px rgba(0,0,0,0.4); animation: bannerIn 0.2s cubic-bezier(0.16,1,0.3,1) both; white-space: nowrap; cursor: pointer; text-align: left; }
|
||||||
.resume-banner.fading { animation: bannerOut 1s ease forwards; }
|
.resume-banner.fading { animation: bannerOut 1s ease forwards; }
|
||||||
@keyframes bannerIn { from { opacity: 0; transform: translateX(-50%) translateY(-6px) scale(0.97); } to { opacity: 1; transform: translateX(-50%) translateY(0) scale(1); } }
|
@keyframes bannerIn { from { opacity: 0; transform: translateX(-50%) translateY(-6px) scale(0.97); } to { opacity: 1; transform: translateX(-50%) translateY(0) scale(1); } }
|
||||||
@keyframes bannerOut { from { opacity: 1; transform: translateX(-50%) translateY(0) scale(1); } to { opacity: 0; transform: translateX(-50%) translateY(-4px) scale(0.97); } }
|
@keyframes bannerOut { from { opacity: 1; transform: translateX(-50%) translateY(0) scale(1); } to { opacity: 0; transform: translateX(-50%) translateY(-4px) scale(0.97); } }
|
||||||
|
|||||||
@@ -12,8 +12,6 @@
|
|||||||
|
|
||||||
let { editingId = $bindable(null), onClose }: Props = $props();
|
let { editingId = $bindable(null), onClose }: Props = $props();
|
||||||
|
|
||||||
// ── Token group definitions ───────────────────────────────────────────────
|
|
||||||
|
|
||||||
const TOKEN_GROUPS: { label: string; tokens: (keyof ThemeTokens)[] }[] = [
|
const TOKEN_GROUPS: { label: string; tokens: (keyof ThemeTokens)[] }[] = [
|
||||||
{
|
{
|
||||||
label: "Backgrounds",
|
label: "Backgrounds",
|
||||||
@@ -65,8 +63,6 @@
|
|||||||
"color-info-bg": "Info background",
|
"color-info-bg": "Info background",
|
||||||
};
|
};
|
||||||
|
|
||||||
// ── State ─────────────────────────────────────────────────────────────────
|
|
||||||
|
|
||||||
function loadInitial(): { name: string; tokens: ThemeTokens } {
|
function loadInitial(): { name: string; tokens: ThemeTokens } {
|
||||||
if (editingId) {
|
if (editingId) {
|
||||||
const existing = store.settings.customThemes.find(t => t.id === editingId);
|
const existing = store.settings.customThemes.find(t => t.id === editingId);
|
||||||
@@ -81,13 +77,10 @@
|
|||||||
let saveStatus: "idle" | "saved" = $state("idle");
|
let saveStatus: "idle" | "saved" = $state("idle");
|
||||||
let importError: string | null = $state(null);
|
let importError: string | null = $state(null);
|
||||||
|
|
||||||
// ── CSS vars helper ───────────────────────────────────────────────────────
|
|
||||||
function toCssVars(t: ThemeTokens): string {
|
function toCssVars(t: ThemeTokens): string {
|
||||||
return Object.entries(t).map(([k, v]) => `--${k}: ${v};`).join(" ");
|
return Object.entries(t).map(([k, v]) => `--${k}: ${v};`).join(" ");
|
||||||
}
|
}
|
||||||
|
|
||||||
// ── Actions ───────────────────────────────────────────────────────────────
|
|
||||||
|
|
||||||
function handleSave() {
|
function handleSave() {
|
||||||
const name = themeName.trim() || "Untitled Theme";
|
const name = themeName.trim() || "Untitled Theme";
|
||||||
const id = editingId ?? `custom:${Math.random().toString(36).slice(2, 10)}`;
|
const id = editingId ?? `custom:${Math.random().toString(36).slice(2, 10)}`;
|
||||||
@@ -154,17 +147,15 @@
|
|||||||
|
|
||||||
<svelte:window onkeydown={onKey} />
|
<svelte:window onkeydown={onKey} />
|
||||||
|
|
||||||
<!-- ── Main editor ────────────────────────────────────────────────────────────── -->
|
<div class="te-backdrop" tabindex="-1" onclick={onClose} onkeydown={(e) => e.key === "Escape" && onClose()}>
|
||||||
<!-- svelte-ignore a11y_click_events_have_key_events a11y_no_static_element_interactions -->
|
|
||||||
<div class="te-backdrop" onclick={onClose} role="presentation">
|
|
||||||
<div
|
<div
|
||||||
class="te-shell"
|
class="te-shell"
|
||||||
role="dialog"
|
role="dialog"
|
||||||
aria-label="Theme editor"
|
aria-label="Theme editor"
|
||||||
|
tabindex="0"
|
||||||
onclick={(e) => e.stopPropagation()}
|
onclick={(e) => e.stopPropagation()}
|
||||||
>
|
>
|
||||||
|
|
||||||
<!-- ── Header ──────────────────────────────────────────────────────── -->
|
|
||||||
<header class="te-header">
|
<header class="te-header">
|
||||||
<div class="te-header-left">
|
<div class="te-header-left">
|
||||||
<button class="te-icon-btn" onclick={onClose} title="Close editor">
|
<button class="te-icon-btn" onclick={onClose} title="Close editor">
|
||||||
@@ -209,25 +200,17 @@
|
|||||||
</div>
|
</div>
|
||||||
</header>
|
</header>
|
||||||
|
|
||||||
<!-- ── Body ───────────────────────────────────────────────────────── -->
|
|
||||||
<div class="te-body">
|
<div class="te-body">
|
||||||
|
|
||||||
<!-- Left: live preview -->
|
|
||||||
<aside class="te-preview-pane">
|
<aside class="te-preview-pane">
|
||||||
<div class="te-pane-label">Live Preview</div>
|
<div class="te-pane-label">Live Preview</div>
|
||||||
|
|
||||||
<!--
|
|
||||||
FIX 1: toCssVars scoped only to this element, so only the
|
|
||||||
preview UI sees the draft tokens — not the editor shell.
|
|
||||||
-->
|
|
||||||
<div class="te-preview-ui" style={toCssVars(tokens)}>
|
<div class="te-preview-ui" style={toCssVars(tokens)}>
|
||||||
<!-- Sidebar -->
|
|
||||||
<div class="prv-sidebar">
|
<div class="prv-sidebar">
|
||||||
{#each [true, false, false, false] as active}
|
{#each [true, false, false, false] as active}
|
||||||
<div class="prv-sb-dot" class:active></div>
|
<div class="prv-sb-dot" class:active></div>
|
||||||
{/each}
|
{/each}
|
||||||
</div>
|
</div>
|
||||||
<!-- Main -->
|
|
||||||
<div class="prv-main">
|
<div class="prv-main">
|
||||||
<div class="prv-titlebar">
|
<div class="prv-titlebar">
|
||||||
<div class="prv-win-dots">
|
<div class="prv-win-dots">
|
||||||
@@ -262,7 +245,6 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- Swatch strip — scoped to draft tokens too -->
|
|
||||||
<div class="te-swatches" style={toCssVars(tokens)}>
|
<div class="te-swatches" style={toCssVars(tokens)}>
|
||||||
{#each [
|
{#each [
|
||||||
["bg-base","bg-base"],["bg-surface","bg-surface"],
|
["bg-base","bg-base"],["bg-surface","bg-surface"],
|
||||||
@@ -279,7 +261,6 @@
|
|||||||
</div>
|
</div>
|
||||||
</aside>
|
</aside>
|
||||||
|
|
||||||
<!-- Right: token editor -->
|
|
||||||
<div class="te-editor-pane">
|
<div class="te-editor-pane">
|
||||||
{#each TOKEN_GROUPS as group}
|
{#each TOKEN_GROUPS as group}
|
||||||
<div class="te-group">
|
<div class="te-group">
|
||||||
|
|||||||
@@ -11,8 +11,6 @@
|
|||||||
onClose: () => void;
|
onClose: () => void;
|
||||||
} = $props();
|
} = $props();
|
||||||
|
|
||||||
// ── Prefs helpers ──────────────────────────────────────────────────────────
|
|
||||||
|
|
||||||
const mangaPrefs = $derived(
|
const mangaPrefs = $derived(
|
||||||
(store.settings.mangaPrefs?.[mangaId] ?? {}) as Partial<MangaPrefs>
|
(store.settings.mangaPrefs?.[mangaId] ?? {}) as Partial<MangaPrefs>
|
||||||
);
|
);
|
||||||
@@ -30,15 +28,11 @@
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
// ── Scanlator list — derived from loaded chapters ──────────────────────────
|
|
||||||
|
|
||||||
const scanlators = $derived(
|
const scanlators = $derived(
|
||||||
[...new Set(chapters.map(c => c.scanlator).filter((s): s is string => !!s?.trim()))]
|
[...new Set(chapters.map(c => c.scanlator).filter((s): s is string => !!s?.trim()))]
|
||||||
.sort((a, b) => a.localeCompare(b))
|
.sort((a, b) => a.localeCompare(b))
|
||||||
);
|
);
|
||||||
|
|
||||||
// ── Options ────────────────────────────────────────────────────────────────
|
|
||||||
|
|
||||||
const DOWNLOAD_AHEAD_OPTIONS = [
|
const DOWNLOAD_AHEAD_OPTIONS = [
|
||||||
{ value: 0, label: "Off" },
|
{ value: 0, label: "Off" },
|
||||||
{ value: 2, label: "2" },
|
{ value: 2, label: "2" },
|
||||||
@@ -66,18 +60,14 @@
|
|||||||
{ value: "manual", label: "Manual" },
|
{ value: "manual", label: "Manual" },
|
||||||
];
|
];
|
||||||
|
|
||||||
// ── Backdrop close ─────────────────────────────────────────────────────────
|
|
||||||
|
|
||||||
function onBackdrop(e: MouseEvent) {
|
function onBackdrop(e: MouseEvent) {
|
||||||
if (e.target === e.currentTarget) onClose();
|
if (e.target === e.currentTarget) onClose();
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<!-- svelte-ignore a11y_no_static_element_interactions -->
|
<div class="backdrop" role="presentation" tabindex="-1" onmousedown={onBackdrop}>
|
||||||
<div class="backdrop" onmousedown={onBackdrop}>
|
|
||||||
<div class="modal" role="dialog" aria-modal="true" aria-label="Automation">
|
<div class="modal" role="dialog" aria-modal="true" aria-label="Automation">
|
||||||
|
|
||||||
<!-- Header -->
|
|
||||||
<div class="modal-header">
|
<div class="modal-header">
|
||||||
<div class="header-left">
|
<div class="header-left">
|
||||||
<span class="modal-title">Automation</span>
|
<span class="modal-title">Automation</span>
|
||||||
@@ -86,10 +76,8 @@
|
|||||||
<button class="close-btn" onclick={onClose} aria-label="Close"><X size={16} weight="light" /></button>
|
<button class="close-btn" onclick={onClose} aria-label="Close"><X size={16} weight="light" /></button>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- Body -->
|
|
||||||
<div class="modal-body">
|
<div class="modal-body">
|
||||||
|
|
||||||
<!-- ── Downloads ────────────────────────────────────────────────────── -->
|
|
||||||
<p class="section-label">Downloads</p>
|
<p class="section-label">Downloads</p>
|
||||||
|
|
||||||
<div class="auto-row">
|
<div class="auto-row">
|
||||||
@@ -100,6 +88,7 @@
|
|||||||
<button
|
<button
|
||||||
role="switch"
|
role="switch"
|
||||||
aria-checked={getPref("autoDownload")}
|
aria-checked={getPref("autoDownload")}
|
||||||
|
aria-label="Auto-download new chapters"
|
||||||
class="auto-toggle"
|
class="auto-toggle"
|
||||||
class:auto-toggle-on={getPref("autoDownload")}
|
class:auto-toggle-on={getPref("autoDownload")}
|
||||||
onclick={() => setPref("autoDownload", !getPref("autoDownload"))}
|
onclick={() => setPref("autoDownload", !getPref("autoDownload"))}
|
||||||
@@ -140,7 +129,6 @@
|
|||||||
|
|
||||||
<div class="divider"></div>
|
<div class="divider"></div>
|
||||||
|
|
||||||
<!-- ── On Read ──────────────────────────────────────────────────────── -->
|
|
||||||
<p class="section-label">On Read</p>
|
<p class="section-label">On Read</p>
|
||||||
|
|
||||||
<div class="auto-row">
|
<div class="auto-row">
|
||||||
@@ -151,6 +139,7 @@
|
|||||||
<button
|
<button
|
||||||
role="switch"
|
role="switch"
|
||||||
aria-checked={getPref("deleteOnRead")}
|
aria-checked={getPref("deleteOnRead")}
|
||||||
|
aria-label="Delete after reading"
|
||||||
class="auto-toggle"
|
class="auto-toggle"
|
||||||
class:auto-toggle-on={getPref("deleteOnRead")}
|
class:auto-toggle-on={getPref("deleteOnRead")}
|
||||||
onclick={() => setPref("deleteOnRead", !getPref("deleteOnRead"))}
|
onclick={() => setPref("deleteOnRead", !getPref("deleteOnRead"))}
|
||||||
@@ -174,7 +163,6 @@
|
|||||||
|
|
||||||
<div class="divider"></div>
|
<div class="divider"></div>
|
||||||
|
|
||||||
<!-- ── Updates ─────────────────────────────────────────────────────── -->
|
|
||||||
<p class="section-label">Updates</p>
|
<p class="section-label">Updates</p>
|
||||||
|
|
||||||
<div class="auto-row">
|
<div class="auto-row">
|
||||||
@@ -185,6 +173,7 @@
|
|||||||
<button
|
<button
|
||||||
role="switch"
|
role="switch"
|
||||||
aria-checked={getPref("pauseUpdates")}
|
aria-checked={getPref("pauseUpdates")}
|
||||||
|
aria-label="Pause updates"
|
||||||
class="auto-toggle"
|
class="auto-toggle"
|
||||||
class:auto-toggle-on={getPref("pauseUpdates")}
|
class:auto-toggle-on={getPref("pauseUpdates")}
|
||||||
onclick={() => setPref("pauseUpdates", !getPref("pauseUpdates"))}
|
onclick={() => setPref("pauseUpdates", !getPref("pauseUpdates"))}
|
||||||
@@ -210,7 +199,6 @@
|
|||||||
{#if scanlators.length > 1}
|
{#if scanlators.length > 1}
|
||||||
<div class="divider"></div>
|
<div class="divider"></div>
|
||||||
|
|
||||||
<!-- ── Scanlator ──────────────────────────────────────────────────── -->
|
|
||||||
<p class="section-label">Scanlator</p>
|
<p class="section-label">Scanlator</p>
|
||||||
|
|
||||||
<div class="auto-row auto-row-align-start">
|
<div class="auto-row auto-row-align-start">
|
||||||
|
|||||||
@@ -19,8 +19,6 @@
|
|||||||
onClose: () => void;
|
onClose: () => void;
|
||||||
} = $props();
|
} = $props();
|
||||||
|
|
||||||
// ── State ──────────────────────────────────────────────────────────────────
|
|
||||||
|
|
||||||
type TabId = "records" | number;
|
type TabId = "records" | number;
|
||||||
|
|
||||||
let trackers: Tracker[] = $state([]);
|
let trackers: Tracker[] = $state([]);
|
||||||
@@ -39,8 +37,6 @@
|
|||||||
let editingChapter: number | null = $state(null);
|
let editingChapter: number | null = $state(null);
|
||||||
let chapterDraft: number = $state(0);
|
let chapterDraft: number = $state(0);
|
||||||
|
|
||||||
// ── Load ───────────────────────────────────────────────────────────────────
|
|
||||||
|
|
||||||
async function load() {
|
async function load() {
|
||||||
loading = true;
|
loading = true;
|
||||||
try {
|
try {
|
||||||
@@ -61,7 +57,6 @@
|
|||||||
|
|
||||||
$effect(() => { load(); });
|
$effect(() => { load(); });
|
||||||
|
|
||||||
// Auto-search with manga title when switching to a tracker tab
|
|
||||||
$effect(() => {
|
$effect(() => {
|
||||||
const tab = activeTab;
|
const tab = activeTab;
|
||||||
if (typeof tab !== "number") return;
|
if (typeof tab !== "number") return;
|
||||||
@@ -71,14 +66,10 @@
|
|||||||
doSearch(tab, mangaTitle);
|
doSearch(tab, mangaTitle);
|
||||||
});
|
});
|
||||||
|
|
||||||
// ── Helpers ────────────────────────────────────────────────────────────────
|
|
||||||
|
|
||||||
function trackerFor(id: number) { return trackers.find(t => t.id === id); }
|
function trackerFor(id: number) { return trackers.find(t => t.id === id); }
|
||||||
function recordFor(trackerId: number){ return records.find(r => r.trackerId === trackerId); }
|
function recordFor(trackerId: number){ return records.find(r => r.trackerId === trackerId); }
|
||||||
const loggedInTrackers = $derived(trackers.filter(t => t.isLoggedIn));
|
const loggedInTrackers = $derived(trackers.filter(t => t.isLoggedIn));
|
||||||
|
|
||||||
// ── Search ─────────────────────────────────────────────────────────────────
|
|
||||||
|
|
||||||
let searchTimer: ReturnType<typeof setTimeout>;
|
let searchTimer: ReturnType<typeof setTimeout>;
|
||||||
|
|
||||||
function onSearchInput() {
|
function onSearchInput() {
|
||||||
@@ -105,8 +96,6 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// ── Bind / Unbind ──────────────────────────────────────────────────────────
|
|
||||||
|
|
||||||
async function bind(result: TrackSearch) {
|
async function bind(result: TrackSearch) {
|
||||||
if (typeof activeTab !== "number") return;
|
if (typeof activeTab !== "number") return;
|
||||||
binding = true;
|
binding = true;
|
||||||
@@ -137,8 +126,6 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// ── Update ─────────────────────────────────────────────────────────────────
|
|
||||||
|
|
||||||
async function updateStatus(record: TrackRecord, status: number) {
|
async function updateStatus(record: TrackRecord, status: number) {
|
||||||
updatingRecord = record.id;
|
updatingRecord = record.id;
|
||||||
try {
|
try {
|
||||||
@@ -234,7 +221,6 @@
|
|||||||
>
|
>
|
||||||
<div class="modal" role="dialog" aria-label="Tracking">
|
<div class="modal" role="dialog" aria-label="Tracking">
|
||||||
|
|
||||||
<!-- ── Header ─────────────────────────────────────────────────────────── -->
|
|
||||||
<div class="modal-header">
|
<div class="modal-header">
|
||||||
<div class="header-left">
|
<div class="header-left">
|
||||||
<span class="modal-title">Tracking</span>
|
<span class="modal-title">Tracking</span>
|
||||||
@@ -256,7 +242,6 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
{:else}
|
{:else}
|
||||||
<!-- ── Tabs ──────────────────────────────────────────────────────────── -->
|
|
||||||
<div class="tabs">
|
<div class="tabs">
|
||||||
<button
|
<button
|
||||||
class="tab"
|
class="tab"
|
||||||
@@ -282,7 +267,6 @@
|
|||||||
{/each}
|
{/each}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- ── My List tab ───────────────────────────────────────────────────── -->
|
|
||||||
{#if activeTab === "records"}
|
{#if activeTab === "records"}
|
||||||
<div class="tab-body">
|
<div class="tab-body">
|
||||||
{#if records.length === 0}
|
{#if records.length === 0}
|
||||||
@@ -434,7 +418,6 @@
|
|||||||
{/if}
|
{/if}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- ── Tracker search tab ─────────────────────────────────────────────── -->
|
|
||||||
{:else}
|
{:else}
|
||||||
{@const tracker = trackerFor(activeTab as number)}
|
{@const tracker = trackerFor(activeTab as number)}
|
||||||
{@const boundRecord = recordFor(activeTab as number)}
|
{@const boundRecord = recordFor(activeTab as number)}
|
||||||
@@ -644,7 +627,6 @@
|
|||||||
.result-bound { background: color-mix(in srgb, var(--accent) 8%, transparent) !important; }
|
.result-bound { background: color-mix(in srgb, var(--accent) 8%, transparent) !important; }
|
||||||
.result-cover { width: 44px; height: 62px; object-fit: cover; border-radius: var(--radius-sm); border: 1px solid var(--border-dim); flex-shrink: 0; }
|
.result-cover { width: 44px; height: 62px; object-fit: cover; border-radius: var(--radius-sm); border: 1px solid var(--border-dim); flex-shrink: 0; }
|
||||||
.result-cover-empty { background: var(--bg-raised); }
|
.result-cover-empty { background: var(--bg-raised); }
|
||||||
.hidden { display: none; }
|
|
||||||
.result-info { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: var(--sp-1); padding-top: 2px; }
|
.result-info { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: var(--sp-1); padding-top: 2px; }
|
||||||
.result-title { font-size: var(--text-sm); color: var(--text-secondary); line-height: var(--leading-snug); text-align: left; }
|
.result-title { font-size: var(--text-sm); color: var(--text-secondary); line-height: var(--leading-snug); text-align: left; }
|
||||||
.result-meta { display: flex; flex-wrap: wrap; gap: var(--sp-1); }
|
.result-meta { display: flex; flex-wrap: wrap; gap: var(--sp-1); }
|
||||||
|
|||||||
Reference in New Issue
Block a user