From f96b8a8266063e611284c99a84fdcec6af0d3726 Mon Sep 17 00:00:00 2001 From: Leon Mika Date: Mon, 26 Jan 2026 09:31:14 +1100 Subject: [PATCH] Added a store --- app.go | 13 ++++++- frontend/src/main.js | 2 ++ frontend/src/services.js | 36 ++++++++++++++++--- frontend/wailsjs/go/main/App.d.ts | 4 +++ frontend/wailsjs/go/main/App.js | 8 +++++ go.mod | 1 + go.sum | 2 ++ main.go | 38 +++++++++++++++++++-- store.go | 57 +++++++++++++++++++++++++++++++ 9 files changed, 154 insertions(+), 7 deletions(-) create mode 100644 store.go diff --git a/app.go b/app.go index 274a987..0cde11d 100644 --- a/app.go +++ b/app.go @@ -15,13 +15,14 @@ import ( // App struct type App struct { + store *Store uclInst *ucl.Inst ctx context.Context } // NewApp creates a new App application struct -func NewApp() *App { +func NewApp(store *Store) *App { uclInst := ucl.New( ucl.WithModule(builtins.CSV(nil)), ucl.WithModule(builtins.Fns()), @@ -34,6 +35,7 @@ func NewApp() *App { ucl.WithModule(builtins.Time()), ) return &App{ + store: store, uclInst: uclInst, } } @@ -44,6 +46,15 @@ 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 { + log.Printf("Saving buffer") + 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}) diff --git a/frontend/src/main.js b/frontend/src/main.js index 063030a..e25e044 100644 --- a/frontend/src/main.js +++ b/frontend/src/main.js @@ -9,6 +9,7 @@ import {multiCursorKeymap, commandPalette} from "./cmplugins.js"; import {StatusController} from "./controllers/status_controller.js"; import {CommandsController} from "./controllers/commands_controller.js"; +import {LogPrint, EventsOn} from "../wailsjs/runtime/runtime"; @@ -28,5 +29,6 @@ Stimulus.register("commands", CommandsController); Stimulus.register("status", StatusController); textProcessor.setCodeMirrorEditor(view); +textProcessor.loadCurrentBuffer().then(() => textProcessor.startAutoSaver()); view.focus(); \ No newline at end of file diff --git a/frontend/src/services.js b/frontend/src/services.js index 7a149f5..bb9e368 100644 --- a/frontend/src/services.js +++ b/frontend/src/services.js @@ -1,6 +1,14 @@ -import {ProcessText} from "../wailsjs/go/main/App"; +import { + ProcessText, + LoadCurrentBuffer, + SaveCurrentBuffer, +} from "../wailsjs/go/main/App"; class TextProcessor { + constructor() { + this._lastAutoSave = undefined; + } + setCodeMirrorEditor(editor) { this._editor = editor; window.runtime.EventsOn("process-text-response", (data) => { @@ -23,7 +31,7 @@ class TextProcessor { }); } - runTextCommand(command) { + async runTextCommand(command) { if (this._editor === undefined) { return; } @@ -46,12 +54,32 @@ class TextProcessor { })) } - ProcessText({ + await ProcessText({ action: command, input: inputs, }); + await this.saveBuffer(); + } + + async loadCurrentBuffer() { + let buffer = await LoadCurrentBuffer(); + this._editor.dispatch({ changes: { from: 0, to: this._editor.state.doc.length, insert: buffer } }); + this._lastAutoSave = buffer; + } + + startAutoSaver() { + setInterval(() => { + this.saveBuffer(); + }, 1000); + } + + async saveBuffer(force) { + let buffer = this._editor.state.doc.toString(); + if (force || (buffer !== this._lastAutoSave)) { + this._lastAutoSave = buffer; + await SaveCurrentBuffer(buffer); + } } } - export const textProcessor = new TextProcessor(); \ No newline at end of file diff --git a/frontend/wailsjs/go/main/App.d.ts b/frontend/wailsjs/go/main/App.d.ts index a381b11..45cbb46 100755 --- a/frontend/wailsjs/go/main/App.d.ts +++ b/frontend/wailsjs/go/main/App.d.ts @@ -4,4 +4,8 @@ import {main} from '../models'; export function ListProcessors():Promise>; +export function LoadCurrentBuffer():Promise; + export function ProcessText(arg1:main.ProcessTextRequest):Promise; + +export function SaveCurrentBuffer(arg1:string):Promise; diff --git a/frontend/wailsjs/go/main/App.js b/frontend/wailsjs/go/main/App.js index f39aa5b..a6ec05f 100755 --- a/frontend/wailsjs/go/main/App.js +++ b/frontend/wailsjs/go/main/App.js @@ -6,6 +6,14 @@ export function ListProcessors() { return window['go']['main']['App']['ListProcessors'](); } +export function LoadCurrentBuffer() { + return window['go']['main']['App']['LoadCurrentBuffer'](); +} + export function ProcessText(arg1) { return window['go']['main']['App']['ProcessText'](arg1); } + +export function SaveCurrentBuffer(arg1) { + return window['go']['main']['App']['SaveCurrentBuffer'](arg1); +} diff --git a/go.mod b/go.mod index 47a3602..1bb4fd7 100644 --- a/go.mod +++ b/go.mod @@ -3,6 +3,7 @@ module dequoter go 1.25 require ( + github.com/kirsle/configdir v0.0.0-20170128060238-e45d2f54772f github.com/wailsapp/wails/v2 v2.10.2 gopkg.in/yaml.v3 v3.0.1 lmika.dev/pkg/modash v0.1.0 diff --git a/go.sum b/go.sum index 7eee4e2..554a490 100644 --- a/go.sum +++ b/go.sum @@ -20,6 +20,8 @@ github.com/hexops/gotextdiff v1.0.3 h1:gitA9+qJrrTCsiCl7+kh75nPqQt1cx4ZkudSTLoUq github.com/hexops/gotextdiff v1.0.3/go.mod h1:pSWU5MAI3yDq+fZBTazCSJysOMbxWL1BSow5/V2vxeg= github.com/jchv/go-winloader v0.0.0-20210711035445-715c2860da7e h1:Q3+PugElBCf4PFpxhErSzU3/PY5sFL5Z6rfv4AbGAck= github.com/jchv/go-winloader v0.0.0-20210711035445-715c2860da7e/go.mod h1:alcuEEnZsY1WQsagKhZDsoPCRoOijYqhZvPwLG0kzVs= +github.com/kirsle/configdir v0.0.0-20170128060238-e45d2f54772f h1:dKccXx7xA56UNqOcFIbuqFjAWPVtP688j5QMgmo6OHU= +github.com/kirsle/configdir v0.0.0-20170128060238-e45d2f54772f/go.mod h1:4rEELDSfUAlBSyUjPG0JnaNGjf13JySHFeRdD/3dLP0= github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= github.com/labstack/echo/v4 v4.13.3 h1:pwhpCPrTl5qry5HRdM5FwdXnhXSLSY+WE+YQSeCaafY= diff --git a/main.go b/main.go index 9b49243..5fcbfca 100644 --- a/main.go +++ b/main.go @@ -2,21 +2,48 @@ package main import ( "embed" + "log" + "runtime" + + rt "github.com/wailsapp/wails/v2/pkg/runtime" "github.com/wailsapp/wails/v2" + "github.com/wailsapp/wails/v2/pkg/menu" + "github.com/wailsapp/wails/v2/pkg/menu/keys" "github.com/wailsapp/wails/v2/pkg/options" "github.com/wailsapp/wails/v2/pkg/options/assetserver" + "github.com/wailsapp/wails/v2/pkg/options/mac" ) //go:embed all:frontend/dist var assets embed.FS func main() { + store, err := NewStore() + if err != nil { + log.Fatal(err) + } + // Create an instance of the app structure - app := NewApp() + app := NewApp(store) + + appMenu := menu.NewMenu() + if runtime.GOOS == "darwin" { + appMenu.Append(menu.AppMenu()) // On macOS platform, this must be done right after `NewMenu()` + } + fileMenu := appMenu.AddSubmenu("File") + fileMenu.AddText("Quit", keys.CmdOrCtrl("q"), func(_ *menu.CallbackData) { + // `rt` is an alias of "github.com/wailsapp/wails/v2/pkg/runtime" to prevent collision with standard package + rt.Quit(app.ctx) + }) + + if runtime.GOOS == "darwin" { + appMenu.Append(menu.EditMenu()) + appMenu.Append(menu.WindowMenu()) + } // Create application with options - err := wails.Run(&options.App{ + err = wails.Run(&options.App{ Title: "Dequoter", Width: 800, Height: 600, @@ -28,6 +55,13 @@ func main() { Bind: []interface{}{ app, }, + Menu: appMenu, + Mac: &mac.Options{ + About: &mac.AboutInfo{ + Title: "Dequoter", + Message: "© 2025 Leon Mika", + }, + }, }) if err != nil { diff --git a/store.go b/store.go new file mode 100644 index 0000000..59badb8 --- /dev/null +++ b/store.go @@ -0,0 +1,57 @@ +package main + +import ( + "errors" + "fmt" + "os" + "path/filepath" + + "github.com/kirsle/configdir" +) + +const ( + packageName = "dev.lmika.dequoter" +) + +type Store struct { + storeDir string + currentBufferIndex int +} + +func NewStore() (*Store, error) { + cfgDir := configdir.LocalConfig(packageName) + if err := os.MkdirAll(cfgDir, 0755); err != nil { + return nil, err + } + + return &Store{ + storeDir: cfgDir, + currentBufferIndex: 0, + }, nil +} + +func (s *Store) LoadBuffer() (string, error) { + return s.loadBuffer(fmt.Sprintf("%02d", s.currentBufferIndex)) +} + +func (s *Store) SaveBuffer(buffer string) error { + return s.saveBuffer(fmt.Sprintf("%02d", s.currentBufferIndex), buffer) +} + +func (s *Store) loadBuffer(name string) (string, error) { + bfrFilename := filepath.Join(s.storeDir, fmt.Sprintf("%s.buffer", name)) + bts, err := os.ReadFile(bfrFilename) + if err != nil { + if errors.Is(err, os.ErrNotExist) { + return "", nil + } + return "", err + } + + return string(bts), err +} + +func (s *Store) saveBuffer(name string, buffer string) error { + bfrFilename := filepath.Join(s.storeDir, fmt.Sprintf("%s.buffer", name)) + return os.WriteFile(bfrFilename, []byte(buffer), 0644) +}