ObsiViewer/src/app/features/parameters/parameters.page.ts
Bruno Charest 59d8a9f83a feat: add multi-select notes and Gemini AI integration
- Implemented multi-selection for notes with Ctrl+click, long-press, and keyboard shortcuts (Ctrl+A, Escape)
- Added Gemini API integration with environment configuration and routes
- Enhanced code block UI with improved copy feedback animation and visual polish
- Added sort order toggle (asc/desc) for note lists with persistent state
2025-11-04 09:54:03 -05:00

157 lines
5.5 KiB
TypeScript

import { Component, inject, signal, effect } from '@angular/core';
import { CommonModule } from '@angular/common';
import { FormsModule } from '@angular/forms';
import { ThemeService, ThemeMode, ThemeId, Language } from '../../core/services/theme.service';
import { SettingsService } from '../../services/settings.service';
import { ToastService } from '../../shared/toast/toast.service';
import { FolderFilterService, FolderFilterConfig } from '../../services/folder-filter.service';
import { SettingsIntegrationsGeminiComponent } from '../settings/integrations/settings-integrations-gemini.component';
@Component({
standalone: true,
selector: 'app-parameters',
imports: [CommonModule, FormsModule, SettingsIntegrationsGeminiComponent],
templateUrl: './parameters.page.html',
styleUrls: ['./parameters.page.css']
})
export class ParametersPage {
private themeService = inject(ThemeService);
private toastService = inject(ToastService);
private folderFilterService = inject(FolderFilterService);
private settingsService = inject(SettingsService);
// Reactive prefs
prefs = signal(this.themeService.prefsValue);
folderFilterConfig = signal<FolderFilterConfig>(this.folderFilterService.getConfig());
newExcludedFolder = '';
backupsEnabled = signal<boolean>(true);
modes: ThemeMode[] = ['system', 'light', 'dark'];
themes: ThemeId[] = ['light', 'dark', 'obsidian', 'nord', 'notion', 'github', 'discord', 'monokai'];
languages: Language[] = ['fr', 'en'];
// Labels pour les thèmes
themeLabels: Record<ThemeId, string> = {
light: 'Pure White',
dark: 'Blue',
obsidian: 'Obsidian',
nord: 'Nord',
notion: 'Notion',
github: 'GitHub',
discord: 'Discord',
monokai: 'Monokai'
};
constructor() {
// S'abonner aux changements de préférences
effect(() => {
const subscription = this.themeService.onPrefs$.subscribe(prefs => {
this.prefs.set(prefs);
});
return () => subscription.unsubscribe();
});
effect(() => {
const sub = this.settingsService.getSettings().subscribe(({ enableBackups }) => {
this.backupsEnabled.set(!!enableBackups);
});
return () => sub.unsubscribe();
});
}
setMode(mode: ThemeMode): void {
this.themeService.setMode(mode);
this.showToast('Mode changed successfully');
}
setTheme(theme: ThemeId): void {
this.themeService.setTheme(theme);
this.showToast('Theme changed successfully');
}
setLanguage(language: Language): void {
this.themeService.setLanguage(language);
this.showToast('Language changed successfully');
}
private showToast(message: string): void {
this.toastService.success(message, 2000);
}
getThemePreview(themeId: ThemeId): string {
// Couleurs de preview pour chaque thème
const previews: Record<ThemeId, string> = {
light: 'linear-gradient(135deg, #ffffff 0%, #f7f7f7 100%)',
dark: 'linear-gradient(135deg, #0f172a 0%, #1e293b 100%)',
obsidian: 'linear-gradient(135deg, #fafaf8 0%, #a89984 100%)',
nord: 'linear-gradient(135deg, #2e3440 0%, #88c0d0 100%)',
notion: 'linear-gradient(135deg, #ffffff 0%, #f7f7f5 100%)',
github: 'linear-gradient(135deg, #ffffff 0%, #0969da 100%)',
discord: 'linear-gradient(135deg, #313338 0%, #5865f2 100%)',
monokai: 'linear-gradient(135deg, #272822 0%, #a6e22e 100%)'
};
return previews[themeId];
}
// Folder Filter Methods
toggleHiddenFolders(): void {
const config = this.folderFilterConfig();
this.folderFilterService.updateConfig({
...config,
excludeHiddenFolders: !config.excludeHiddenFolders
});
this.folderFilterConfig.set(this.folderFilterService.getConfig());
this.showToast('Hidden folders filter updated');
}
toggleAttachments(): void {
const config = this.folderFilterConfig();
this.folderFilterService.updateConfig({
...config,
excludeAttachments: !config.excludeAttachments
});
this.folderFilterConfig.set(this.folderFilterService.getConfig());
this.showToast('Attachments filter updated');
}
// Dynamic excluded folders list management
addExcludedFolder(): void {
const raw = (this.newExcludedFolder || '').trim();
if (!raw) return;
// Normalize path (remove leading/trailing slashes)
const normalized = raw.replace(/\\/g, '/').replace(/^\/+|\/+$/g, '');
if (!normalized) return;
this.folderFilterService.addCustomExclusion(normalized);
this.folderFilterConfig.set(this.folderFilterService.getConfig());
this.newExcludedFolder = '';
this.showToast('Folder added to exclusions');
}
removeExcludedFolder(path: string): void {
this.folderFilterService.removeCustomExclusion(path);
this.folderFilterConfig.set(this.folderFilterService.getConfig());
this.showToast('Folder removed from exclusions');
}
resetFolderFilters(): void {
this.folderFilterService.resetToDefaults();
this.folderFilterConfig.set(this.folderFilterService.getConfig());
this.showToast('Folder filters reset to defaults');
}
toggleBackups(): void {
const next = !this.backupsEnabled();
this.settingsService.updateBackups(next).subscribe((res) => {
this.backupsEnabled.set(res.enableBackups);
if (!res.enableBackups && (res.deletedBakFiles ?? 0) > 0) {
this.showToast(`Backups disabled. Deleted ${res.deletedBakFiles} .bak files`);
} else if (!res.enableBackups) {
this.showToast('Backups disabled');
} else {
this.showToast('Backups enabled');
}
});
}
}