From d22ff4509260f9f05cc736b447ed28f6ea5660d7 Mon Sep 17 00:00:00 2001 From: Erik Winter Date: Fri, 26 Apr 2024 15:10:38 +0200 Subject: [PATCH] full loop with backend and gui state --- desktop-client/backend/backend.go | 63 +++++++++++++++++++++++-------- desktop-client/backend/command.go | 3 +- desktop-client/backend/state.go | 16 ++++---- desktop-client/gui/gui.go | 42 ++++++++++++++++----- desktop-client/gui/state.go | 19 ++++++++++ desktop-client/main.go | 24 +++++++++++- 6 files changed, 130 insertions(+), 37 deletions(-) create mode 100644 desktop-client/gui/state.go diff --git a/desktop-client/backend/backend.go b/desktop-client/backend/backend.go index 813a2c0..6c4bd10 100644 --- a/desktop-client/backend/backend.go +++ b/desktop-client/backend/backend.go @@ -1,49 +1,80 @@ package backend -import "strings" +import ( + "fmt" + + "code.ewintr.nl/emdb/client" + "code.ewintr.nl/emdb/storage" +) type Backend struct { - s *State - c chan Command - log []string + s *State + in chan Command + out chan State + logLines []string + movieRepo *storage.MovieRepository + tmdb *client.TMDB } -func NewBackend() *Backend { +func NewBackend(movieRepo *storage.MovieRepository, tmdb *client.TMDB) *Backend { b := &Backend{ - s: NewState(), - c: make(chan Command), - log: make([]string, 0), + s: NewState(), + in: make(chan Command), + out: make(chan State), + logLines: make([]string, 0), + movieRepo: movieRepo, + tmdb: tmdb, } go b.Run() + b.in <- Command{Name: CommandRefreshWatched} + return b } -func (b *Backend) Out() *State { - return b.s +func (b *Backend) Out() chan State { + return b.out } func (b *Backend) In() chan Command { - return b.c + return b.in } func (b *Backend) Run() { - for cmd := range b.c { + for cmd := range b.in { switch cmd.Name { case CommandAdd: newName, ok := cmd.Args[ArgName] if ok { newNameStr, ok := newName.(string) if ok { - b.s.Watched.Append(newNameStr) + //b.s.Watched.Append(newNameStr) b.Log("Item added: " + newNameStr) } } + case CommandRefreshWatched: + b.RefreshWatched() + default: + b.Error(fmt.Errorf("unknown command: %s", cmd.Name)) } + + b.out <- *b.s } } -func (b *Backend) Log(msg string) { - b.log = append(b.log, msg) - b.s.Log.Set(strings.Join(b.log, "\n")) +func (b *Backend) RefreshWatched() { + watched, err := b.movieRepo.FindAll() + if err != nil { + b.Error(fmt.Errorf("could not refresh watched: %w", err)) + } + b.s.Watched = watched +} + +func (b *Backend) Error(err error) { + b.Log(fmt.Sprintf("ERROR: %s", err)) +} + +func (b *Backend) Log(msg string) { + b.logLines = append(b.logLines, msg) + b.s.Log = b.logLines } diff --git a/desktop-client/backend/command.go b/desktop-client/backend/command.go index d53ea1a..9b6d9f6 100644 --- a/desktop-client/backend/command.go +++ b/desktop-client/backend/command.go @@ -1,7 +1,8 @@ package backend const ( - CommandAdd = "add" + CommandAdd = "add" + CommandRefreshWatched = "refreshWatched" ArgName = "name" ) diff --git a/desktop-client/backend/state.go b/desktop-client/backend/state.go index 0e53f27..8e00680 100644 --- a/desktop-client/backend/state.go +++ b/desktop-client/backend/state.go @@ -1,19 +1,17 @@ package backend -import "fyne.io/fyne/v2/data/binding" +import ( + "code.ewintr.nl/emdb/storage" +) type State struct { - Watched binding.StringList - Log binding.String + Watched []storage.Movie + Log []string } func NewState() *State { - watched := binding.BindStringList( - &[]string{"Item 1", "Item 2", "Item 3"}, - ) - return &State{ - Watched: watched, - Log: binding.NewString(), + Watched: make([]storage.Movie, 0), + Log: make([]string, 0), } } diff --git a/desktop-client/gui/gui.go b/desktop-client/gui/gui.go index 974e3f5..44815f2 100644 --- a/desktop-client/gui/gui.go +++ b/desktop-client/gui/gui.go @@ -1,6 +1,8 @@ package gui import ( + "strings" + "code.ewintr.nl/emdb/desktop-client/backend" "fyne.io/fyne/v2" "fyne.io/fyne/v2/app" @@ -11,22 +13,24 @@ import ( ) type GUI struct { - a fyne.App - w fyne.Window - s *backend.State - c chan backend.Command + a fyne.App + w fyne.Window + in chan backend.State + out chan backend.Command + s *State } -func New(c chan backend.Command, s *backend.State) *GUI { +func New(out chan backend.Command, in chan backend.State) *GUI { a := app.New() w := a.NewWindow("EMDB") w.Resize(fyne.NewSize(800, 600)) g := &GUI{ - a: a, - w: w, - s: s, - c: c, + a: a, + w: w, + in: in, + out: out, + s: NewState(), } g.SetContent() @@ -35,9 +39,27 @@ func New(c chan backend.Command, s *backend.State) *GUI { } func (g *GUI) Run() { + go func() { + for s := range g.in { + g.Update(s) + } + }() g.w.ShowAndRun() } +func (g *GUI) Update(bs backend.State) { + // watched + watched := make([]string, 0, len(bs.Watched)) + for _, m := range bs.Watched { + watched = append(watched, m.Title) + } + g.s.Watched.Set(watched) + + // log + g.s.Log.Set(strings.Join(bs.Log, "\n")) + +} + func (g *GUI) SetContent() { label1 := widget.NewLabel("Label 1") label2 := widget.NewLabel("Label 2") @@ -49,7 +71,7 @@ func (g *GUI) SetContent() { form := container.New(layout.NewFormLayout(), label1, input, label2, value2) button := widget.NewButton("Save", func() { - g.c <- backend.Command{ + g.out <- backend.Command{ Name: backend.CommandAdd, Args: map[string]any{ backend.ArgName: input.Text, diff --git a/desktop-client/gui/state.go b/desktop-client/gui/state.go new file mode 100644 index 0000000..78ede7a --- /dev/null +++ b/desktop-client/gui/state.go @@ -0,0 +1,19 @@ +package gui + +import "fyne.io/fyne/v2/data/binding" + +type State struct { + Watched binding.StringList + Log binding.String +} + +func NewState() *State { + watched := binding.BindStringList( + &[]string{"Item 1", "Item 2", "Item 3"}, + ) + + return &State{ + Watched: watched, + Log: binding.NewString(), + } +} diff --git a/desktop-client/main.go b/desktop-client/main.go index 5ee5e1c..f93c331 100644 --- a/desktop-client/main.go +++ b/desktop-client/main.go @@ -1,12 +1,34 @@ package main import ( + "fmt" + "os" + + "code.ewintr.nl/emdb/client" "code.ewintr.nl/emdb/desktop-client/backend" "code.ewintr.nl/emdb/desktop-client/gui" + "code.ewintr.nl/emdb/storage" ) func main() { - b := backend.NewBackend() + tmdb, err := client.NewTMDB(os.Getenv("TMDB_API_KEY")) + if err != nil { + fmt.Println(err) + os.Exit(1) + } + dbHost := os.Getenv("EMDB_DB_HOST") + dbName := os.Getenv("EMDB_DB_NAME") + dbUser := os.Getenv("EMDB_DB_USER") + dbPassword := os.Getenv("EMDB_DB_PASSWORD") + pgConnStr := fmt.Sprintf("host=%s user=%s password=%s dbname=%s sslmode=disable", dbHost, dbUser, dbPassword, dbName) + dbPostgres, err := storage.NewPostgres(pgConnStr) + if err != nil { + fmt.Printf("could not create new postgres repo: %s", err.Error()) + os.Exit(1) + } + movieRepo := storage.NewMovieRepository(dbPostgres) + + b := backend.NewBackend(movieRepo, tmdb) g := gui.New(b.In(), b.Out()) g.Run() }