Merge pull request #190 from kveld9/feat/playlist-csv-import

feature: spotify CSV playlist import
This commit is contained in:
Psychotoxical
2026-04-15 18:09:27 +02:00
committed by GitHub
15 changed files with 867 additions and 21 deletions
+23 -7
View File
@@ -20,19 +20,21 @@ function reflow(): void {
}
}
export type ToastVariant = 'error' | 'info';
export type ToastVariant = 'error' | 'info' | 'warning' | 'success';
export function showToast(text: string, durationMs = 4000, variant: ToastVariant = 'info'): void {
const isError = variant === 'error';
const isWarning = variant === 'warning';
const isSuccess = variant === 'success';
const toast = document.createElement('div');
toast.className = 'psysonic-toast';
const icon = document.createElement('span');
icon.textContent = isError ? '✕' : '';
icon.textContent = isError ? '✕' : isWarning ? '!' : isSuccess ? '✓' : '';
icon.style.cssText = `
flex-shrink: 0;
font-size: 11px;
font-size: ${isSuccess ? '10px' : '11px'};
font-weight: 700;
width: 18px;
height: 18px;
@@ -40,7 +42,7 @@ export function showToast(text: string, durationMs = 4000, variant: ToastVariant
display: flex;
align-items: center;
justify-content: center;
background: ${isError ? 'var(--danger)' : 'var(--accent)'};
background: ${isError ? 'var(--danger)' : isWarning ? 'var(--warning, #f59e0b)' : isSuccess ? 'var(--success, #10b981)' : 'var(--accent)'};
color: var(--bg-app);
line-height: 1;
`;
@@ -49,6 +51,20 @@ export function showToast(text: string, durationMs = 4000, variant: ToastVariant
msg.textContent = text;
msg.style.cssText = `flex: 1; min-width: 0;`;
const getBorderColor = () => {
if (isError) return 'var(--danger)';
if (isWarning) return 'var(--warning, #f59e0b)';
if (isSuccess) return 'var(--success, #10b981)';
return 'var(--accent)';
};
const getBoxShadow = () => {
const base = '0 4px 24px rgba(0,0,0,0.45)';
if (isError) return `${base}, 0 0 0 1px color-mix(in srgb, var(--danger) 20%, transparent)`;
if (isWarning) return `${base}, 0 0 0 1px color-mix(in srgb, var(--warning, #f59e0b) 20%, transparent)`;
return base;
};
toast.style.cssText = `
position: fixed;
bottom: ${TOAST_BOTTOM_ANCHOR}px;
@@ -59,15 +75,15 @@ export function showToast(text: string, durationMs = 4000, variant: ToastVariant
gap: 10px;
background: var(--bg-card);
color: var(--text-primary);
border: 1px solid ${isError ? 'var(--danger)' : 'var(--border)'};
border-left: 3px solid ${isError ? 'var(--danger)' : 'var(--accent)'};
border: 1px solid ${getBorderColor()};
border-left: 3px solid ${getBorderColor()};
padding: 10px 16px;
border-radius: 8px;
font-size: 13.5px;
font-weight: 500;
z-index: 999999;
pointer-events: none;
box-shadow: 0 4px 24px rgba(0,0,0,0.45)${isError ? ', 0 0 0 1px color-mix(in srgb, var(--danger) 20%, transparent)' : ''};
box-shadow: ${getBoxShadow()};
white-space: normal;
word-break: break-word;
transition: bottom 150ms ease;