v0.20.1 d9a391f

types.ts RawHistoryFolder

1// ═══════════════════════════════════════════════════════════════════════════════
2// Homepage TypeScript Types
3// Mirrors Go models from internal/db/models.go and related query files
4// ═══════════════════════════════════════════════════════════════════════════════
5
6// ─────────────────────────────────────────────────────────────────────────────
7// History Types
8// ─────────────────────────────────────────────────────────────────────────────
9
10export interface HistoryEntry {
11  id: number;
12  url: string;
13  title: string | null;
14  favicon_url: string | null;
15  visit_count: number;
16  last_visited: string;
17  created_at: string;
18}
19
20export interface TimelineGroup {
21  date: string; // YYYY-MM-DD
22  label: string; // "Today", "Yesterday", "Dec 5", etc.
23  entries: HistoryEntry[];
24}
25
26export interface HistoryStats {
27  total_entries: number;
28  total_visits: number;
29  unique_days: number;
30}
31
32export interface DomainStat {
33  domain: string;
34  page_count: number;
35  total_visits: number;
36  last_visit: string;
37}
38
39export interface DailyVisitCount {
40  day: string;
41  entries: number;
42  visits: number;
43}
44
45export interface HourlyDistribution {
46  hour: number;
47  visit_count: number;
48}
49
50// ─────────────────────────────────────────────────────────────────────────────
51// Favorites Types
52// ─────────────────────────────────────────────────────────────────────────────
53
54export interface Favorite {
55  id: number;
56  url: string;
57  title: string | null;
58  favicon_url: string | null;
59  position: number;
60  created_at: string;
61  updated_at: string;
62  folder_id: number | null;
63  shortcut_key: number | null; // 1-9
64  tags?: Tag[]; // Populated via join
65}
66
67export interface Folder {
68  id: number;
69  name: string;
70  icon: string | null;
71  position: number;
72  created_at: string;
73}
74
75export interface Tag {
76  id: number;
77  name: string;
78  color: string; // Hex color like #6b7280
79  created_at: string;
80}
81
82export interface TagAssignment {
83  favorite_id: number;
84  tag_id: number;
85}
86
87// ─────────────────────────────────────────────────────────────────────────────
88// Analytics Types
89// ─────────────────────────────────────────────────────────────────────────────
90
91// Matches Go HistoryAnalytics struct (flat structure)
92export interface Analytics {
93  total_entries: number;
94  total_visits: number;
95  unique_days: number;
96  top_domains: DomainStat[];
97  daily_visits: DailyVisitCount[];
98  hourly_distribution: HourlyDistribution[];
99}
100
101// ─────────────────────────────────────────────────────────────────────────────
102// UI State Types
103// ─────────────────────────────────────────────────────────────────────────────
104
105export type PanelType = 'history' | 'favorites' | 'analytics';
106
107export type HistoryCleanupRange = 'hour' | 'day' | 'week' | 'month' | 'all';
108
109export interface CommandPaletteItem {
110  id: string;
111  label: string;
112  description?: string;
113  icon?: import('svelte').Component | string;
114  action: () => void;
115  shortcut?: string;
116}
117
118export interface KeyboardShortcut {
119  key: string;
120  description: string;
121  action: () => void;
122  context?: 'global' | 'history' | 'favorites' | 'command-palette';
123}
124
125// ─────────────────────────────────────────────────────────────────────────────
126// Message Types (WebKit Bridge)
127// ─────────────────────────────────────────────────────────────────────────────
128
129export type MessageType =
130  // Folders
131  | 'folder_list'
132  | 'folder_create'
133  | 'folder_update'
134  | 'folder_delete'
135  // Tags
136  | 'tag_list'
137  | 'tag_create'
138  | 'tag_update'
139  | 'tag_delete'
140  | 'tag_assign'
141  | 'tag_remove'
142  // History
143  | 'history_timeline'
144  | 'history_search_fts'
145  | 'history_analytics'
146  | 'history_domain_stats'
147  | 'history_delete_entry'
148  | 'history_delete_range'
149  | 'history_clear_all'
150  | 'history_delete_domain'
151  // Favorites
152  | 'favorite_list'
153  | 'favorite_set_shortcut'
154  | 'favorite_get_by_shortcut'
155  | 'favorite_set_folder';
156
157export interface Message<T = unknown> {
158  type: MessageType;
159  requestId?: string;
160  payload?: T;
161}
162
163export interface MessageResponse<T = unknown> {
164  success: boolean;
165  data?: T;
166  error?: string;
167}
168
169// ─────────────────────────────────────────────────────────────────────────────
170// Request/Response Payloads
171// ─────────────────────────────────────────────────────────────────────────────
172
173// History
174export interface HistoryTimelineRequest {
175  limit?: number;
176  offset?: number;
177}
178
179export interface HistorySearchRequest {
180  query: string;
181  limit?: number;
182}
183
184export interface HistoryDeleteRangeRequest {
185  range: HistoryCleanupRange;
186}
187
188export interface HistoryDeleteDomainRequest {
189  domain: string;
190}
191
192// Folders
193export interface FolderCreateRequest {
194  name: string;
195  icon?: string;
196}
197
198export interface FolderUpdateRequest {
199  id: number;
200  name: string;
201  icon?: string;
202}
203
204// Tags
205export interface TagCreateRequest {
206  name: string;
207  color?: string;
208}
209
210export interface TagUpdateRequest {
211  id: number;
212  name?: string;
213  color?: string;
214}
215
216export interface TagAssignRequest {
217  favorite_id: number;
218  tag_id: number;
219}
220
221// Favorites
222export interface FavoriteShortcutRequest {
223  favorite_id: number;
224  shortcut_key: number; // 1-9
225}
226
227export interface FavoriteFolderRequest {
228  favorite_id: number;
229  folder_id: number | null;
230}

Keyboard shortcuts

Single-key shortcuts are on. ctrl k and esc work whatever this says.

ctrl k :
go to a section, branch, tag, file or repository
?
this list
j k
move the row cursor down / up
enter
open the row under the cursor; on Files, a directory opens or closes in place
↑ ↓ ← → home end
in the file tree (focus on a row): previous / next row, close / open a directory or go to its parent / first entry, first / last row. They never open a file
l h
on Files: open a directory or a file / close a directory or go up to its parent, then to the parent page. Elsewhere: into the side panel (on a merge request, its files) / back to the content; there j k move between its controls
g g G
first / last row
/
filter the list; on Files, find a file anywhere in the repository (esc clears, enter opens the best match)
b
switch branch or tag
g s g f g c g b g m g i g r g a
tabs: summary, files, commits, branches & tags, merge requests, issues, releases, actions (when available)
g h
home
w
wide mode: use the whole width of the screen, or not (remembered)
y
copy a permalink pinned to the commit
d u x
diff: split / unified / collapse or expand all
e E
diff: the whole file in view / every file, with the lines the hunks hide
n
merge request: next note in the diff
esc
close a dialog, leave a field

Branches 8

Tags 42

↑↓ moveenter openesc close