fixed common track scanning bugs with custom workarounds

This commit is contained in:
2026-02-20 17:14:03 -05:00
parent 84f027aedf
commit 089af5e299
7 changed files with 817 additions and 10 deletions
@@ -183,6 +183,8 @@ export class ConfigPage extends LitElement {
@state() private statusMessage = '';
@state() private metrics: ScanMetrics | null = null;
@state() private copied = false;
@state() private errorsCopied = false;
@state() private scanErrors = '';
@state() private concurrencyMode = 'auto';
private cancelScanStarted?: () => void;
@@ -293,6 +295,49 @@ export class ConfigPage extends LitElement {
color: var(--yj-accent, #ffd43b);
}
/* Error block */
.error-block {
margin-top: 1em;
border: 1px solid var(--yj-error, #e03131);
border-radius: 4px;
overflow: hidden;
}
.error-header {
display: flex;
align-items: center;
justify-content: space-between;
padding: 0.5em 1em;
background: color-mix(
in srgb,
var(--yj-error, #e03131) 15%,
var(--yj-bg-elevated, #343a40)
);
}
.error-title {
font-size: 0.8em;
font-weight: 600;
color: var(--yj-error, #e03131);
}
.error-body {
max-height: 200px;
overflow-y: auto;
padding: 0.75em 1em;
background: var(--yj-bg-elevated, #343a40);
}
.error-body pre {
margin: 0;
font-size: 0.8em;
font-family: inherit;
white-space: pre-wrap;
word-break: break-word;
color: var(--yj-text-secondary, #adb5bd);
line-height: 1.6;
}
/* Metrics tree */
.metrics-wrapper {
margin-top: 1em;
@@ -472,6 +517,8 @@ export class ConfigPage extends LitElement {
this.statusMessage = 'Scanning...';
this.metrics = null;
this.copied = false;
this.scanErrors = '';
this.errorsCopied = false;
};
private handleScanComplete = (
@@ -536,7 +583,9 @@ export class ConfigPage extends LitElement {
try {
await Scan();
} catch (err) {
this.statusMessage = `Scan failed: ${err}`;
this.statusMessage =
'Scan completed with errors.';
this.scanErrors = String(err);
}
};
@@ -550,7 +599,9 @@ export class ConfigPage extends LitElement {
try {
await FullRescan();
} catch (err) {
this.statusMessage = `Full rescan failed: ${err}`;
this.statusMessage =
'Full rescan completed with errors.';
this.scanErrors = String(err);
}
};
@@ -573,6 +624,27 @@ export class ConfigPage extends LitElement {
}
};
private handleCopyErrors =
async (): Promise<void> => {
if (!this.scanErrors) return;
try {
await navigator.clipboard.writeText(
this.scanErrors,
);
this.errorsCopied = true;
setTimeout(() => {
this.errorsCopied = false;
}, 2000);
} catch (err) {
console.error(
'Failed to copy errors:',
err,
);
}
};
// ===================================================================
// THEME HANDLERS
// ===================================================================
@@ -817,6 +889,29 @@ export class ConfigPage extends LitElement {
${this.statusMessage || 'Ready.'}
</div>
${this.scanErrors
? html`
<div class="error-block">
<div class="error-header">
<span class="error-title">
Scan Errors
</span>
<button
class="btn-ghost ${this.errorsCopied ? 'copied' : ''}"
@click=${this.handleCopyErrors}
>
${this.errorsCopied
? 'Copied!'
: 'Copy'}
</button>
</div>
<div class="error-body">
<pre>${this.scanErrors}</pre>
</div>
</div>
`
: ''}
${this.renderMetrics()}
</config-section>
`;
@@ -234,6 +234,8 @@ export class LibraryManager extends LitElement {
@state() private statusMessage = '';
@state() private metrics: ScanMetrics | null = null;
@state() private copied = false;
@state() private errorsCopied = false;
@state() private scanErrors = '';
@state() private concurrencyMode = 'auto';
private cancelScanStarted?: () => void;
private cancelScanComplete?: () => void;
@@ -436,6 +438,49 @@ export class LibraryManager extends LitElement {
color: var(--yj-accent, #ffd43b);
}
/* --- Error block --- */
.error-block {
margin-top: 1em;
border: 1px solid var(--yj-error, #e03131);
border-radius: 4px;
overflow: hidden;
}
.error-header {
display: flex;
align-items: center;
justify-content: space-between;
padding: 0.5em 1em;
background: color-mix(
in srgb,
var(--yj-error, #e03131) 15%,
var(--yj-bg-elevated, #1a1d20)
);
}
.error-title {
font-size: 0.8em;
font-weight: 600;
color: var(--yj-error, #e03131);
}
.error-body {
max-height: 200px;
overflow-y: auto;
padding: 0.75em 1em;
background: var(--yj-bg-elevated, #1a1d20);
}
.error-body pre {
margin: 0;
font-size: 0.8em;
font-family: inherit;
white-space: pre-wrap;
word-break: break-word;
color: var(--yj-text-secondary, #adb5bd);
line-height: 1.6;
}
/* --- Metrics tree --- */
.metrics-section {
margin-top: 1.5em;
@@ -593,6 +638,8 @@ export class LibraryManager extends LitElement {
this.statusMessage = 'Scanning...';
this.metrics = null;
this.copied = false;
this.scanErrors = '';
this.errorsCopied = false;
};
private handleScanComplete = (
@@ -647,7 +694,9 @@ export class LibraryManager extends LitElement {
try {
await Scan();
} catch (err) {
this.statusMessage = `Scan failed: ${err}`;
this.statusMessage =
'Scan completed with errors.';
this.scanErrors = String(err);
console.error('Soft scan failed:', err);
}
};
@@ -663,7 +712,9 @@ export class LibraryManager extends LitElement {
try {
await FullRescan();
} catch (err) {
this.statusMessage = `Full rescan failed: ${err}`;
this.statusMessage =
'Full rescan completed with errors.';
this.scanErrors = String(err);
console.error(
'Full rescan failed:',
err,
@@ -694,6 +745,27 @@ export class LibraryManager extends LitElement {
}
};
private handleCopyErrors =
async (): Promise<void> => {
if (!this.scanErrors) return;
try {
await navigator.clipboard.writeText(
this.scanErrors,
);
this.errorsCopied = true;
setTimeout(() => {
this.errorsCopied = false;
}, 2000);
} catch (err) {
console.error(
'Failed to copy errors:',
err,
);
}
};
private get directoryChanged(): boolean {
return (
this.selectedDirectory !==
@@ -1006,6 +1078,29 @@ export class LibraryManager extends LitElement {
${this.statusMessage || 'Ready.'}
</div>
${this.scanErrors
? html`
<div class="error-block">
<div class="error-header">
<span class="error-title">
Scan Errors
</span>
<button
class="btn-ghost ${this.errorsCopied ? 'copied' : ''}"
@click=${this.handleCopyErrors}
>
${this.errorsCopied
? 'Copied!'
: 'Copy'}
</button>
</div>
<div class="error-body">
<pre>${this.scanErrors}</pre>
</div>
</div>
`
: ''}
${this.renderMetrics()}
`;
}