From eebd1b6446d4f75b23b09bbd38079e32f8a442e8 Mon Sep 17 00:00:00 2001 From: Youwes09 Date: Sat, 28 Mar 2026 20:09:40 -0500 Subject: [PATCH] Fix: Remove Manga Drag & Drop + Libray Move System --- src/components/pages/Library.svelte | 391 ++++++++++++++++------------ 1 file changed, 228 insertions(+), 163 deletions(-) diff --git a/src/components/pages/Library.svelte b/src/components/pages/Library.svelte index 6ad1e57..b647429 100644 --- a/src/components/pages/Library.svelte +++ b/src/components/pages/Library.svelte @@ -1,6 +1,6 @@ @@ -545,9 +516,9 @@ draggable="true" onclick={() => store.libraryFilter = String(cat.id)} ondragstart={(e) => onTabDragStart(e, cat)} - ondragover={(e) => tabDragOver(e, cat, idx)} - ondragleave={tabDragLeave} - ondrop={(e) => tabDrop(e, cat)} + ondragover={(e) => onTabDragOver(e, cat, idx)} + ondragleave={onTabDragLeave} + ondrop={(e) => onTabDrop(e, cat)} ondragend={onTabDragEnd} > {#if isDefault} @@ -570,6 +541,53 @@ + + {#if selectMode} +
+
+ + {selectedIds.size} selected + +
+
+ {#if visibleCategories.length} +
+ + {#if bulkMoveOpen} +
+ {#each visibleCategories as cat} + + {/each} +
+ {/if} +
+ {/if} + +
+
+ {/if} +
{#if loading}
@@ -589,19 +607,32 @@ {:else}
{#each visibleManga as m (m.id)} + {@const isSelected = selectedIds.has(m.id)} @@ -650,15 +681,49 @@ .search { background: var(--bg-raised); border: 1px solid var(--border-dim); border-radius: var(--radius-md); padding: 5px 10px 5px 28px; color: var(--text-primary); font-size: var(--text-sm); width: 180px; outline: none; transition: border-color var(--t-base); } .search::placeholder { color: var(--text-faint); } .search:focus { border-color: var(--border-strong); } + + /* ── Selection toolbar ──────────────────────────────────────────────────── */ + .select-bar { display: flex; align-items: center; justify-content: space-between; gap: var(--sp-3); padding: var(--sp-2) var(--sp-6); background: var(--bg-raised); border-bottom: 1px solid var(--accent-dim); flex-shrink: 0; animation: fadeIn 0.1s ease both; } + .select-bar-left { display: flex; align-items: center; gap: var(--sp-3); } + .select-bar-right { display: flex; align-items: center; gap: var(--sp-2); position: relative; } + .sel-count { font-family: var(--font-ui); font-size: var(--text-xs); color: var(--accent-fg); letter-spacing: var(--tracking-wide); } + .sel-btn { display: flex; align-items: center; gap: 5px; font-family: var(--font-ui); font-size: var(--text-2xs); letter-spacing: var(--tracking-wide); text-transform: uppercase; padding: 4px 10px; border-radius: var(--radius-sm); border: 1px solid var(--border-dim); background: var(--bg-base); color: var(--text-muted); cursor: pointer; transition: color var(--t-base), border-color var(--t-base), background var(--t-base); white-space: nowrap; } + .sel-btn:hover:not(:disabled) { color: var(--text-primary); border-color: var(--border-strong); } + .sel-btn:disabled { opacity: 0.4; cursor: not-allowed; } + .sel-cancel { border-color: transparent; background: transparent; } + .sel-cancel:hover { background: var(--bg-raised); border-color: var(--border-dim); } + .sel-move { color: var(--accent-fg); border-color: var(--accent-dim); background: var(--accent-muted); } + .sel-move:hover:not(:disabled) { background: var(--accent-dim); } + .sel-remove { color: var(--color-error, #e05c5c); border-color: color-mix(in srgb, var(--color-error, #e05c5c) 30%, transparent); } + .sel-remove:hover:not(:disabled) { background: color-mix(in srgb, var(--color-error, #e05c5c) 12%, transparent); } + .sel-all { border-color: transparent; background: transparent; } + + /* Bulk folder dropdown */ + .bulk-move-wrap { position: relative; } + .bulk-folder-list { position: absolute; top: calc(100% + 4px); right: 0; z-index: 200; background: var(--bg-raised); border: 1px solid var(--border-dim); border-radius: var(--radius-md); padding: 4px; min-width: 160px; box-shadow: 0 8px 24px rgba(0,0,0,0.35); animation: fadeIn 0.1s ease both; } + .bulk-folder-item { display: flex; align-items: center; gap: 6px; width: 100%; padding: 6px 10px; border-radius: var(--radius-sm); border: none; background: transparent; color: var(--text-muted); font-family: var(--font-ui); font-size: var(--text-xs); cursor: pointer; text-align: left; transition: background var(--t-base), color var(--t-base); } + .bulk-folder-item:hover { background: var(--bg-hover, var(--bg-base)); color: var(--text-primary); } + + /* ── Grid & cards ───────────────────────────────────────────────────────── */ .grid { position: relative; z-index: 1; display: grid; grid-template-columns: repeat(var(--cols, auto-fill), minmax(130px, 1fr)); gap: var(--sp-4); } .card { background: none; border: none; padding: 0; cursor: pointer; text-align: left; } - .card-dragging { opacity: 0.4; cursor: grabbing; } .card:hover .cover { filter: brightness(1.07); } .card:hover .title { color: var(--text-primary); } + /* In select mode, clicking always means "select", so use a checkbox cursor */ + .card.select-mode { cursor: default; } + .card.card-selected .cover-wrap { outline: 2px solid var(--accent); outline-offset: 2px; border-radius: var(--radius-md); } + .card.card-selected .title { color: var(--accent-fg); } .cover-wrap { position: relative; aspect-ratio: 2/3; overflow: hidden; border-radius: var(--radius-md); background: var(--bg-raised); border: 1px solid var(--border-dim); transform: translateZ(0); } .cover { width: 100%; height: 100%; transition: filter var(--t-base); will-change: filter; } .badge-dl { position: absolute; bottom: var(--sp-1); right: var(--sp-1); min-width: 18px; height: 18px; padding: 0 3px; display: flex; align-items: center; justify-content: center; font-size: 10px; font-weight: bold; background: var(--accent-dim); color: var(--accent-fg); border-radius: var(--radius-sm); border: 1px solid var(--accent-muted); } .badge-unread { position: absolute; top: var(--sp-1); left: var(--sp-1); min-width: 18px; height: 18px; padding: 0 4px; display: flex; align-items: center; justify-content: center; font-size: 10px; font-weight: bold; background: var(--bg-void); color: var(--text-primary); border-radius: var(--radius-sm); border: 1px solid var(--border-strong); } + + /* Select overlay (checkbox) */ + .select-overlay { position: absolute; inset: 0; background: rgba(0,0,0,0.18); display: flex; align-items: flex-start; justify-content: flex-end; padding: 6px; pointer-events: none; } + .select-check { color: var(--text-faint); opacity: 0.7; transition: color var(--t-base), opacity var(--t-base); } + .select-check.checked { color: var(--accent-fg); opacity: 1; } + .select-check-empty { width: 20px; height: 20px; border-radius: 4px; border: 2px solid var(--text-faint); background: rgba(0,0,0,0.3); } + .title { margin-top: var(--sp-2); font-size: var(--text-sm); color: var(--text-secondary); line-height: var(--leading-snug); display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden; transition: color var(--t-base); } .card-skeleton { padding: 0; } .cover-skeleton { aspect-ratio: 2/3; border-radius: var(--radius-md); }