chore: update Angular cache and TypeScript build info files

This commit is contained in:
2025-09-22 09:34:22 -04:00
parent 08fd0682a4
commit 4eb339eb22
34 changed files with 1511 additions and 154 deletions
+4 -108
View File
@@ -14,114 +14,10 @@
</a>
</div>
<!-- Center: search (grid-centered, avoids overlap) -->
<form class="justify-self-center mx-auto w-full max-w-2xl md:max-w-3xl lg:max-w-4xl px-4 relative group" (submit)="onSubmitSearch($event, searchInput)">
<input #searchInput type="search" [placeholder]="('search.placeholder' | t)" aria-label="Search"
(focus)="onSearchFocus()" (input)="onSearchInput(searchInput)" (blur)="onSearchBlur()" (keydown)="onSearchKeydown($event, searchInput)"
(search)="onSearchCleared(searchInput)"
[ngClass]="{
'bg-white text-slate-900 placeholder-slate-500 ring-slate-300 hover:bg-slate-50': isLightTheme(),
'bg-slate-700/80 text-slate-200 placeholder-slate-400 ring-slate-600/50 hover:bg-slate-700/70': isDarkTheme(),
'bg-black text-slate-200 placeholder-slate-400 ring-slate-800/50 hover:bg-slate-900': isBlackTheme(),
'bg-blue-950/80 text-blue-100 placeholder-blue-300 ring-blue-900/60 hover:bg-blue-900/70': isBlueTheme()
}"
class="w-full rounded-lg py-2.5 px-4 pl-10 pr-16 focus:outline-none ring-1 focus:ring-2 focus:ring-red-500/70 transition-all duration-200 shadow-sm">
<svg class="w-5 h-5 absolute left-6 md:left-5 top-1/2 -translate-y-1/2"
[ngClass]="{
'text-slate-500': isLightTheme(),
'text-slate-400': isDarkTheme(),
'text-slate-300': isBlackTheme(),
'text-blue-200': isBlueTheme()
}"
xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke="currentColor">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M21 21l-6-6m2-5a7 7 0 11-14 0 7 7 0 0114 0z" />
</svg>
<!-- Keyboard shortcut hint (only when no provider indicator) -->
<div *ngIf="!providerContextLabel()" class="absolute right-6 top-1/2 -translate-y-1/2 hidden md:flex items-center gap-1 text-xs select-none"
[ngClass]="{
'text-slate-700/80': isLightTheme(),
'text-slate-300/80': isDarkTheme() || isBlackTheme(),
'text-blue-200/80': isBlueTheme()
}">
<kbd [ngClass]="{
'bg-slate-200/80 border-slate-300 text-slate-700': isLightTheme(),
'bg-slate-700/80 border-slate-600/60': isDarkTheme(),
'bg-slate-900/80 border-slate-800/60 text-slate-300': isBlackTheme(),
'bg-blue-800/80 border-blue-700/60 text-blue-200': isBlueTheme()
}" class="px-1.5 py-0.5 rounded border">Ctrl</kbd>
<span>+</span>
<kbd [ngClass]="{
'bg-slate-200/80 border-slate-300 text-slate-700': isLightTheme(),
'bg-slate-700/80 border-slate-600/60 text-slate-300': isDarkTheme(),
'bg-slate-900/80 border-slate-800/60 text-slate-300': isBlackTheme(),
'bg-blue-800/80 border-blue-700/60 text-blue-200': isBlueTheme()
}" class="px-1.5 py-0.5 rounded border">K</kbd>
</div>
<!-- Suggestions dropdown -->
@if (suggestionsOpen() && suggestionItems().length > 0) {
<div class="absolute z-50 mt-2 left-1/2 -translate-x-1/2 w-full max-w-2xl md:max-w-3xl lg:max-w-4xl rounded-xl shadow-2xl overflow-hidden"
[ngClass]="{
'bg-white border border-slate-200 text-slate-900': isLightTheme(),
'bg-slate-800/95 border border-slate-700 text-slate-200': isDarkTheme(),
'bg-black/95 border border-slate-900 text-slate-200': isBlackTheme(),
'bg-blue-950/90 border border-blue-800 text-blue-100': isBlueTheme(),
'backdrop-blur-md': !isLightTheme()
}">
<ul class="max-h-[70vh] overflow-y-auto py-1">
@for (item of suggestionItems(); track $index; let i = $index) {
<!-- Divider before first generated suggestion -->
@if (isFirstGenerated(i)) {
<li class="px-4 py-2 text-xs uppercase tracking-wide border-t border-b"
[ngClass]="{
'text-slate-500 border-slate-100': isLightTheme(),
'text-slate-400 border-slate-700': isDarkTheme(),
'text-slate-400 border-slate-800': isBlackTheme(),
'text-blue-300 border-blue-800': isBlueTheme()
}">Suggestions</li>
}
<li (mouseenter)="highlightedIndex.set(i)">
<button type="button" (mousedown)="pickSuggestion(item.text, searchInput)"
class="w-full text-left px-4 py-2 flex items-center gap-3 transition-colors duration-150"
[ngClass]="{
'hover:bg-slate-100': isLightTheme(),
'hover:bg-slate-700/70': isDarkTheme(),
'hover:bg-slate-900': isBlackTheme(),
'hover:bg-blue-800/60': isBlueTheme(),
'bg-slate-200': isLightTheme() && highlightedIndex() === i,
'bg-slate-700/50': isDarkTheme() && highlightedIndex() === i,
'bg-slate-900/70': isBlackTheme() && highlightedIndex() === i,
'bg-blue-800/50': isBlueTheme() && highlightedIndex() === i,
'text-slate-900': isLightTheme(),
'text-slate-200': isDarkTheme() || isBlackTheme(),
'text-blue-100': isBlueTheme()
}">
<!-- Clock for history, magnifier for generated -->
<svg *ngIf="item.source === 'history'" xmlns="http://www.w3.org/2000/svg" class="h-5 w-5"
[ngClass]="{
'text-slate-500': isLightTheme(),
'text-slate-400': isDarkTheme(),
'text-slate-300': isBlackTheme(),
'text-blue-200': isBlueTheme()
}" fill="none" viewBox="0 0 24 24" stroke="currentColor">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 8v4l3 3m6-3a9 9 0 11-18 0 9 9 0 0118 0z" />
</svg>
<svg *ngIf="item.source === 'generated'" xmlns="http://www.w3.org/2000/svg" class="h-5 w-5"
[ngClass]="{
'text-slate-500': isLightTheme(),
'text-slate-400': isDarkTheme(),
'text-slate-300': isBlackTheme(),
'text-blue-200': isBlueTheme()
}" fill="none" viewBox="0 0 24 24" stroke="currentColor">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M21 21l-6-6m2-5a7 7 0 11-14 0 7 7 0 0114 0z" />
</svg>
<span class="truncate">{{ item.text }}</span>
</button>
</li>
}
</ul>
</div>
}
</form>
<!-- Center: search box with providers -->
<div class="justify-self-center mx-auto w-full max-w-2xl md:max-w-3xl lg:max-w-4xl px-4 relative">
<app-search-box [placeholder]="('search.placeholder' | t)" (submitted)="onSearchBoxSubmit($event)"></app-search-box>
</div>
<!-- Right: user -->
<div class="justify-self-end flex items-center gap-3 pr-3 md:pr-4">
+22 -2
View File
@@ -10,6 +10,7 @@ import { TranslatePipe } from '../../pipes/translate.pipe';
import { I18nService } from '../../services/i18n.service';
import { ThemesService } from '../../services/themes.service';
import { HistoryService, SearchHistoryItem } from '../../services/history.service';
import { SearchBoxComponent } from '../search/search-box.component';
@Component({
selector: 'app-header',
@@ -20,7 +21,9 @@ import { HistoryService, SearchHistoryItem } from '../../services/history.servic
RouterLink,
CommonModule,
FormsModule,
TranslatePipe
TranslatePipe,
// New unified search box with provider chips and picker
SearchBoxComponent
]
})
export class HeaderComponent {
@@ -60,7 +63,7 @@ export class HeaderComponent {
const lower = q.toLowerCase();
historyList = fromHistory.filter(txt => txt.toLowerCase().includes(lower)).slice(0, 15);
}
const items: Item[] = historyList.map(text => ({ text, source: 'history' }));
// 2) If we have fewer than 15, fill with generated suggestions
@@ -85,6 +88,23 @@ export class HeaderComponent {
return items;
});
// New SearchBox submit handler (navigate with providers list)
onSearchBoxSubmit(evt: { q: string; providers: ("yt"|"dm"|"tw"|"pt"|"od"|"ru")[] | 'all' }) {
const q = (evt?.q || '').trim();
if (!q) return;
const provider = this.selectedProvider();
const theme = this.themes.activeSlug();
const qp: any = { q, provider };
if (Array.isArray(evt.providers)) {
qp.providers = evt.providers.join(',');
} else if (evt.providers === 'all') {
// Explicitly include all providers so SearchComponent uses unified multi-provider mode
qp.providers = 'yt,dm,tw,pt,od,ru';
}
if (theme) qp.theme = theme;
this.router.navigate(['/search'], { queryParams: qp });
}
// Generate query suggestions based on the current text and provider
private generateQuerySuggestions(q: string, provider: string | null): string[] {
const base = (q || '').trim();