1type HistoryEntry = {
2 id: number;
3 url: string;
4 title: string;
5 visit_count: number;
6 last_visited: string | null;
7 created_at: string | null;
8}
9
10export class AppService {
11 private history: HistoryEntry[] = [];
12 private shortcuts: Record<string, any> = {};
13
14 constructor() {}
15
16 async initialize(): Promise<void> {
17 try {
18 await Promise.all([
19 this.loadHistory(),
20 this.loadShortcuts()
21 ]);
22 } catch (error) {
23 console.error('Failed to initialize app:', error);
24 }
25 }
26
27 async loadHistory(): Promise<void> {
28 try {
29 const recentHistory: HistoryEntry[] = await fetch('/api/history/recent?limit=50').then(r => r.json());
30 this.history = recentHistory;
31 } catch (error) {
32 console.error('Failed to load history:', error);
33 // Mock history for development/fallback
34 this.history = [
35 {
36 id: 1,
37 url: 'https://github.com/wailsapp/wails',
38 title: 'Wails Framework',
39 visit_count: 3,
40 last_visited: new Date().toISOString(),
41 created_at: new Date().toISOString()
42 },
43 {
44 id: 2,
45 url: 'https://go.dev',
46 title: 'The Go Programming Language',
47 visit_count: 2,
48 last_visited: new Date().toISOString(),
49 created_at: new Date().toISOString()
50 },
51 {
52 id: 3,
53 url: 'https://developer.mozilla.org',
54 title: 'MDN Web Docs',
55 visit_count: 1,
56 last_visited: new Date().toISOString(),
57 created_at: new Date().toISOString()
58 }
59 ];
60 }
61 }
62
63 async loadShortcuts(): Promise<void> {
64 try {
65 const cfg = await fetch('/api/config').then(r => r.json());
66 const raw = cfg?.search_shortcuts || {};
67 // Normalize field casing from backend (supports URL/Description and url/description)
68 const normalized: Record<string, { description: string; url: string }> = {};
69 for (const [key, value] of Object.entries(raw)) {
70 const v: any = value as any;
71 normalized[key] = {
72 description: v.description ?? v.Description ?? '',
73 url: v.url ?? v.URL ?? ''
74 };
75 }
76 this.shortcuts = normalized;
77 } catch (error) {
78 console.error('Failed to load shortcuts:', error);
79 // Mock shortcuts for development/fallback
80 this.shortcuts = {
81 'g': { description: 'Google Search', url: 'https://google.com/search?q={query}' },
82 'gh': { description: 'GitHub Search', url: 'https://github.com/search?q={query}' },
83 'so': { description: 'Stack Overflow', url: 'https://stackoverflow.com/search?q={query}' },
84 'w': { description: 'Wikipedia', url: 'https://en.wikipedia.org/wiki/Special:Search?search={query}' }
85 };
86 }
87 }
88
89 getHistory(): HistoryEntry[] {
90 return this.history;
91 }
92
93 getShortcuts(): Record<string, any> {
94 return this.shortcuts;
95 }
96
97 async copyToClipboard(text: string): Promise<void> {
98 try {
99 await navigator.clipboard.writeText(text);
100 console.log('Copied to clipboard:', text);
101 } catch (err) {
102 console.error('Failed to copy:', err);
103 }
104 }
105}