gte/cmd/android-app/runner/runner.go

203 lines
4.2 KiB
Go
Raw Normal View History

2022-10-18 16:58:12 +02:00
package runner
import (
2022-10-23 12:45:21 +02:00
"encoding/json"
2022-10-18 16:58:12 +02:00
"fmt"
2022-10-23 12:45:21 +02:00
"io"
"sync"
2022-10-20 13:58:48 +02:00
"time"
2022-10-18 16:58:12 +02:00
"ewintr.nl/gte/cmd/android-app/component"
"ewintr.nl/gte/cmd/android-app/screen"
2022-10-23 12:45:21 +02:00
"ewintr.nl/gte/internal/task"
2022-10-18 16:58:12 +02:00
"fyne.io/fyne/v2"
2022-10-23 12:45:21 +02:00
"fyne.io/fyne/v2/storage"
2022-10-18 16:58:12 +02:00
)
var runnerLock = sync.Mutex{}
2022-10-18 16:58:12 +02:00
type Runner struct {
fyneApp fyne.App
fyneWindow fyne.Window
conf *component.Configuration
logger *component.Logger
tasks *component.Tasks
2022-10-20 08:50:52 +02:00
status string
2022-10-18 16:58:12 +02:00
requests chan interface{}
2022-10-20 08:50:52 +02:00
refresh chan bool
2022-10-23 14:08:19 +02:00
fileURI fyne.URI
2022-10-24 15:57:55 +02:00
screenSet *screen.ScreenSet
2022-10-18 16:58:12 +02:00
}
2022-10-23 14:08:19 +02:00
func NewRunner(conf *component.Configuration, fileURI fyne.URI, logger *component.Logger) *Runner {
2022-10-18 16:58:12 +02:00
return &Runner{
status: "init",
conf: conf,
logger: logger,
requests: make(chan interface{}),
2022-10-20 08:50:52 +02:00
refresh: make(chan bool),
2022-10-23 14:08:19 +02:00
fileURI: fileURI,
2022-10-18 16:58:12 +02:00
}
}
func (r *Runner) Init() fyne.CanvasObject {
2022-10-23 14:08:19 +02:00
stored, err := load(r.fileURI)
2022-10-18 16:58:12 +02:00
if err != nil {
r.logger.Log(err.Error())
}
2022-10-23 12:45:21 +02:00
r.logger.Log(fmt.Sprintf("loaded %d tasks from file", len(stored)))
r.tasks = component.NewTasks(r.conf, stored)
2022-10-18 16:58:12 +02:00
2022-10-24 15:57:55 +02:00
r.screenSet = screen.NewScreenSet(r.requests)
return r.screenSet.Content()
2022-10-18 16:58:12 +02:00
}
func (r *Runner) Run() {
2022-10-24 15:57:55 +02:00
go r.screenSet.Run()
2022-10-20 08:50:52 +02:00
go r.refresher()
2022-10-18 16:58:12 +02:00
go r.processRequest()
r.backgroundSync()
2022-10-18 16:58:12 +02:00
}
func (r *Runner) processRequest() {
for req := range r.requests {
switch v := req.(type) {
case screen.SaveConfigRequest:
2022-10-20 10:40:46 +02:00
r.status = "saving..."
r.refresh <- true
2022-10-18 16:58:12 +02:00
for k, val := range v.Fields {
r.conf.Set(k, val)
}
2022-10-24 15:57:55 +02:00
r.status = "config saved"
2022-10-23 16:46:37 +02:00
r.logger.Log("config saved")
2022-10-18 16:58:12 +02:00
case screen.SyncTasksRequest:
2022-10-20 08:50:52 +02:00
r.status = "syncing..."
r.refresh <- true
2022-10-23 16:46:37 +02:00
countDisp, countFetch, err := r.tasks.Sync()
2022-10-18 16:58:12 +02:00
if err != nil {
r.logger.Log(err.Error())
}
2022-10-23 16:46:37 +02:00
if countDisp > 0 || countFetch > 0 {
r.logger.Log(fmt.Sprintf("task sync: dispatched: %d, fetched: %d", countDisp, countFetch))
}
2022-10-24 15:57:55 +02:00
r.status = "synced"
2022-10-23 12:45:21 +02:00
all, err := r.tasks.All()
if err != nil {
r.logger.Log(err.Error())
break
}
2022-10-23 14:08:19 +02:00
if err := save(r.fileURI, all); err != nil {
2022-10-23 12:45:21 +02:00
r.logger.Log(err.Error())
break
}
2022-10-20 10:40:46 +02:00
case screen.MarkTaskDoneRequest:
2022-10-24 15:57:55 +02:00
r.status = "marking done..."
r.refresh <- true
2022-10-20 10:40:46 +02:00
if err := r.tasks.MarkDone(v.ID); err != nil {
r.logger.Log(err.Error())
}
2022-10-20 14:49:33 +02:00
r.logger.Log(fmt.Sprintf("marked task %q done", v.ID))
2022-10-24 15:57:55 +02:00
r.status = "marked done"
2022-10-31 09:18:36 +01:00
case screen.SaveNewTaskRequest:
r.status = "saving..."
r.refresh <- true
if err := r.tasks.Add(v.Fields); err != nil {
r.logger.Log(err.Error())
}
r.status = "saved"
r.refresh <- true
2022-10-31 15:59:58 +01:00
case screen.UpdateTaskRequest:
r.status = "saving..."
r.refresh <- true
if err := r.tasks.Update(v.ID, v.Due); err != nil {
r.logger.Log(err.Error())
}
r.logger.Log(fmt.Sprintf("updated due date task %q", v.ID))
r.status = "saved"
r.refresh <- true
2022-10-18 16:58:12 +02:00
default:
r.logger.Log("request unknown")
}
r.refresh <- true
2022-10-18 16:58:12 +02:00
}
}
2022-10-20 08:50:52 +02:00
func (r *Runner) refresher() {
for <-r.refresh {
2022-10-20 08:50:52 +02:00
tasks, err := r.tasks.Today()
if err != nil {
r.logger.Log(err.Error())
}
2022-10-20 10:40:46 +02:00
sTasks := []screen.Task{}
for id, action := range tasks {
sTasks = append(sTasks, screen.Task{
ID: id,
Action: action,
})
}
2022-10-20 08:50:52 +02:00
state := screen.State{
Status: r.status,
2022-10-20 10:40:46 +02:00
Tasks: sTasks,
2022-10-20 08:50:52 +02:00
Config: r.conf.Fields(),
Logs: r.logger.Lines(),
}
2022-10-24 15:57:55 +02:00
r.screenSet.Refresh(state)
2022-10-18 16:58:12 +02:00
}
}
2022-10-20 13:58:48 +02:00
func (r *Runner) backgroundSync() {
ticker := time.NewTicker(15 * time.Second)
2022-10-20 13:58:48 +02:00
for {
r.requests <- screen.SyncTasksRequest{}
<-ticker.C
2022-10-20 13:58:48 +02:00
}
}
2022-10-23 12:45:21 +02:00
2022-10-23 14:08:19 +02:00
func load(fu fyne.URI) ([]*task.Task, error) {
fr, err := storage.Reader(fu)
2022-10-23 12:45:21 +02:00
if err != nil {
return []*task.Task{}, err
}
defer fr.Close()
2022-10-23 14:08:19 +02:00
exists, err := storage.Exists(fu)
2022-10-23 12:45:21 +02:00
if !exists {
return []*task.Task{}, fmt.Errorf("uri does not exist")
}
if err != nil {
return []*task.Task{}, err
}
data, err := io.ReadAll(fr)
if err != nil {
return []*task.Task{}, err
}
storedTasks := []*task.Task{}
if err := json.Unmarshal(data, &storedTasks); err != nil {
return []*task.Task{}, err
}
return storedTasks, nil
}
2022-10-23 14:08:19 +02:00
func save(fu fyne.URI, tasks []*task.Task) error {
fw, err := storage.Writer(fu)
2022-10-23 12:45:21 +02:00
if err != nil {
return err
}
data, err := json.Marshal(tasks)
if err != nil {
return err
}
if _, err := fw.Write(data); err != nil {
return err
}
defer fw.Close()
return nil
}