v0.31.0 bf0756b

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

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