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}