v0.10.0 0f4e9eb

messaging.ts RawHistoryFolder

1/**
2 * Omnibox Message Bridge
3 *
4 * TypeScript interface for Go-JavaScript communication
5 */
6
7import type { OmniboxMessage, OmniboxMessageBridge, Suggestion } from "./types";
8import { omniboxStore } from "./stores.svelte.ts";
9
10export class OmniboxBridge implements OmniboxMessageBridge {
11  // Forward messages to the native WebKit message handler when available
12  // Fallback: for navigate, perform direct location change
13  postMessage(msg: OmniboxMessage): void {
14    console.log("📤 [DEBUG] Posting message to backend:", msg);
15    // NOTE: Do NOT detach postMessage from its receiver. In WKWebView,
16    // postMessage must be called on the UserMessageHandler instance.
17    const bridge = window.webkit?.messageHandlers?.dumber;
18    if (bridge && typeof bridge.postMessage === "function") {
19      try {
20        console.log("📱 [DEBUG] Using webkit message handler");
21        bridge.postMessage(JSON.stringify(msg));
22        return;
23      } catch (e) {
24        console.warn(
25          "postMessage to native handler failed, using fallback:",
26          e,
27        );
28      }
29    }
30    console.log("⚠️ [DEBUG] No webkit bridge available");
31    // Fallback navigation if no native bridge is available
32    if (msg.type === "navigate" && typeof msg.url === "string" && msg.url) {
33      try {
34        window.location.href = msg.url;
35      } catch (e) {
36        console.error("Fallback navigation failed:", e);
37      }
38    }
39  }
40
41  /**
42   * Update suggestions from Go backend
43   */
44  setSuggestions(suggestions: Suggestion[]): void {
45    console.log("📝 [DEBUG] Received suggestions from backend:", suggestions);
46    omniboxStore.updateSuggestions(suggestions);
47  }
48
49  /**
50   * Handle navigation request
51   */
52  navigate(url: string): void {
53    console.log("🚀 Omnibox navigate called with:", url);
54    this.postMessage({ type: "navigate", url });
55  }
56
57  /**
58   * Handle search query
59   */
60  query(searchTerm: string, limit?: number): void {
61    const q = searchTerm ?? "";
62    const lim = limit || omniboxStore.config.defaultLimit;
63    console.log("🔍 [DEBUG] Sending query to backend:", { q, limit: lim });
64    // Send to native handler; Go will compute suggestions and call setSuggestions
65    this.postMessage({ type: "query", q, limit: lim });
66  }
67
68  // Suggestions are returned via setSuggestions() when native handler responds
69}
70
71// Singleton instance
72export const omniboxBridge = new OmniboxBridge();
73
74/**
75 * Debounced query function for search input
76 */
77export function debouncedQuery(searchTerm: string): void {
78  omniboxStore.clearDebounceTimer();
79
80  const timerId = window.setTimeout(() => {
81    omniboxBridge.query(searchTerm);
82  }, omniboxStore.config.debounceDelay);
83
84  omniboxStore.setDebounceTimer(timerId);
85}
86
87// Extend global window interface for Go bridge compatibility
88declare global {
89  interface Window {
90    webkit?: {
91      messageHandlers?: {
92        dumber?: {
93          postMessage: (message: string) => void;
94        };
95      };
96    };
97    // Omnibox API for Go bridge
98    __dumber_omnibox?: {
99      setSuggestions: (suggestions: Suggestion[]) => void;
100      toggle: () => void;
101      open: (mode?: string, query?: string) => void;
102      close: () => void;
103      findQuery: (query: string) => void;
104      setActive: (active: boolean) => void;
105    };
106  }
107}

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