gui/pkg/contextmenu/service.go
Snider 62ec735c10
Some checks failed
Security Scan / security (push) Has been cancelled
Test / test (push) Has been cancelled
refactor: AX compliance sweep — replace banned stdlib imports with core primitives
Replaced fmt, strings, sort, os, io, sync, encoding/json, path/filepath,
errors, log, reflect with core.Sprintf, core.E, core.Contains, core.Trim,
core.Split, core.Join, core.JoinPath, slices.Sort, c.Fs(), c.Lock(),
core.JSONMarshal, core.ReadAll and other CoreGO v0.8.0 primitives.

Framework boundary exceptions preserved where stdlib types are required
by external interfaces (Gin, net/http, CGo, Wails, bubbletea).

Co-Authored-By: Virgil <virgil@lethean.io>
2026-04-13 09:32:01 +01:00

114 lines
2.7 KiB
Go

// pkg/contextmenu/service.go
package contextmenu
import (
"context"
corego "dappco.re/go/core"
"forge.lthn.ai/core/go/pkg/core"
)
// Options holds configuration for the context menu service.
type Options struct{}
// Service is a core.Service managing context menus via IPC.
// It maintains an in-memory registry of menus (map[string]ContextMenuDef)
// and delegates platform-level registration to the Platform interface.
type Service struct {
*core.ServiceRuntime[Options]
platform Platform
menus map[string]ContextMenuDef
}
// OnStartup registers IPC handlers.
func (s *Service) OnStartup(ctx context.Context) error {
s.Core().RegisterQuery(s.handleQuery)
s.Core().RegisterTask(s.handleTask)
return nil
}
// HandleIPCEvents is auto-discovered and registered by core.WithService.
func (s *Service) HandleIPCEvents(c *core.Core, msg core.Message) error {
return nil
}
// --- Query Handlers ---
func (s *Service) handleQuery(c *core.Core, q core.Query) (any, bool, error) {
switch q := q.(type) {
case QueryGet:
return s.queryGet(q), true, nil
case QueryList:
return s.queryList(), true, nil
default:
return nil, false, nil
}
}
// queryGet returns a single menu definition by name, or nil if not found.
func (s *Service) queryGet(q QueryGet) *ContextMenuDef {
menu, ok := s.menus[q.Name]
if !ok {
return nil
}
return &menu
}
// queryList returns a copy of all registered menus.
func (s *Service) queryList() map[string]ContextMenuDef {
result := make(map[string]ContextMenuDef, len(s.menus))
for k, v := range s.menus {
result[k] = v
}
return result
}
// --- Task Handlers ---
func (s *Service) handleTask(c *core.Core, t core.Task) (any, bool, error) {
switch t := t.(type) {
case TaskAdd:
return nil, true, s.taskAdd(t)
case TaskRemove:
return nil, true, s.taskRemove(t)
default:
return nil, false, nil
}
}
func (s *Service) taskAdd(t TaskAdd) error {
// If menu already exists, remove it first (replace semantics)
if _, exists := s.menus[t.Name]; exists {
_ = s.platform.Remove(t.Name)
delete(s.menus, t.Name)
}
// Register on platform with a callback that broadcasts ActionItemClicked
err := s.platform.Add(t.Name, t.Menu, func(menuName, actionID, data string) {
_ = s.Core().ACTION(ActionItemClicked{
MenuName: menuName,
ActionID: actionID,
Data: data,
})
})
if err != nil {
return corego.Wrap(err, "contextmenu.add", "platform add failed")
}
s.menus[t.Name] = t.Menu
return nil
}
func (s *Service) taskRemove(t TaskRemove) error {
if _, exists := s.menus[t.Name]; !exists {
return ErrMenuNotFound
}
err := s.platform.Remove(t.Name)
if err != nil {
return corego.Wrap(err, "contextmenu.remove", "platform remove failed")
}
delete(s.menus, t.Name)
return nil
}