1package control
2
3import (
4 "context"
5 "log"
6 "os"
7
8 "github.com/bnema/dumber/internal/services"
9 "github.com/bnema/dumber/pkg/webkit"
10)
11
12// NavigationController manages navigation functionality
13type NavigationController struct {
14 parserService *services.ParserService
15 browserService *services.BrowserService
16 webView *webkit.WebView
17 zoomController *ZoomController
18}
19
20// NewNavigationController creates a new navigation controller
21func NewNavigationController(
22 parserService *services.ParserService,
23 browserService *services.BrowserService,
24 webView *webkit.WebView,
25 zoomController *ZoomController,
26) *NavigationController {
27 return &NavigationController{
28 parserService: parserService,
29 browserService: browserService,
30 webView: webView,
31 zoomController: zoomController,
32 }
33}
34
35// NavigateToURL parses input and navigates to the resulting URL
36func (n *NavigationController) NavigateToURL(input string) error {
37 ctx := context.Background()
38 result, err := n.parserService.ParseInput(ctx, input)
39 if err != nil {
40 return err
41 }
42
43 // Record navigation in browser service
44 if _, navErr := n.browserService.Navigate(ctx, result.URL); navErr != nil {
45 log.Printf("Warning: failed to navigate to %s: %v", result.URL, navErr)
46 }
47
48 var (
49 zoomLevel float64
50 haveZoom bool
51 )
52 if n.browserService != nil {
53 if level, err := n.browserService.GetZoomLevel(ctx, result.URL); err == nil {
54 zoomLevel = level
55 haveZoom = true
56 if n.webView != nil {
57 if n.webView.UsesDomZoom() {
58 n.webView.SeedDomZoom(zoomLevel)
59 } else {
60 n.webView.RunOnMainThread(func() {
61 if err := n.webView.SetZoom(zoomLevel); err != nil {
62 log.Printf("Warning: failed to prime native zoom for %s: %v", result.URL, err)
63 }
64 })
65 }
66 }
67 } else {
68 log.Printf("Warning: failed to lookup zoom for %s: %v", result.URL, err)
69 }
70 }
71
72 // Load URL in WebView
73 if err := n.webView.LoadURL(result.URL); err != nil {
74 return err
75 }
76
77 // Apply zoom for the new URL using the cached level when available.
78 if n.zoomController != nil {
79 if haveZoom {
80 n.zoomController.ApplyZoomForURLWithLevel(result.URL, zoomLevel, false)
81 } else {
82 n.zoomController.ApplyZoomForURL(result.URL)
83 }
84 }
85
86 return nil
87}
88
89// HandleBrowseCommand processes the browse command line argument
90func (n *NavigationController) HandleBrowseCommand() {
91 if len(os.Args) >= 3 && os.Args[1] == "browse" {
92 log.Printf("Browse command detected: %s", os.Args[2])
93 ctx := context.Background()
94 result, err := n.parserService.ParseInput(ctx, os.Args[2])
95 if err == nil {
96 log.Printf("Parsed input → URL: %s", result.URL)
97 if _, navErr := n.browserService.Navigate(ctx, result.URL); navErr != nil {
98 log.Printf("Warning: failed to navigate to %s: %v", result.URL, navErr)
99 }
100 if n.webView != nil {
101 log.Printf("Loading URL in WebView: %s", result.URL)
102 var (
103 zoomLevel float64
104 haveZoom bool
105 )
106 if n.browserService != nil {
107 if level, err := n.browserService.GetZoomLevel(ctx, result.URL); err == nil {
108 zoomLevel = level
109 haveZoom = true
110 if n.webView.UsesDomZoom() {
111 n.webView.SeedDomZoom(zoomLevel)
112 } else {
113 n.webView.RunOnMainThread(func() {
114 if err := n.webView.SetZoom(zoomLevel); err != nil {
115 log.Printf("Warning: failed to prime native zoom for %s: %v", result.URL, err)
116 }
117 })
118 }
119 } else {
120 log.Printf("Warning: failed to lookup zoom for %s: %v", result.URL, err)
121 }
122 }
123 if err := n.webView.LoadURL(result.URL); err != nil {
124 log.Printf("Warning: failed to load URL: %v", err)
125 }
126 if n.zoomController != nil {
127 if haveZoom {
128 n.zoomController.ApplyZoomForURLWithLevel(result.URL, zoomLevel, false)
129 } else {
130 n.zoomController.ApplyZoomForURL(result.URL)
131 }
132 }
133 }
134 }
135 }
136}