detached 42b083b

refactor(assets): update embedded asset paths from frontend/dist to assets/gui

commit
42b083b2c8eb763f996105e068996e2e37534592
author
bamen · · 2025-09-15 05:21 UTC
parent
d5d7212
signature
unsigned
3 files · +15 -16
M internal/app/api/scheme.go +3 -3
@@ -40,7 +40,7 @@ func (s *SchemeHandler) Handle(uri string, cfg *config.Config) (string, []byte,
4040 log.Printf("[scheme] request: %s", uri)
4141 // Known forms:
4242 // - dumb://homepage or dumb:homepage → index.html
43- // - dumb://app/index.html, dumb://app/<path> → serve from frontend/dist/<path>
43+ // - dumb://app/index.html, dumb://app/<path> → serve from gui/<path>
4444 // - dumb://<anything> without path → index.html
4545 u, err := neturl.Parse(uri)
4646 if err != nil || u.Scheme != "dumb" {
@@ -117,14 +117,14 @@ func (s *SchemeHandler) handleAsset(u *neturl.URL) (string, []byte, bool) {
117117 // Special-case homepage favicon: map .ico request to embedded SVG file
118118 if (u.Host == constants.HomepagePath || u.Opaque == constants.HomepagePath) && strings.EqualFold(rel, "favicon.ico") {
119119 log.Printf("[scheme] asset: rel=%s (host=%s path=%s) → mapping to favicon.svg", rel, u.Host, u.Path)
120- data, rerr := s.assets.ReadFile(filepath.ToSlash(filepath.Join("frontend", "dist", "favicon.svg")))
120+ data, rerr := s.assets.ReadFile(filepath.ToSlash(filepath.Join("assets", "gui", "favicon.svg")))
121121 if rerr == nil {
122122 return "image/svg+xml", data, true
123123 }
124124 }
125125
126126 log.Printf("[scheme] asset: rel=%s (host=%s path=%s)", rel, u.Host, u.Path)
127- data, rerr := s.assets.ReadFile(filepath.ToSlash(filepath.Join("frontend", "dist", rel)))
127+ data, rerr := s.assets.ReadFile(filepath.ToSlash(filepath.Join("assets", "gui", rel)))
128128 if rerr != nil {
129129 log.Printf("[scheme] not found: %s", rel)
130130 return "", nil, false
@@ -40,7 +40,7 @@ func (s *SchemeHandler) Handle(uri string, cfg *config.Config) (string, []byte,
40 log.Printf("[scheme] request: %s", uri)40 log.Printf("[scheme] request: %s", uri)
41 // Known forms:41 // Known forms:
42 // - dumb://homepage or dumb:homepage → index.html42 // - dumb://homepage or dumb:homepage → index.html
43- // - dumb://app/index.html, dumb://app/<path> → serve from frontend/dist/<path>43+ // - dumb://app/index.html, dumb://app/<path> → serve from gui/<path>
44 // - dumb://<anything> without path → index.html44 // - dumb://<anything> without path → index.html
45 u, err := neturl.Parse(uri)45 u, err := neturl.Parse(uri)
46 if err != nil || u.Scheme != "dumb" {46 if err != nil || u.Scheme != "dumb" {
@@ -117,14 +117,14 @@ func (s *SchemeHandler) handleAsset(u *neturl.URL) (string, []byte, bool) {
117 // Special-case homepage favicon: map .ico request to embedded SVG file117 // Special-case homepage favicon: map .ico request to embedded SVG file
118 if (u.Host == constants.HomepagePath || u.Opaque == constants.HomepagePath) && strings.EqualFold(rel, "favicon.ico") {118 if (u.Host == constants.HomepagePath || u.Opaque == constants.HomepagePath) && strings.EqualFold(rel, "favicon.ico") {
119 log.Printf("[scheme] asset: rel=%s (host=%s path=%s) → mapping to favicon.svg", rel, u.Host, u.Path)119 log.Printf("[scheme] asset: rel=%s (host=%s path=%s) → mapping to favicon.svg", rel, u.Host, u.Path)
120- data, rerr := s.assets.ReadFile(filepath.ToSlash(filepath.Join("frontend", "dist", "favicon.svg")))120+ data, rerr := s.assets.ReadFile(filepath.ToSlash(filepath.Join("assets", "gui", "favicon.svg")))
121 if rerr == nil {121 if rerr == nil {
122 return "image/svg+xml", data, true122 return "image/svg+xml", data, true
123 }123 }
124 }124 }
125 125
126 log.Printf("[scheme] asset: rel=%s (host=%s path=%s)", rel, u.Host, u.Path)126 log.Printf("[scheme] asset: rel=%s (host=%s path=%s)", rel, u.Host, u.Path)
127- data, rerr := s.assets.ReadFile(filepath.ToSlash(filepath.Join("frontend", "dist", rel)))127+ data, rerr := s.assets.ReadFile(filepath.ToSlash(filepath.Join("assets", "gui", rel)))
128 if rerr != nil {128 if rerr != nil {
129 log.Printf("[scheme] not found: %s", rel)129 log.Printf("[scheme] not found: %s", rel)
130 return "", nil, false130 return "", nil, false
M internal/parser/parser.go +11 -12
@@ -39,7 +39,7 @@ func (p *Parser) ParseInput(input string) (*ParseResult, error) {
3939 if strings.Contains(finalURL, "google.com/search") {
4040 resultType = InputTypeFallbackSearch
4141 confidence = 0.1
42- } else if strings.HasPrefix(finalURL, "http://") || strings.HasPrefix(finalURL, "https://") {
42+ } else if strings.HasPrefix(finalURL, "http://") || strings.HasPrefix(finalURL, "https://") || strings.HasPrefix(finalURL, "dumb://") || strings.HasPrefix(finalURL, "file://") {
4343 resultType = InputTypeDirectURL
4444 confidence = 1.0
4545 }
@@ -108,17 +108,22 @@ func (p *Parser) parseInputUsingCLILogic(input string) (string, error) {
108108 return input, nil
109109 }
110110
111- // 4. Localhost/development URLs
111+ // 4. Dumb protocol for custom browser pages
112+ if strings.HasPrefix(input, "dumb://") {
113+ return input, nil
114+ }
115+
116+ // 5. Localhost/development URLs
112117 if regexp.MustCompile(`^(localhost|127\.0\.0\.1|0\.0\.0\.0|::1)(:\d+)?(/.*)?$`).MatchString(input) {
113118 return "http://" + input, nil
114119 }
115120
116- // 5. Local network IPs
121+ // 6. Local network IPs
117122 if regexp.MustCompile(`^(192\.168|10\.|172\.(1[6-9]|2[0-9]|3[01]))\.\d+\.\d+(:\d+)?(/.*)?$`).MatchString(input) {
118123 return "http://" + input, nil
119124 }
120125
121- // 6. Domain with TLD (must have dot and valid TLD)
126+ // 7. Domain with TLD (must have dot and valid TLD)
122127 // More comprehensive TLD pattern for better URL detection
123128 domainPattern := regexp.MustCompile(`^([a-zA-Z0-9]([a-zA-Z0-9\-]{0,61}[a-zA-Z0-9])?\.)+[a-zA-Z]{2,}(/.*)?$`)
124129 if domainPattern.MatchString(input) {
@@ -132,15 +137,9 @@ func (p *Parser) parseInputUsingCLILogic(input string) (string, error) {
132137 return "https://" + input, nil
133138 }
134139
135- // 7. Possible local hostname (single word, might be on local network)
136- singleHostPattern := regexp.MustCompile(`^[a-zA-Z0-9]([a-zA-Z0-9\-]{0,61}[a-zA-Z0-9])?$`)
137- if singleHostPattern.MatchString(input) && len(input) <= 63 {
138- // Could be local hostname, try as URL but don't validate
139- return "http://" + input, nil
140- }
141-
142140 // 8. Everything else is a search query
143- // This includes: multi-word phrases, questions, special characters, etc.
141+ // This includes: single words, multi-word phrases, questions, special characters, etc.
142+ // Single words without TLDs should be treated as search queries, not hostnames
144143 return fmt.Sprintf("https://www.google.com/search?q=%s", neturl.QueryEscape(input)), nil
145144 }
146145
@@ -39,7 +39,7 @@ func (p *Parser) ParseInput(input string) (*ParseResult, error) {
39 if strings.Contains(finalURL, "google.com/search") {39 if strings.Contains(finalURL, "google.com/search") {
40 resultType = InputTypeFallbackSearch40 resultType = InputTypeFallbackSearch
41 confidence = 0.141 confidence = 0.1
42- } else if strings.HasPrefix(finalURL, "http://") || strings.HasPrefix(finalURL, "https://") {42+ } else if strings.HasPrefix(finalURL, "http://") || strings.HasPrefix(finalURL, "https://") || strings.HasPrefix(finalURL, "dumb://") || strings.HasPrefix(finalURL, "file://") {
43 resultType = InputTypeDirectURL43 resultType = InputTypeDirectURL
44 confidence = 1.044 confidence = 1.0
45 }45 }
@@ -108,17 +108,22 @@ func (p *Parser) parseInputUsingCLILogic(input string) (string, error) {
108 return input, nil108 return input, nil
109 }109 }
110 110
111- // 4. Localhost/development URLs111+ // 4. Dumb protocol for custom browser pages
112+ if strings.HasPrefix(input, "dumb://") {
113+ return input, nil
114+ }
115+
116+ // 5. Localhost/development URLs
112 if regexp.MustCompile(`^(localhost|127\.0\.0\.1|0\.0\.0\.0|::1)(:\d+)?(/.*)?$`).MatchString(input) {117 if regexp.MustCompile(`^(localhost|127\.0\.0\.1|0\.0\.0\.0|::1)(:\d+)?(/.*)?$`).MatchString(input) {
113 return "http://" + input, nil118 return "http://" + input, nil
114 }119 }
115 120
116- // 5. Local network IPs121+ // 6. Local network IPs
117 if regexp.MustCompile(`^(192\.168|10\.|172\.(1[6-9]|2[0-9]|3[01]))\.\d+\.\d+(:\d+)?(/.*)?$`).MatchString(input) {122 if regexp.MustCompile(`^(192\.168|10\.|172\.(1[6-9]|2[0-9]|3[01]))\.\d+\.\d+(:\d+)?(/.*)?$`).MatchString(input) {
118 return "http://" + input, nil123 return "http://" + input, nil
119 }124 }
120 125
121- // 6. Domain with TLD (must have dot and valid TLD)126+ // 7. Domain with TLD (must have dot and valid TLD)
122 // More comprehensive TLD pattern for better URL detection127 // More comprehensive TLD pattern for better URL detection
123 domainPattern := regexp.MustCompile(`^([a-zA-Z0-9]([a-zA-Z0-9\-]{0,61}[a-zA-Z0-9])?\.)+[a-zA-Z]{2,}(/.*)?$`)128 domainPattern := regexp.MustCompile(`^([a-zA-Z0-9]([a-zA-Z0-9\-]{0,61}[a-zA-Z0-9])?\.)+[a-zA-Z]{2,}(/.*)?$`)
124 if domainPattern.MatchString(input) {129 if domainPattern.MatchString(input) {
@@ -132,15 +137,9 @@ func (p *Parser) parseInputUsingCLILogic(input string) (string, error) {
132 return "https://" + input, nil137 return "https://" + input, nil
133 }138 }
134 139
135- // 7. Possible local hostname (single word, might be on local network)
136- singleHostPattern := regexp.MustCompile(`^[a-zA-Z0-9]([a-zA-Z0-9\-]{0,61}[a-zA-Z0-9])?$`)
137- if singleHostPattern.MatchString(input) && len(input) <= 63 {
138- // Could be local hostname, try as URL but don't validate
139- return "http://" + input, nil
140- }
141-
142 // 8. Everything else is a search query140 // 8. Everything else is a search query
143- // This includes: multi-word phrases, questions, special characters, etc.141+ // This includes: single words, multi-word phrases, questions, special characters, etc.
142+ // Single words without TLDs should be treated as search queries, not hostnames
144 return fmt.Sprintf("https://www.google.com/search?q=%s", neturl.QueryEscape(input)), nil143 return fmt.Sprintf("https://www.google.com/search?q=%s", neturl.QueryEscape(input)), nil
145 }144 }
146 145
M main.go +1 -1
@@ -13,7 +13,7 @@ import (
1313 "github.com/bnema/dumber/pkg/webkit"
1414 )
1515
16-//go:embed frontend/dist assets
16+//go:embed assets
1717 var assets embed.FS
1818
1919 // Build information set via ldflags
@@ -13,7 +13,7 @@ import (
13 "github.com/bnema/dumber/pkg/webkit"13 "github.com/bnema/dumber/pkg/webkit"
14 )14 )
15 15
16-//go:embed frontend/dist assets16+//go:embed assets
17 var assets embed.FS17 var assets embed.FS
18 18
19 // Build information set via ldflags19 // Build information set via ldflags

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