deps.go RawHistoryFolder

1// Package ui provides the GTK4 presentation layer for the dumber browser.
2package ui
3
4import (
5	"context"
6
7	"github.com/bnema/dumber/internal/application/port"
8	"github.com/bnema/dumber/internal/application/usecase"
9	"github.com/bnema/dumber/internal/domain/entity"
10	"github.com/bnema/dumber/internal/domain/repository"
11	"github.com/bnema/dumber/internal/ui/adapter"
12	"github.com/bnema/dumber/internal/ui/theme"
13	"github.com/bnema/puregotk/v4/gtk"
14)
15
16// Dependencies holds all injected dependencies for the UI layer.
17// This struct is created once at startup and passed to UI components.
18type Dependencies struct {
19	// ApplicationID optionally distinguishes the GUI for the Wayland compositor.
20	ApplicationID string
21	// Core context and configuration
22	Ctx                    context.Context
23	RuntimeConfig          port.RuntimeConfigProvider
24	InitialURL             string // URL to open on startup (optional)
25	RestoreSessionID       string // Session ID to restore on startup (optional)
26	StartupCrashReports    []string
27	OnFirstWebViewShown    func(context.Context)
28	OnSessionPersisted     func() // Called by main after session is persisted to DB
29	OnCrashReportsDetected func([]string)
30
31	// Theme and color scheme management
32	Theme                *theme.Manager
33	ResolveThemeUC       *usecase.ResolveThemeUseCase
34	ExternalThemeSource  port.ConfigurableExternalThemeSource
35	ExternalThemeWatcher port.ExternalThemeWatcher
36	ColorResolver        port.ColorSchemeResolver
37	AdwaitaDetector      port.ToolkitAvailabilityNotifier
38
39	// XDG paths
40	XDG port.XDGPaths
41
42	// Engine (replaces individual webkit fields)
43	Engine port.Engine
44
45	// Handler dependencies built by bootstrap (keybindings, config save).
46	HandlerDeps port.HandlerDeps
47
48	// Repositories
49	HistoryRepo    repository.HistoryRepository
50	FavoriteRepo   repository.FavoriteRepository
51	ZoomRepo       repository.ZoomRepository
52	PermissionRepo port.PermissionRepository
53	FilterRepo     repository.ContentWhitelistRepository
54
55	// Use Cases
56	TabsUC            *usecase.ManageTabsUseCase
57	PanesUC           *usecase.ManagePanesUseCase
58	NavigateUC        *usecase.NavigateUseCase
59	HistoryRecorderUC *usecase.HistoryRecorderUseCase
60	ZoomUC            *usecase.ManageZoomUseCase
61	PermissionUC      *usecase.HandlePermissionUseCase
62	FavoritesUC       *usecase.ManageFavoritesUseCase
63	HistoryUC         *usecase.SearchHistoryUseCase
64	CopyURLUC         *usecase.CopyURLUseCase
65
66	// Infrastructure Adapters
67	Clipboard                 port.Clipboard
68	FaviconService            port.FaviconService
69	FaviconResolver           port.FaviconResolver
70	SystemviewFaviconResolver port.FaviconSystemviewResolver
71	FaviconAdapterConfig      adapter.FaviconAdapterConfig
72	FilterManager             port.FilterManager
73	IdleInhibitor             port.IdleInhibitor
74
75	// Accent picker for dead keys support
76	InsertAccentUC      *usecase.InsertAccentUseCase
77	AccentFocusProvider port.FocusedInputProvider
78	// NewGTKEntryTarget creates a port.TextInputTarget from a GTK SearchEntry.
79	// Injected to avoid importing infrastructure/textinput from the UI layer.
80	NewGTKEntryTarget func(entry *gtk.SearchEntry) port.TextInputTarget
81
82	// Session management
83	SessionStateRepo repository.SessionStateRepository
84	SessionRepo      repository.SessionRepository
85	CurrentSessionID entity.SessionID
86	SnapshotUC       *usecase.SnapshotSessionUseCase
87	// SnapshotServiceFactory creates a snapshot service bound to the given window state provider.
88	// Called after the App is initialized so the App can serve as the provider.
89	SnapshotServiceFactory func(provider port.WindowStateProvider, intervalMs int) port.SnapshotService
90	// SessionSpawner spawns a new dumber instance for session restoration.
91	SessionSpawner port.SessionSpawner
92	// FileSystem provides file operations (e.g., for download deduplication).
93	FileSystem port.FileSystem
94	// LocalPathResolver resolves user-entered local filesystem paths for navigation.
95	LocalPathResolver port.LocalPathResolver
96
97	// Update management
98	CheckUpdateUC *usecase.CheckUpdateUseCase
99	ApplyUpdateUC *usecase.ApplyUpdateUseCase
100
101	// Config migration checker (optional; nil disables migration notifications)
102	MigrationChecker port.ConfigMigrator
103
104	// LaunchExternalURL opens a URI with the system's default handler (e.g. xdg-open).
105	// Used for external URL schemes (vscode://, spotify://, etc.).
106	// Optional: if nil, external URLs are silently dropped.
107	LaunchExternalURL func(uri string)
108	// LaunchBrowserURL opens a URL in a new dumber browser window.
109	// Returns an error when the launcher is unavailable or the launch fails.
110	// Optional: if nil, standalone omnibox navigation returns a configuration error.
111	LaunchBrowserURL func(ctx context.Context, uri string) error
112	// BrowserLaunchRelay listens for in-process browser launch requests.
113	BrowserLaunchRelay port.BrowserLaunchRelay
114}
115
116// Validate checks that all required dependencies are set.
117func (d *Dependencies) Validate() error {
118	if d.Ctx == nil {
119		return ErrMissingDependency("Ctx")
120	}
121	if d.RuntimeConfig == nil {
122		return ErrMissingDependency("RuntimeConfig")
123	}
124	if d.Engine == nil {
125		return ErrMissingDependency("Engine")
126	}
127	if d.HandlerDeps.SaveConfig == nil {
128		return ErrMissingDependency("HandlerDeps.SaveConfig")
129	}
130	if d.HandlerDeps.SaveOmniboxInitialBehavior == nil {
131		return ErrMissingDependency("HandlerDeps.SaveOmniboxInitialBehavior")
132	}
133	// Use cases are optional - can be nil if not needed
134	return nil
135}
136
137// DependencyError indicates a missing required dependency.
138type DependencyError struct {
139	Name string
140}
141
142func (e DependencyError) Error() string {
143	return "missing required dependency: " + e.Name
144}
145
146// ErrMissingDependency creates a new DependencyError.
147func ErrMissingDependency(name string) error {
148	return DependencyError{Name: name}
149}

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