Remove comments from backend and web-player source

Strip //, /* */ and XML doc comments from all backend .cs files, and
JS/TS/CSS/HTML comments from web-player source (.ts, .svelte, .css),
per the project's no-comments convention.
This commit is contained in:
2026-09-21 17:12:18 +02:00
parent 1b6d7ecb42
commit 2662abe460
99 changed files with 381 additions and 578 deletions
+1 -23
View File
@@ -1,21 +1,4 @@
#!/usr/bin/env node
// Guardrail contra la reintroducción de lo que P0-P14 limpió
// (ver docs/frontend-refactor-plan.md, secciones B.4 y P14). Escanea
// src/**/*.svelte en busca de valores arbitrarios y utilidades de Tailwind
// que deberían ser tokens del sistema de diseño (src/routes/layout.css).
//
// Gaps conocidos, no cubiertos aquí a propósito:
// - `strokeWidth={n}` en iconos: hay ~13 valores distintos repartidos por
// casi todos los componentes. Migrarlo a las recetas `stroke-*` requeriría
// verificar que lucide-svelte respeta `stroke-width` por CSS en vez del
// atributo del componente, y no hay forma de comprobarlo visualmente en
// esta sesión (sin Docker). Se deja fuera para no arriesgar una regresión
// silenciosa en todos los iconos de la app.
// - `text-base` sin receta: solo queda un caso real (Queue.svelte, título
// "En cola", 16px) sin equivalente en la escala text-display-*. Crear una
// receta nueva para un único consumidor sería una abstracción prematura;
// se acepta como excepción documentada en vez de forzarlo a un tamaño que
// no le corresponde.
import { readFileSync } from 'node:fs';
import { execSync } from 'node:child_process';
@@ -24,7 +7,6 @@ const files = execSync('git ls-files "src/**/*.svelte"', { encoding: 'utf8' })
.split('\n')
.filter(Boolean);
// B.4 — arbitrarios permitidos tras el refactor.
const ARBITRARY_WHITELIST = [
/^text-\[clamp\([^)]+\)\]$/, // tipografía fluida (login, Logo)
/^leading-\[[\d.]+\]$/, // leading ajustado del display gigante de login
@@ -33,13 +15,9 @@ const ARBITRARY_WHITELIST = [
/^my-\[\d+d?vh\]$/, // +error.svelte: centrado vertical de página de error
/^py-\[\d+d?vh\]$/, // Explorar: centrado vertical de "sin resultados"
/^transition-\[filter\]$/, // Explorar: genre-tile hover
/^bg-\[image:var\(--mf-[\w-]+\)\]$/ // gradientes dinámicos por tema (Artwork, Logo, liked)
/^bg-\[image:var\(--mf-[\w-]+\)\]$/
];
// Radios semánticos de B.1.1 — cualquier otro rounded-* de Tailwind (o el
// `rounded` a secas de fábrica) es una regresión. `rounded-full` y los
// tokens (`rounded-tag/thumb/control/art/art-lg/panel/panel-lg`) están bien:
// el lookahead exige que no venga más texto de clase pegado con `-`.
const RAW_ROUNDED = /\brounded(-(none|xs|sm|md|lg|xl|2xl|3xl))?(?![\w-])/g;
const PAIRED_HW = /\b(?:([a-z0-9-]+:))?h-([\d.]+)\s+\1w-\2\b/g;
+239 -242
View File
File diff suppressed because it is too large Load Diff
@@ -109,7 +109,7 @@
<div class="mt-1 flex flex-col gap-0.5">
{#each tracks as track, i (track.id)}
{@const active = player.current.id === track.id}
<!-- svelte-ignore a11y_no_static_element_interactions -->
<div
class="group grid track-grid items-center gap-3 rounded-control py-3 pr-4 pl-2 transition-colors sm:gap-8 sm:pr-6 sm:pl-3 {active
? 'bg-accent-tint'
@@ -132,7 +132,7 @@
{/if}
</button>
{/if}
<!-- svelte-ignore a11y_click_events_have_key_events -->
<div
role="button"
tabindex="0"
-2
View File
@@ -1,5 +1,3 @@
// No hay sistema de tags/géneros todavía: esta lista es un placeholder de
// cliente y cada tile enlaza a una búsqueda normal por ese término.
export const GENRE_INFO: Record<string, { label: string; tagline: string }> = {
pop: { label: 'Pop', tagline: 'Éxitos que suenan en todas partes' },
rock: { label: 'Rock', tagline: 'Guitarras, actitud y ruido' },
-4
View File
@@ -1,9 +1,5 @@
import { player, toQueueItems, type ApiTrackLike, type QueueItem } from '$lib/player/player.svelte';
/**
* Merges the in-memory session history (tracks played since the page loaded)
* with the server-side listening history, de-duplicated by id and capped at `limit`.
*/
export function mergeRecentlyPlayed(history: ApiTrackLike[], limit: number): QueueItem[] {
const seen = new Set<string>();
const merged: QueueItem[] = [];
-4
View File
@@ -88,10 +88,6 @@ export interface Birthday {
day: number;
}
/**
* `birthday` is optional because the user's date of birth isn't part of the
* session/profile data yet. Wire it up here once that field exists upstream.
*/
export function pickGreeting(date: Date, birthday?: Birthday | null): string {
const month = date.getMonth() + 1;
const day = date.getDate();
@@ -15,8 +15,6 @@ export async function getAllowAnonymousListening(fetchFn: typeof fetch): Promise
cached = { allowAnonymousListening, expiresAt: Date.now() + CACHE_TTL_MS };
return allowAnonymousListening;
} catch {
// The API being unreachable shouldn't take down every page in the app;
// fail closed (as if anonymous listening were off) and retry next time.
return false;
}
}
-12
View File
@@ -1,10 +1,4 @@
:root {
/* Hue-based tokens (--mf-accent*, --mf-bg/elevated/panel-bg/bar-bg/hairline,
--mf-ambient, --mf-hero-bg/spotlight-bg/modal-glow, --mf-logo-grad,
--mf-cover-grad) are NOT defined here: they come only from
buildThemeTokens() in theme/tokens.ts, inlined as SSR <style> by
+layout.svelte and reapplied on every hue change. A duplicate default
here could never be overridden by a light-mode selector (see A.2). */
--mf-liked-grad: linear-gradient(150deg, oklch(0.4 0.09 330), oklch(0.18 0.04 10));
--mf-accent-dim: color-mix(in oklch, var(--mf-accent) 22%, transparent);
--mf-tile-l: 0.34;
@@ -12,7 +6,6 @@
--mf-tile-shade-l: 0.14;
--mf-tile-shade-c: 0.035;
/* Fixed neutrals: deliberately hue-less, so only the accent carries color. */
--mf-text: #d9d8dc;
--mf-text-2: #8a8a8e;
--mf-text-3: #7d7d81;
@@ -62,14 +55,12 @@
--z-grain: 80;
}
/* PlayerBar switches from its compact row to the full layout at `sm` (640px). */
@media (width >= 40rem) {
:root {
--mf-player-h: 100px;
}
}
/* TabsBar (mobile/tablet nav) is replaced by the Sidebar at `lg` (1024px). */
@media (width >= 64rem) {
:root {
--mf-nav-h: 0px;
@@ -82,9 +73,6 @@
}
}
/* "Modo blanco" — flips the neutral canvas/surface/text tokens to a light
palette. Components that reference these tokens re-theme correctly;
components hardcoding literal dark-mode hex colors do not. */
:root[data-theme='light'] {
--mf-text: #17171a;
--mf-text-2: #4a4a4e;
-18
View File
@@ -13,10 +13,6 @@ function tc(alpha: number, l: number, hue: number): string {
return `oklch(${r(lightness)} ${r(chroma)} ${r(hue, 1)} / ${alpha})`;
}
// Light-mode counterpart of tc(): fades toward a soft tinted glass (~0.88
// lightness) instead of toward black, so the "glow" gradients read as a
// visible colored tint instead of a dark smudge — or, at the old lightness
// floor of 0.97, an almost invisible wash next to the near-white canvas.
function tcLight(alpha: number, l: number, hue: number): string {
const depth = (88 - l) / 58;
const lightness = 0.88 - 0.16 * depth;
@@ -28,15 +24,6 @@ export interface ThemeTokens {
[cssVar: string]: string;
}
/**
* Every color in the app derives from the hue of the track in playback.
* See design_handoff_musify_player/README.md § "Sistema de color dinámico".
*
* `mode` only affects the neutral canvas tokens (bg/elevated/panel/hairline):
* these are re-applied as inline styles on every hue change, so a light-mode
* override in theme.css alone can never win against them — the light values
* have to come from here instead.
*/
export function buildThemeTokens(hue: number, mode: 'dark' | 'light' = 'dark'): ThemeTokens {
const h = ((hue % 360) + 360) % 360;
const h2 = (h + 40) % 360;
@@ -44,11 +31,6 @@ export function buildThemeTokens(hue: number, mode: 'dark' | 'light' = 'dark'):
const H2 = r(h2, 1);
const light = mode === 'light';
// Dark mode wants a bright, light accent (pops on a near-black canvas).
// Light mode needs the opposite: the same hue pulled down to a dark,
// saturated shade so it still reads against a near-white canvas — using
// the dark-mode lightness here is what made accent text/icons/buttons
// nearly invisible in light mode.
const accentL = light ? 0.52 : L;
const accentC = light ? 0.16 : C;
const titleL = light ? 0.4 : 0.87;
@@ -11,8 +11,6 @@ export const load: PageServerLoad = async ({ url, locals, fetch }) => {
const query = url.searchParams.get('q')?.trim() ?? '';
const page = Math.max(1, Number(url.searchParams.get('page')) || 1);
// This page is reachable without a session when anonymous listening is on
// (see +layout.server.ts), so `user` may be null here.
const user = locals.user;
const api = createApiClient({ fetch, accessToken: locals.accessToken ?? undefined });
@@ -273,7 +273,6 @@
<PlayButton as="span" size="lg" label="Reproducir" class="group-hover/top:brightness-110" />
{/snippet}
<!-- svelte-ignore a11y_no_static_element_interactions -->
<svelte:element
this={topResult.kind === 'track' ? 'button' : 'a'}
type={topResult.kind === 'track' ? 'button' : undefined}
@@ -308,7 +307,6 @@
{/if}
{#if !data.query}
<!-- GÉNEROS -->
<div class="grid-wide">
{#each genreTiles as genre, i (genre.query)}
<a
-1
View File
@@ -23,7 +23,6 @@ async function fetchSidebarPlaylists(
});
return data?.items ?? [];
} catch {
// The sidebar shell must render even when the API is unreachable.
return [];
}
}
-1
View File
@@ -11,7 +11,6 @@ import {
import { pickGreeting } from '$lib/server/greeting';
export const load: PageServerLoad = async ({ locals, url, fetch }) => {
// This dashboard is personal; an anonymous listener goes to /explore instead.
if (!locals.user) redirect(302, '/explore');
const user = requireUser(locals, url);
const api = createApiClient({ fetch, accessToken: locals.accessToken ?? undefined });
-5
View File
@@ -182,7 +182,6 @@
</div>
<div class="mt-10 flex flex-col gap-section">
<!-- CONTINUAR ESCUCHANDO -->
<section>
<SectionHeading title="Continuar escuchando" subtitle="Retomalo donde lo dejaste" />
{#if continueItems.length > 0}
@@ -209,7 +208,6 @@
{/if}
</section>
<!-- PLAYLIST DESTACADA -->
{#if spotlight}
<section>
<div
@@ -274,7 +272,6 @@
</section>
{/if}
<!-- MIXES -->
<section>
<SectionHeading title="Mixes" subtitle="Generados a partir de lo que más repites" />
{#if mixes.length > 0}
@@ -299,7 +296,6 @@
{/if}
</section>
<!-- POPULARES ESTA SEMANA -->
<section>
<SectionHeading title="Populares esta semana" subtitle="Lo más escuchado de tu biblioteca" />
{#if popularTracks.length > 0}
@@ -339,7 +335,6 @@
{/if}
</section>
<!-- TUS PLAYLISTS -->
<section>
<SectionHeading
title="Tus playlists"
@@ -3,8 +3,6 @@ import { json } from '@sveltejs/kit';
import { createApiClient, unwrapOrError } from '$lib/server/api';
export const GET: RequestHandler = async ({ params, locals, fetch }) => {
// No hard login gate here: the API itself allows an anonymous request when
// AllowAnonymousListening is on, and rejects it with 401 otherwise.
const api = createApiClient({ fetch, accessToken: locals.accessToken ?? undefined });
const result = await api.GET('/tracks/{id}/stream', {
params: { path: { id: params.id } }