detached eff419b

feat(cli): initialize content filtering in main application

commit
eff419b7ee5db065466b67b5acf44dd60e83fee0
author
brice · · 2025-12-18 18:02 UTC
committer
brice · · 2025-12-18 18:51 UTC
parent
5f7dbbb
signature
unsigned
1 file · +25 -0
M cmd/dumber/main.go +25 -0
@@ -14,6 +14,7 @@ import (
1414 "github.com/bnema/dumber/internal/infrastructure/clipboard"
1515 "github.com/bnema/dumber/internal/infrastructure/config"
1616 "github.com/bnema/dumber/internal/infrastructure/favicon"
17+ "github.com/bnema/dumber/internal/infrastructure/filtering"
1718 "github.com/bnema/dumber/internal/infrastructure/media"
1819 "github.com/bnema/dumber/internal/infrastructure/persistence/sqlite"
1920 "github.com/bnema/dumber/internal/infrastructure/webkit"
@@ -150,6 +151,24 @@ func runGUI() {
150151 logger.Fatal().Err(err).Msg("failed to initialize WebKit context")
151152 }
152153
154+ // Content filtering (ad blocking)
155+ filterStoreDir := filepath.Join(dataDir, "filters", "store")
156+ filterJSONDir := filepath.Join(dataDir, "filters", "json")
157+ filterManager, err := filtering.NewManager(filtering.ManagerConfig{
158+ StoreDir: filterStoreDir,
159+ JSONDir: filterJSONDir,
160+ Enabled: cfg.ContentFiltering.Enabled,
161+ AutoUpdate: cfg.ContentFiltering.AutoUpdate,
162+ })
163+ if err != nil {
164+ logger.Warn().Err(err).Msg("failed to create filter manager, continuing without content filtering")
165+ } else {
166+ // Fast init: load compiled filters if cached
167+ if err := filterManager.Initialize(ctx); err != nil {
168+ logger.Warn().Err(err).Msg("failed to initialize filters, will load async")
169+ }
170+ }
171+
153172 // Register dumb:// scheme handler for serving embedded webui
154173 schemeHandler := webkit.NewDumbSchemeHandler(ctx)
155174 schemeHandler.SetAssets(assets.WebUIAssets)
@@ -169,6 +188,11 @@ func runGUI() {
169188 poolCfg := webkit.DefaultPoolConfig()
170189 pool := webkit.NewWebViewPool(ctx, wkCtx, settings, poolCfg, injector, messageRouter)
171190
191+ // Set filter applier on the pool if filtering is enabled
192+ if filterManager != nil {
193+ pool.SetFilterApplier(filterManager)
194+ }
195+
172196 // Create use cases
173197 idCounter := uint64(0)
174198 idGenerator := func() string {
@@ -214,6 +238,7 @@ func runGUI() {
214238 // Infrastructure Adapters
215239 Clipboard: clipboardAdapter,
216240 FaviconService: faviconService,
241+ FilterManager: filterManager,
217242 }
218243
219244 // Run the application
@@ -14,6 +14,7 @@ import (
14 "github.com/bnema/dumber/internal/infrastructure/clipboard"14 "github.com/bnema/dumber/internal/infrastructure/clipboard"
15 "github.com/bnema/dumber/internal/infrastructure/config"15 "github.com/bnema/dumber/internal/infrastructure/config"
16 "github.com/bnema/dumber/internal/infrastructure/favicon"16 "github.com/bnema/dumber/internal/infrastructure/favicon"
17+ "github.com/bnema/dumber/internal/infrastructure/filtering"
17 "github.com/bnema/dumber/internal/infrastructure/media"18 "github.com/bnema/dumber/internal/infrastructure/media"
18 "github.com/bnema/dumber/internal/infrastructure/persistence/sqlite"19 "github.com/bnema/dumber/internal/infrastructure/persistence/sqlite"
19 "github.com/bnema/dumber/internal/infrastructure/webkit"20 "github.com/bnema/dumber/internal/infrastructure/webkit"
@@ -150,6 +151,24 @@ func runGUI() {
150 logger.Fatal().Err(err).Msg("failed to initialize WebKit context")151 logger.Fatal().Err(err).Msg("failed to initialize WebKit context")
151 }152 }
152 153
154+ // Content filtering (ad blocking)
155+ filterStoreDir := filepath.Join(dataDir, "filters", "store")
156+ filterJSONDir := filepath.Join(dataDir, "filters", "json")
157+ filterManager, err := filtering.NewManager(filtering.ManagerConfig{
158+ StoreDir: filterStoreDir,
159+ JSONDir: filterJSONDir,
160+ Enabled: cfg.ContentFiltering.Enabled,
161+ AutoUpdate: cfg.ContentFiltering.AutoUpdate,
162+ })
163+ if err != nil {
164+ logger.Warn().Err(err).Msg("failed to create filter manager, continuing without content filtering")
165+ } else {
166+ // Fast init: load compiled filters if cached
167+ if err := filterManager.Initialize(ctx); err != nil {
168+ logger.Warn().Err(err).Msg("failed to initialize filters, will load async")
169+ }
170+ }
171+
153 // Register dumb:// scheme handler for serving embedded webui172 // Register dumb:// scheme handler for serving embedded webui
154 schemeHandler := webkit.NewDumbSchemeHandler(ctx)173 schemeHandler := webkit.NewDumbSchemeHandler(ctx)
155 schemeHandler.SetAssets(assets.WebUIAssets)174 schemeHandler.SetAssets(assets.WebUIAssets)
@@ -169,6 +188,11 @@ func runGUI() {
169 poolCfg := webkit.DefaultPoolConfig()188 poolCfg := webkit.DefaultPoolConfig()
170 pool := webkit.NewWebViewPool(ctx, wkCtx, settings, poolCfg, injector, messageRouter)189 pool := webkit.NewWebViewPool(ctx, wkCtx, settings, poolCfg, injector, messageRouter)
171 190
191+ // Set filter applier on the pool if filtering is enabled
192+ if filterManager != nil {
193+ pool.SetFilterApplier(filterManager)
194+ }
195+
172 // Create use cases196 // Create use cases
173 idCounter := uint64(0)197 idCounter := uint64(0)
174 idGenerator := func() string {198 idGenerator := func() string {
@@ -214,6 +238,7 @@ func runGUI() {
214 // Infrastructure Adapters238 // Infrastructure Adapters
215 Clipboard: clipboardAdapter,239 Clipboard: clipboardAdapter,
216 FaviconService: faviconService,240 FaviconService: faviconService,
241+ FilterManager: filterManager,
217 }242 }
218 243
219 // Run the application244 // Run the application

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