refactor(gui): align gui services with ax guidance
This commit is contained in:
parent
973217ae54
commit
c3361b7064
6 changed files with 87 additions and 37 deletions
|
|
@ -3,21 +3,32 @@ package clipboard
|
|||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
|
||||
"forge.lthn.ai/core/go/pkg/core"
|
||||
)
|
||||
|
||||
// Options holds configuration for the clipboard service.
|
||||
// Options configures the clipboard service.
|
||||
//
|
||||
// Example:
|
||||
//
|
||||
// core.WithService(clipboard.Register(platform))
|
||||
type Options struct{}
|
||||
|
||||
// Service is a core.Service managing clipboard operations via IPC.
|
||||
// Service manages clipboard operations via Core queries and tasks.
|
||||
//
|
||||
// Example:
|
||||
//
|
||||
// svc := &clipboard.Service{}
|
||||
type Service struct {
|
||||
*core.ServiceRuntime[Options]
|
||||
platform Platform
|
||||
}
|
||||
|
||||
// Register creates a factory closure that captures the Platform adapter.
|
||||
// Register creates a Core service factory for the clipboard backend.
|
||||
//
|
||||
// Example:
|
||||
//
|
||||
// core.New(core.WithService(clipboard.Register(platform)))
|
||||
func Register(p Platform) func(*core.Core) (any, error) {
|
||||
return func(c *core.Core) (any, error) {
|
||||
return &Service{
|
||||
|
|
@ -27,14 +38,18 @@ func Register(p Platform) func(*core.Core) (any, error) {
|
|||
}
|
||||
}
|
||||
|
||||
// OnStartup registers IPC handlers.
|
||||
// OnStartup registers clipboard handlers with Core.
|
||||
//
|
||||
// Example:
|
||||
//
|
||||
// _ = svc.OnStartup(context.Background())
|
||||
func (s *Service) OnStartup(ctx context.Context) error {
|
||||
s.Core().RegisterQuery(s.handleQuery)
|
||||
s.Core().RegisterTask(s.handleTask)
|
||||
return nil
|
||||
}
|
||||
|
||||
// HandleIPCEvents is auto-discovered by core.WithService.
|
||||
// HandleIPCEvents satisfies Core's IPC hook.
|
||||
func (s *Service) HandleIPCEvents(c *core.Core, msg core.Message) error {
|
||||
return nil
|
||||
}
|
||||
|
|
@ -70,7 +85,7 @@ func (s *Service) handleTask(c *core.Core, t core.Task) (any, bool, error) {
|
|||
if writer, ok := s.platform.(imageWriter); ok {
|
||||
return writer.SetImage(t.Data), true, nil
|
||||
}
|
||||
return false, true, fmt.Errorf("clipboard image write not supported")
|
||||
return false, true, core.E("clipboard.handleTask", "clipboard image write not supported", nil)
|
||||
default:
|
||||
return nil, false, nil
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1562,7 +1562,7 @@ func (s *Service) ReadClipboard() (string, error) {
|
|||
return "", err
|
||||
}
|
||||
if !handled {
|
||||
return "", fmt.Errorf("clipboard service not available")
|
||||
return "", core.E("display.ReadClipboard", "clipboard service not available", nil)
|
||||
}
|
||||
content, _ := result.(clipboard.ClipboardContent)
|
||||
return content.Text, nil
|
||||
|
|
@ -1575,10 +1575,10 @@ func (s *Service) WriteClipboard(text string) error {
|
|||
return err
|
||||
}
|
||||
if !handled {
|
||||
return fmt.Errorf("clipboard service not available")
|
||||
return core.E("display.WriteClipboard", "clipboard service not available", nil)
|
||||
}
|
||||
if ok, _ := result.(bool); !ok {
|
||||
return fmt.Errorf("clipboard write failed")
|
||||
return core.E("display.WriteClipboard", "clipboard write failed", nil)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
|
@ -1607,10 +1607,10 @@ func (s *Service) ClearClipboard() error {
|
|||
return err
|
||||
}
|
||||
if !handled {
|
||||
return fmt.Errorf("clipboard service not available")
|
||||
return core.E("display.ClearClipboard", "clipboard service not available", nil)
|
||||
}
|
||||
if ok, _ := result.(bool); !ok {
|
||||
return fmt.Errorf("clipboard clear failed")
|
||||
return core.E("display.ClearClipboard", "clipboard clear failed", nil)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
|
@ -1622,7 +1622,7 @@ func (s *Service) ReadClipboardImage() (clipboard.ClipboardImageContent, error)
|
|||
return clipboard.ClipboardImageContent{}, err
|
||||
}
|
||||
if !handled {
|
||||
return clipboard.ClipboardImageContent{}, fmt.Errorf("clipboard service not available")
|
||||
return clipboard.ClipboardImageContent{}, core.E("display.ReadClipboardImage", "clipboard service not available", nil)
|
||||
}
|
||||
content, _ := result.(clipboard.ClipboardImageContent)
|
||||
return content, nil
|
||||
|
|
@ -1635,10 +1635,10 @@ func (s *Service) WriteClipboardImage(data []byte) error {
|
|||
return err
|
||||
}
|
||||
if !handled {
|
||||
return fmt.Errorf("clipboard service not available")
|
||||
return core.E("display.WriteClipboardImage", "clipboard service not available", nil)
|
||||
}
|
||||
if ok, _ := result.(bool); !ok {
|
||||
return fmt.Errorf("clipboard image write failed")
|
||||
return core.E("display.WriteClipboardImage", "clipboard image write failed", nil)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
|
@ -1652,7 +1652,7 @@ func (s *Service) ShowNotification(opts notification.NotificationOptions) error
|
|||
return err
|
||||
}
|
||||
if !handled {
|
||||
return fmt.Errorf("notification service not available")
|
||||
return core.E("display.ShowNotification", "notification service not available", nil)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
|
|
|||
|
|
@ -10,16 +10,28 @@ import (
|
|||
"forge.lthn.ai/core/gui/pkg/dialog"
|
||||
)
|
||||
|
||||
// Options holds configuration for the notification service.
|
||||
// Options configures the notification service.
|
||||
//
|
||||
// Example:
|
||||
//
|
||||
// core.WithService(notification.Register(platform))
|
||||
type Options struct{}
|
||||
|
||||
// Service is a core.Service managing notifications via IPC.
|
||||
// Service manages notifications via Core tasks and queries.
|
||||
//
|
||||
// Example:
|
||||
//
|
||||
// svc := ¬ification.Service{}
|
||||
type Service struct {
|
||||
*core.ServiceRuntime[Options]
|
||||
platform Platform
|
||||
}
|
||||
|
||||
// Register creates a factory closure that captures the Platform adapter.
|
||||
// Register creates a Core service factory for the notification backend.
|
||||
//
|
||||
// Example:
|
||||
//
|
||||
// core.New(core.WithService(notification.Register(platform)))
|
||||
func Register(p Platform) func(*core.Core) (any, error) {
|
||||
return func(c *core.Core) (any, error) {
|
||||
return &Service{
|
||||
|
|
@ -29,14 +41,18 @@ func Register(p Platform) func(*core.Core) (any, error) {
|
|||
}
|
||||
}
|
||||
|
||||
// OnStartup registers IPC handlers.
|
||||
// OnStartup registers notification handlers with Core.
|
||||
//
|
||||
// Example:
|
||||
//
|
||||
// _ = svc.OnStartup(context.Background())
|
||||
func (s *Service) OnStartup(ctx context.Context) error {
|
||||
s.Core().RegisterQuery(s.handleQuery)
|
||||
s.Core().RegisterTask(s.handleTask)
|
||||
return nil
|
||||
}
|
||||
|
||||
// HandleIPCEvents is auto-discovered by core.WithService.
|
||||
// HandleIPCEvents satisfies Core's IPC hook.
|
||||
func (s *Service) HandleIPCEvents(c *core.Core, msg core.Message) error {
|
||||
return nil
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,12 +1,12 @@
|
|||
// pkg/systray/menu.go
|
||||
package systray
|
||||
|
||||
import "fmt"
|
||||
import "forge.lthn.ai/core/go/pkg/core"
|
||||
|
||||
// SetMenu sets a dynamic menu on the tray from TrayMenuItem descriptors.
|
||||
func (m *Manager) SetMenu(items []TrayMenuItem) error {
|
||||
if m.tray == nil {
|
||||
return fmt.Errorf("tray not initialised")
|
||||
return core.E("systray.SetMenu", "tray not initialised", nil)
|
||||
}
|
||||
m.menuItems = append([]TrayMenuItem(nil), items...)
|
||||
menu := m.buildMenu(items)
|
||||
|
|
|
|||
|
|
@ -2,16 +2,23 @@ package systray
|
|||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
|
||||
"forge.lthn.ai/core/go/pkg/core"
|
||||
"forge.lthn.ai/core/gui/pkg/notification"
|
||||
)
|
||||
|
||||
// Options holds configuration for the systray service.
|
||||
// Options configures the systray service.
|
||||
//
|
||||
// Example:
|
||||
//
|
||||
// core.WithService(systray.Register(platform))
|
||||
type Options struct{}
|
||||
|
||||
// Service is a core.Service managing the system tray via IPC.
|
||||
// Service manages system tray operations via Core tasks.
|
||||
//
|
||||
// Example:
|
||||
//
|
||||
// svc := &systray.Service{}
|
||||
type Service struct {
|
||||
*core.ServiceRuntime[Options]
|
||||
manager *Manager
|
||||
|
|
@ -19,7 +26,11 @@ type Service struct {
|
|||
iconPath string
|
||||
}
|
||||
|
||||
// OnStartup queries config and registers IPC handlers.
|
||||
// OnStartup loads tray config and registers task handlers.
|
||||
//
|
||||
// Example:
|
||||
//
|
||||
// _ = svc.OnStartup(context.Background())
|
||||
func (s *Service) OnStartup(ctx context.Context) error {
|
||||
cfg, handled, _ := s.Core().QUERY(QueryConfig{})
|
||||
if handled {
|
||||
|
|
@ -45,7 +56,7 @@ func (s *Service) applyConfig(cfg map[string]any) {
|
|||
}
|
||||
}
|
||||
|
||||
// HandleIPCEvents is auto-discovered and registered by core.WithService.
|
||||
// HandleIPCEvents satisfies Core's IPC hook.
|
||||
func (s *Service) HandleIPCEvents(c *core.Core, msg core.Message) error {
|
||||
return nil
|
||||
}
|
||||
|
|
@ -95,7 +106,7 @@ func (s *Service) taskShowMessage(title, message string) error {
|
|||
}
|
||||
tray := s.manager.Tray()
|
||||
if tray == nil {
|
||||
return fmt.Errorf("tray not initialised")
|
||||
return core.E("systray.taskShowMessage", "tray not initialised", nil)
|
||||
}
|
||||
if messenger, ok := tray.(interface{ ShowMessage(title, message string) }); ok {
|
||||
messenger.ShowMessage(title, message)
|
||||
|
|
|
|||
|
|
@ -3,15 +3,19 @@ package systray
|
|||
|
||||
import (
|
||||
_ "embed"
|
||||
"fmt"
|
||||
"sync"
|
||||
|
||||
"forge.lthn.ai/core/go/pkg/core"
|
||||
)
|
||||
|
||||
//go:embed assets/apptray.png
|
||||
var defaultIcon []byte
|
||||
|
||||
// Manager manages the system tray lifecycle.
|
||||
// State that was previously in package-level vars is now on the Manager.
|
||||
//
|
||||
// Example:
|
||||
//
|
||||
// manager := systray.NewManager(platform)
|
||||
type Manager struct {
|
||||
platform Platform
|
||||
tray PlatformTray
|
||||
|
|
@ -25,6 +29,10 @@ type Manager struct {
|
|||
}
|
||||
|
||||
// NewManager creates a systray Manager.
|
||||
//
|
||||
// Example:
|
||||
//
|
||||
// manager := systray.NewManager(platform)
|
||||
func NewManager(platform Platform) *Manager {
|
||||
return &Manager{
|
||||
platform: platform,
|
||||
|
|
@ -36,7 +44,7 @@ func NewManager(platform Platform) *Manager {
|
|||
func (m *Manager) Setup(tooltip, label string) error {
|
||||
m.tray = m.platform.NewTray()
|
||||
if m.tray == nil {
|
||||
return fmt.Errorf("platform returned nil tray")
|
||||
return core.E("systray.Setup", "platform returned nil tray", nil)
|
||||
}
|
||||
m.tray.SetTemplateIcon(defaultIcon)
|
||||
m.tray.SetTooltip(tooltip)
|
||||
|
|
@ -50,7 +58,7 @@ func (m *Manager) Setup(tooltip, label string) error {
|
|||
// SetIcon sets the tray icon.
|
||||
func (m *Manager) SetIcon(data []byte) error {
|
||||
if m.tray == nil {
|
||||
return fmt.Errorf("tray not initialised")
|
||||
return core.E("systray.SetIcon", "tray not initialised", nil)
|
||||
}
|
||||
m.tray.SetIcon(data)
|
||||
m.hasIcon = len(data) > 0
|
||||
|
|
@ -60,7 +68,7 @@ func (m *Manager) SetIcon(data []byte) error {
|
|||
// SetTemplateIcon sets the template icon (macOS).
|
||||
func (m *Manager) SetTemplateIcon(data []byte) error {
|
||||
if m.tray == nil {
|
||||
return fmt.Errorf("tray not initialised")
|
||||
return core.E("systray.SetTemplateIcon", "tray not initialised", nil)
|
||||
}
|
||||
m.tray.SetTemplateIcon(data)
|
||||
m.hasTemplateIcon = len(data) > 0
|
||||
|
|
@ -70,7 +78,7 @@ func (m *Manager) SetTemplateIcon(data []byte) error {
|
|||
// SetTooltip sets the tray tooltip.
|
||||
func (m *Manager) SetTooltip(text string) error {
|
||||
if m.tray == nil {
|
||||
return fmt.Errorf("tray not initialised")
|
||||
return core.E("systray.SetTooltip", "tray not initialised", nil)
|
||||
}
|
||||
m.tray.SetTooltip(text)
|
||||
m.tooltip = text
|
||||
|
|
@ -80,7 +88,7 @@ func (m *Manager) SetTooltip(text string) error {
|
|||
// SetLabel sets the tray label.
|
||||
func (m *Manager) SetLabel(text string) error {
|
||||
if m.tray == nil {
|
||||
return fmt.Errorf("tray not initialised")
|
||||
return core.E("systray.SetLabel", "tray not initialised", nil)
|
||||
}
|
||||
m.tray.SetLabel(text)
|
||||
m.label = text
|
||||
|
|
@ -90,7 +98,7 @@ func (m *Manager) SetLabel(text string) error {
|
|||
// AttachWindow attaches a panel window to the tray.
|
||||
func (m *Manager) AttachWindow(w WindowHandle) error {
|
||||
if m.tray == nil {
|
||||
return fmt.Errorf("tray not initialised")
|
||||
return core.E("systray.AttachWindow", "tray not initialised", nil)
|
||||
}
|
||||
m.tray.AttachWindow(w)
|
||||
return nil
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue