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 // Repositories
42 HistoryRepo repository.HistoryRepository
43 FavoriteRepo repository.FavoriteRepository
44 ZoomRepo repository.ZoomRepository
45 PermissionRepo port.PermissionRepository
46 FilterRepo repository.ContentWhitelistRepository
47
48 // Use Cases
49 TabsUC *usecase.ManageTabsUseCase
50 PanesUC *usecase.ManagePanesUseCase
51 NavigateUC *usecase.NavigateUseCase
52 ZoomUC *usecase.ManageZoomUseCase
53 PermissionUC *usecase.HandlePermissionUseCase
54 FavoritesUC *usecase.ManageFavoritesUseCase
55 HistoryUC *usecase.SearchHistoryUseCase
56 CopyURLUC *usecase.CopyURLUseCase
57
58 // Infrastructure Adapters
59 Clipboard port.Clipboard
60 FaviconService port.FaviconService
61 FaviconAdapterConfig adapter.FaviconAdapterConfig
62 FilterManager port.FilterManager
63 IdleInhibitor port.IdleInhibitor
64
65 // Accent picker for dead keys support
66 InsertAccentUC *usecase.InsertAccentUseCase
67 AccentFocusProvider port.FocusedInputProvider
68 // NewGTKEntryTarget creates a port.TextInputTarget from a GTK SearchEntry.
69 // Injected to avoid importing infrastructure/textinput from the UI layer.
70 NewGTKEntryTarget func(entry *gtk.SearchEntry) port.TextInputTarget
71
72 // Session management
73 SessionStateRepo repository.SessionStateRepository
74 SessionRepo repository.SessionRepository
75 CurrentSessionID entity.SessionID
76 SnapshotUC *usecase.SnapshotSessionUseCase
77 // SnapshotServiceFactory creates a snapshot service bound to the given tab-list provider.
78 // Called after the App is initialized so the App can serve as the provider.
79 SnapshotServiceFactory func(provider port.TabListProvider, intervalMs int) port.SnapshotService
80 // SessionSpawner spawns a new dumber instance for session restoration.
81 SessionSpawner port.SessionSpawner
82 // FileSystem provides file operations (e.g., for download deduplication).
83 FileSystem port.FileSystem
84 // OnConfigChange registers a callback for config hot-reload.
85 // The config pointer in deps.Config is updated in-place before the callback fires.
86 OnConfigChange func(callback func())
87 // WatchConfig starts watching the config file for changes.
88 WatchConfig func() error
89
90 // Update management
91 CheckUpdateUC *usecase.CheckUpdateUseCase
92 ApplyUpdateUC *usecase.ApplyUpdateUseCase
93
94 // Config migration checker (optional; nil disables migration notifications)
95 ConfigMigrator port.ConfigMigrator
96
97 // LaunchExternalURL opens a URI with the system's default handler (e.g. xdg-open).
98 // Used for external URL schemes (vscode://, spotify://, etc.).
99 // Optional: if nil, external URLs are silently dropped.
100 LaunchExternalURL func(uri string)
101}
102
103// Validate checks that all required dependencies are set.
104func (d *Dependencies) Validate() error {
105 if d.Ctx == nil {
106 return ErrMissingDependency("Ctx")
107 }
108 if d.Config == nil {
109 return ErrMissingDependency("Config")
110 }
111 if d.Engine == nil {
112 return ErrMissingDependency("Engine")
113 }
114 // Use cases are optional - can be nil if not needed
115 return nil
116}
117
118// DependencyError indicates a missing required dependency.
119type DependencyError struct {
120 Name string
121}
122
123func (e DependencyError) Error() string {
124 return "missing required dependency: " + e.Name
125}
126
127// ErrMissingDependency creates a new DependencyError.
128func ErrMissingDependency(name string) error {
129 return DependencyError{Name: name}
130}