mirror of
https://github.com/ksyasuda/SubMiner.git
synced 2026-07-30 07:21:32 -07:00
feat(stats): add library entry deletion and app-wide delete progress
- Add "Delete Entry" to the anime detail view: removes every episode, session, subtitle line, rollup and cover art for a title plus the vocab counts derived from them, then drops it from the Library grid; refused while that title is currently playing. - Show delete progress (session, session group, episode, entry) app-wide via a top progress bar + status toast that persist across tab switches, detail views, and the stats overlay window instead of going blank off-tab. - Fix delete and Vocabulary-tab performance: store seen_ms on word/kanji occurrences so deletes subtract only removed rows via a covering index instead of rescanning each word's full history, and paginate vocab rows before aggregating anime counts. - Migrate existing databases in place on first launch after upgrade.
This commit is contained in:
@@ -6,6 +6,8 @@ interface AnimeHeaderProps {
|
||||
anilistEntries: AnilistEntry[];
|
||||
coverRetryToken?: number;
|
||||
onChangeAnilist?: () => void;
|
||||
onDeleteAnime?: () => void;
|
||||
isDeletingAnime?: boolean;
|
||||
}
|
||||
|
||||
function AnilistButton({ entry }: { entry: AnilistEntry }) {
|
||||
@@ -32,6 +34,8 @@ export function AnimeHeader({
|
||||
anilistEntries,
|
||||
coverRetryToken = 0,
|
||||
onChangeAnilist,
|
||||
onDeleteAnime,
|
||||
isDeletingAnime = false,
|
||||
}: AnimeHeaderProps) {
|
||||
const altTitles = [detail.titleRomaji, detail.titleEnglish, detail.titleNative].filter(
|
||||
(t): t is string => t != null && t !== detail.canonicalTitle,
|
||||
@@ -95,6 +99,25 @@ export function AnimeHeader({
|
||||
: 'Link to AniList'}
|
||||
</button>
|
||||
)}
|
||||
{onDeleteAnime && (
|
||||
<button
|
||||
type="button"
|
||||
onClick={onDeleteAnime}
|
||||
disabled={isDeletingAnime}
|
||||
title="Delete this title and every session and stat recorded for it"
|
||||
className="inline-flex items-center gap-1 px-2 py-1 text-xs rounded bg-ctp-surface1 text-ctp-red/80 hover:bg-ctp-red/15 hover:text-ctp-red transition-colors disabled:opacity-50 disabled:cursor-not-allowed"
|
||||
>
|
||||
{isDeletingAnime ? (
|
||||
<span
|
||||
aria-hidden="true"
|
||||
className="h-3 w-3 animate-spin rounded-full border-2 border-ctp-surface2 border-t-ctp-red"
|
||||
/>
|
||||
) : (
|
||||
<span aria-hidden="true">{'\u2715'}</span>
|
||||
)}
|
||||
{isDeletingAnime ? 'Deleting\u2026' : 'Delete Entry'}
|
||||
</button>
|
||||
)}
|
||||
</div>
|
||||
{detail.description && (
|
||||
<p className="text-xs text-ctp-subtext0 mt-3 line-clamp-3 leading-relaxed">
|
||||
|
||||
Reference in New Issue
Block a user