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}