package main import ( "context" "fmt" "log" "sort" "strings" "github.com/wailsapp/wails/v2/pkg/runtime" "lmika.dev/pkg/modash/moslice" "ucl.lmika.dev/ucl" "ucl.lmika.dev/ucl/builtins" ) // App struct type App struct { store *Store uclInst *ucl.Inst ctx context.Context } // NewApp creates a new App application struct func NewApp(store *Store) *App { uclInst := ucl.New( ucl.WithModule(builtins.CSV(nil)), ucl.WithModule(builtins.Fns()), ucl.WithModule(builtins.FS(nil)), ucl.WithModule(builtins.Itrs()), ucl.WithModule(builtins.Lists()), ucl.WithModule(builtins.Log(nil)), ucl.WithModule(builtins.OS()), ucl.WithModule(builtins.Strs()), ucl.WithModule(builtins.Time()), ) return &App{ store: store, uclInst: uclInst, } } // startup is called when the app starts. The context is saved // so we can call the runtime methods func (a *App) startup(ctx context.Context) { a.ctx = context.WithValue(ctx, uclInstKey, a.uclInst) } func (a *App) LoadCurrentBuffer() (string, error) { return a.store.LoadBuffer() } func (a *App) SaveCurrentBuffer(buffer string) error { return a.store.SaveBuffer(buffer) } func (a *App) ListProcessors() (resp []ListProcessorsResponse) { for k, v := range TextFilters { resp = append(resp, ListProcessorsResponse{Name: k, Label: v.Label}) } sort.Slice(resp, func(i, j int) bool { return resp[i].Label < resp[j].Label }) return resp } func (a *App) ProcessText(req ProcessTextRequest) { filter, ok := TextFilters[req.Action] if !ok { log.Printf("Unknown filter: [%s]", req.Action) return } switch { case filter.Analyze != nil: inBfr := strings.Builder{} for _, span := range req.Input { if inBfr.Len() > 0 { inBfr.WriteString("\n") } inBfr.WriteString(span.Text) } msg, err := filter.Analyze(a.ctx, inBfr.String()) if err != nil { runtime.EventsEmit(a.ctx, "set-statusbar-message", SetStatusbarMessage{ Message: fmt.Sprintf("Error running analysis: %v", err.Error()), Error: true, }) return } runtime.EventsEmit(a.ctx, "set-statusbar-message", SetStatusbarMessage{ Message: msg, }) case filter.Filter != nil: resp, err := moslice.MapWithError(req.Input, func(span TextSpan) (TextSpan, error) { outRes, err := filter.Filter(a.ctx, span.Text) if err != nil { return TextSpan{}, err } return TextSpan{ Text: outRes.Output, Pos: span.Pos, Len: span.Len, Append: outRes.Append, }, nil }) if err != nil { runtime.EventsEmit(a.ctx, "set-statusbar-message", SetStatusbarMessage{ Message: fmt.Sprintf("Error running filter: %v", err.Error()), Error: true, }) return } runtime.EventsEmit(a.ctx, "process-text-response", ProcessTextResponse{ Output: resp, }) } }