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