chore: update Angular cache and TypeScript build info files
This commit is contained in:
parent
3f04191623
commit
5d6aa17b81
2
.angular/cache/20.2.2/app/.tsbuildinfo
vendored
2
.angular/cache/20.2.2/app/.tsbuildinfo
vendored
File diff suppressed because one or more lines are too long
BIN
db/newtube.db
BIN
db/newtube.db
Binary file not shown.
@ -251,37 +251,40 @@ export class HeaderComponent {
|
||||
}
|
||||
|
||||
// Theme helpers for styling based on current theme
|
||||
private resolveThemeSlug(slug: string | null | undefined): 'light' | 'dark' | 'black' | 'blue' | 'system' {
|
||||
const v = (slug || 'system') as string;
|
||||
if (v === 'system') return (window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches) ? 'dark' : 'light';
|
||||
if (v === 'light' || v === 'dark' || v === 'black' || v === 'blue') return v;
|
||||
return 'light';
|
||||
}
|
||||
|
||||
getCurrentTheme(): string {
|
||||
return this.currentTheme() || 'system';
|
||||
}
|
||||
|
||||
isLightTheme(): boolean {
|
||||
const t = this.getCurrentTheme();
|
||||
return t === 'light' || t === 'system';
|
||||
return this.resolveThemeSlug(this.getCurrentTheme()) === 'light';
|
||||
}
|
||||
|
||||
isDarkTheme(): boolean {
|
||||
const t = this.getCurrentTheme();
|
||||
return t === 'dark';
|
||||
return this.resolveThemeSlug(this.getCurrentTheme()) === 'dark';
|
||||
}
|
||||
|
||||
isBlackTheme(): boolean {
|
||||
const t = this.getCurrentTheme();
|
||||
return t === 'black';
|
||||
return this.resolveThemeSlug(this.getCurrentTheme()) === 'black';
|
||||
}
|
||||
|
||||
isBlueTheme(): boolean {
|
||||
const t = this.getCurrentTheme();
|
||||
return t === 'blue';
|
||||
return this.resolveThemeSlug(this.getCurrentTheme()) === 'blue';
|
||||
}
|
||||
|
||||
getThemeClasses(): { [key: string]: boolean } {
|
||||
const theme = this.getCurrentTheme();
|
||||
const rt = this.resolveThemeSlug(this.getCurrentTheme());
|
||||
return {
|
||||
'theme-light': theme === 'light' || theme === 'system',
|
||||
'theme-dark': theme === 'dark',
|
||||
'theme-black': theme === 'black',
|
||||
'theme-blue': theme === 'blue'
|
||||
'theme-light': rt === 'light',
|
||||
'theme-dark': rt === 'dark',
|
||||
'theme-black': rt === 'black',
|
||||
'theme-blue': rt === 'blue'
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -1,16 +1,15 @@
|
||||
<nav class="sticky top-16 left-0 right-0 z-40 w-full relative"
|
||||
[ngClass]="{
|
||||
'bg-slate-100 border-b border-slate-200': isLightTheme(),
|
||||
'bg-slate-900 border-b border-slate-800': isDarkTheme(),
|
||||
'bg-black border-b border-slate-900': isBlackTheme(),
|
||||
'bg-blue-950 border-b border-blue-900': isBlueTheme()
|
||||
'bg-slate-800 border-b border-slate-700': isDarkTheme(),
|
||||
'bg-slate-900 border-b border-slate-800': isBlackTheme(),
|
||||
'bg-slate-700 border-b border-slate-600': isBlueTheme()
|
||||
}">
|
||||
<!-- Left scroll button -->
|
||||
<button type="button" (click)="scrollBy(-320)" aria-label="Scroll left"
|
||||
class="hidden md:flex items-center justify-center absolute left-2 top-1/2 -translate-y-1/2 h-9 w-9 rounded-full shadow z-10"
|
||||
[ngClass]="{
|
||||
'bg-white/90 border border-slate-300 text-slate-700 hover:bg-slate-100': isLightTheme(),
|
||||
'bg-slate-800/90 border border-slate-700 text-slate-200 hover:bg-slate-700': !isLightTheme()
|
||||
'bg-slate-800/90 border border-slate-700 text-slate-200 hover:bg-slate-700': isDarkTheme() || isBlackTheme() || isBlueTheme()
|
||||
}">
|
||||
«
|
||||
</button>
|
||||
@ -20,7 +19,7 @@
|
||||
class="hidden md:flex items-center justify-center absolute right-2 top-1/2 -translate-y-1/2 h-9 w-9 rounded-full shadow z-10"
|
||||
[ngClass]="{
|
||||
'bg-white/90 border border-slate-300 text-slate-700 hover:bg-slate-100': isLightTheme(),
|
||||
'bg-slate-800/90 border border-slate-700 text-slate-200 hover:bg-slate-700': !isLightTheme()
|
||||
'bg-slate-800/90 border border-slate-700 text-slate-200 hover:bg-slate-700': isDarkTheme() || isBlackTheme() || isBlueTheme()
|
||||
}">
|
||||
»
|
||||
</button>
|
||||
|
50
src/components/themes/themes-nav.component.html.bak
Normal file
50
src/components/themes/themes-nav.component.html.bak
Normal file
@ -0,0 +1,50 @@
|
||||
<nav class="sticky top-16 left-0 right-0 z-40 w-full relative"
|
||||
[ngClass]="{
|
||||
'bg-slate-800 border-b border-slate-700': isDarkTheme(),
|
||||
'bg-slate-900 border-b border-slate-800': isBlackTheme(),
|
||||
'bg-slate-700 border-b border-slate-600': isBlueTheme()
|
||||
}">
|
||||
<!-- Left scroll button -->
|
||||
<button type="button" (click)="scrollBy(-320)" aria-label="Scroll left"
|
||||
class="hidden md:flex items-center justify-center absolute left-2 top-1/2 -translate-y-1/2 h-9 w-9 rounded-full shadow z-10"
|
||||
[ngClass]="{
|
||||
'bg-white/90 border border-slate-300 text-slate-700 hover:bg-slate-100': isLightTheme(),
|
||||
'bg-slate-800/90 border border-slate-700 text-slate-200 hover:bg-slate-700': !isLightTheme()
|
||||
}">
|
||||
«
|
||||
</button>
|
||||
|
||||
<!-- Right scroll button -->
|
||||
<button type="button" (click)="scrollBy(320)" aria-label="Scroll right"
|
||||
class="hidden md:flex items-center justify-center absolute right-2 top-1/2 -translate-y-1/2 h-9 w-9 rounded-full shadow z-10"
|
||||
[ngClass]="{
|
||||
'bg-white/90 border border-slate-300 text-slate-700 hover:bg-slate-100': isLightTheme(),
|
||||
'bg-slate-800/90 border border-slate-700 text-slate-200 hover:bg-slate-700': !isLightTheme()
|
||||
}">
|
||||
»
|
||||
</button>
|
||||
|
||||
<div class="w-full overflow-x-auto no-scrollbar" #scroll (wheel)="onWheel($event)">
|
||||
<ul role="tablist" aria-label="Themes" class="flex gap-2 px-12 py-2 min-w-max items-center">
|
||||
<li *ngFor="let t of displayedThemes(); let i = index" class="shrink-0">
|
||||
<button
|
||||
#pill
|
||||
role="tab"
|
||||
type="button"
|
||||
class="px-3 py-1.5 rounded-full text-sm font-medium border transition-colors whitespace-nowrap focus:outline-none focus:ring-2 focus:ring-red-500"
|
||||
[class.bg-slate-100/10]="activeSlug() === t.slug"
|
||||
[class.text-white]="activeSlug() === t.slug"
|
||||
[class.border-red-500]="activeSlug() === t.slug"
|
||||
[class.text-slate-300]="activeSlug() !== t.slug"
|
||||
[class.border-slate-700]="activeSlug() !== t.slug"
|
||||
[attr.aria-selected]="activeSlug() === t.slug"
|
||||
(click)="goToTheme(t.slug)"
|
||||
(keydown)="onKeydown($event, i)"
|
||||
>
|
||||
<span class="mr-1 select-none">{{ t.emoji }}</span>
|
||||
<span>{{ themesSvc.i18nLabel(t) }}</span>
|
||||
</button>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</nav>
|
@ -1,4 +1,4 @@
|
||||
import { ChangeDetectionStrategy, Component, ElementRef, QueryList, ViewChild, ViewChildren, inject, signal, effect } from '@angular/core';
|
||||
import { ChangeDetectionStrategy, Component, ElementRef, QueryList, ViewChild, ViewChildren, inject, signal, effect, OnInit, OnDestroy } from '@angular/core';
|
||||
import { CommonModule } from '@angular/common';
|
||||
import { Router, NavigationEnd, ActivatedRoute } from '@angular/router';
|
||||
import { ThemesService } from '../../services/themes.service';
|
||||
@ -10,7 +10,7 @@ import { ThemesService } from '../../services/themes.service';
|
||||
imports: [CommonModule],
|
||||
templateUrl: './themes-nav.component.html'
|
||||
})
|
||||
export class ThemesNavComponent {
|
||||
export class ThemesNavComponent implements OnDestroy {
|
||||
private router = inject(Router);
|
||||
private route = inject(ActivatedRoute);
|
||||
themesSvc = inject(ThemesService);
|
||||
@ -22,6 +22,9 @@ export class ThemesNavComponent {
|
||||
@ViewChildren('pill', { read: ElementRef }) pills!: QueryList<ElementRef<HTMLButtonElement>>;
|
||||
@ViewChild('scroll', { static: false }) scrollRef?: ElementRef<HTMLDivElement>;
|
||||
|
||||
// Signal to force re-evaluation when data-theme changes
|
||||
private themeChanged = signal<number>(0);
|
||||
|
||||
constructor() {
|
||||
// Reflect current URL into active slug
|
||||
this.router.events.subscribe((e) => {
|
||||
@ -29,6 +32,17 @@ export class ThemesNavComponent {
|
||||
});
|
||||
// Also on init
|
||||
setTimeout(() => this.syncFromUrl(), 0);
|
||||
|
||||
// Effect to listen for theme changes on document.documentElement
|
||||
effect(() => {
|
||||
const currentTheme = document.documentElement.getAttribute('data-theme') || 'system';
|
||||
// Trigger re-evaluation when theme changes
|
||||
this.themeChanged.update(n => n + 1);
|
||||
});
|
||||
}
|
||||
|
||||
ngOnDestroy() {
|
||||
// Nothing to cleanup
|
||||
}
|
||||
|
||||
private syncFromUrl() {
|
||||
@ -75,30 +89,40 @@ export class ThemesNavComponent {
|
||||
}
|
||||
|
||||
// Theme helpers (read from document attribute/localStorage)
|
||||
private getCurrentTheme(): string {
|
||||
private getCurrentTheme(): 'light' | 'dark' | 'black' | 'blue' | 'system' {
|
||||
try {
|
||||
const fromAttr = document.documentElement.getAttribute('data-theme');
|
||||
if (fromAttr) return fromAttr;
|
||||
if (fromAttr) return fromAttr as any;
|
||||
const fromStorage = localStorage.getItem('newtube.theme');
|
||||
const val = fromStorage || 'system';
|
||||
if (val === 'system') {
|
||||
// Resolve to light/dark using media query so styles can be deterministic
|
||||
const prefersDark = window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches;
|
||||
return prefersDark ? 'dark' : 'light';
|
||||
}
|
||||
return val;
|
||||
return (fromStorage as any) || 'system';
|
||||
} catch {
|
||||
// Safe fallback: prefer dark for safety in most UIs
|
||||
const prefersDark = typeof window !== 'undefined' && (window.matchMedia?.('(prefers-color-scheme: dark)').matches ?? false);
|
||||
return prefersDark ? 'dark' : 'light';
|
||||
return 'system';
|
||||
}
|
||||
}
|
||||
|
||||
private resolveThemeSlug(): 'light' | 'dark' | 'black' | 'blue' {
|
||||
const cur = this.getCurrentTheme();
|
||||
if (cur === 'system') {
|
||||
const prefersDark = typeof window !== 'undefined' && window.matchMedia?.('(prefers-color-scheme: dark)').matches;
|
||||
return prefersDark ? 'dark' : 'light';
|
||||
}
|
||||
return cur as any;
|
||||
}
|
||||
|
||||
isLightTheme(): boolean {
|
||||
const t = this.getCurrentTheme();
|
||||
return t === 'light' || t === 'system';
|
||||
this.themeChanged(); // Trigger re-evaluation
|
||||
return this.resolveThemeSlug() === 'light';
|
||||
}
|
||||
isDarkTheme(): boolean {
|
||||
this.themeChanged(); // Trigger re-evaluation
|
||||
return this.resolveThemeSlug() === 'dark';
|
||||
}
|
||||
isBlackTheme(): boolean {
|
||||
this.themeChanged(); // Trigger re-evaluation
|
||||
return this.resolveThemeSlug() === 'black';
|
||||
}
|
||||
isBlueTheme(): boolean {
|
||||
this.themeChanged(); // Trigger re-evaluation
|
||||
return this.resolveThemeSlug() === 'blue';
|
||||
}
|
||||
isDarkTheme(): boolean { return this.getCurrentTheme() === 'dark'; }
|
||||
isBlackTheme(): boolean { return this.getCurrentTheme() === 'black'; }
|
||||
isBlueTheme(): boolean { return this.getCurrentTheme() === 'blue'; }
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user