reveil/ui/nojs.go

140 lines
3.6 KiB
Go

package ui
import (
"embed"
"fmt"
"html/template"
"net/http"
"strconv"
"strings"
"time"
"github.com/gin-gonic/gin"
"git.nemunai.re/nemunaire/reveil/config"
"git.nemunai.re/nemunaire/reveil/model"
"git.nemunai.re/nemunaire/reveil/player"
)
//go:embed nojs_templates/*
var nojs_tpl embed.FS
func DeclareNoJSRoutes(router *gin.Engine, cfg *config.Config, db *reveil.LevelDBStorage, resetTimer func()) {
templ := template.Must(template.New("").ParseFS(nojs_tpl, "nojs_templates/*.tmpl"))
router.SetHTMLTemplate(templ)
router.GET("/nojs.html", func(c *gin.Context) {
alarm, _, err := reveil.GetNextAlarm(cfg, db)
if err != nil {
c.HTML(http.StatusInternalServerError, "error.tmpl", gin.H{"errmsg": err.Error()})
return
}
nCycles := int(time.Until(*alarm) / (90 * time.Minute))
nDays := int(time.Until(*alarm) / (24 * time.Hour))
nMinutes := int((time.Until(*alarm) / time.Minute) % 90)
c.HTML(http.StatusOK, "index.tmpl", gin.H{
"nextAlarmDate": alarm.Format("Mon 2"),
"nextAlarmTime": alarm.Format("15:04"),
"sameDay": time.Now().Day() == alarm.Day(),
"nCycles": nCycles,
"nDays": nDays,
"nMinutes": nMinutes,
"isPlaying": player.CommonPlayer != nil,
})
})
router.POST("/nojs.html", func(c *gin.Context) {
var form struct {
Action string `form:"action"`
Time *string `form:"time"`
}
c.Bind(&form)
switch form.Action {
case "new":
if form.Time == nil {
c.HTML(http.StatusBadRequest, "error.tmpl", gin.H{"errmsg": "This time is invalid."})
return
}
alarm := time.Now()
if len(*form.Time) == 2 && (*form.Time)[1] == 'c' {
n, err := strconv.Atoi((*form.Time)[:1])
if err != nil {
c.HTML(http.StatusBadRequest, "error.tmpl", gin.H{"errmsg": fmt.Sprintf("This number of cycle is invalid: %s", err.Error())})
return
}
alarm = alarm.Add((time.Duration(90*n) + 10) * time.Minute)
} else {
tmp := strings.Split(*form.Time, ":")
if len(tmp) != 2 {
c.HTML(http.StatusBadRequest, "error.tmpl", gin.H{"errmsg": "This time is invalid."})
return
}
duration, err := time.ParseDuration(fmt.Sprintf("%sh%sm", tmp[0], tmp[1]))
if err != nil {
c.HTML(http.StatusBadRequest, "error.tmpl", gin.H{"errmsg": fmt.Sprintf("This time is invalid: %s", err.Error())})
return
}
alarm = alarm.Local().Truncate(24 * time.Hour)
alarm = alarm.Add(-time.Duration(alarm.Hour())*time.Hour + duration)
}
if time.Now().After(alarm) {
alarm = alarm.Add(24 * time.Hour)
}
if err := reveil.PutAlarmSingle(db, &reveil.AlarmSingle{
Time: alarm,
}); err != nil {
c.HTML(http.StatusInternalServerError, "error.tmpl", gin.H{"errmsg": err.Error()})
return
}
resetTimer()
case "cancel":
err := reveil.DropNextAlarm(cfg, db)
if err != nil {
c.HTML(http.StatusInternalServerError, "error.tmpl", gin.H{"errmsg": err.Error()})
return
}
resetTimer()
case "start":
if player.CommonPlayer == nil {
err := player.WakeUp(cfg, nil)
if err != nil {
c.HTML(http.StatusInternalServerError, "error.tmpl", gin.H{"errmsg": err.Error()})
return
}
} else {
c.HTML(http.StatusBadRequest, "error.tmpl", gin.H{"errmsg": "Player already running"})
return
}
case "nexttrack":
if player.CommonPlayer != nil {
player.CommonPlayer.NextTrack()
}
case "stop":
if player.CommonPlayer != nil {
err := player.CommonPlayer.Stop()
if err != nil {
c.HTML(http.StatusInternalServerError, "error.tmpl", gin.H{"errmsg": err.Error()})
return
}
}
}
c.Redirect(http.StatusFound, "/nojs.html")
})
}