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") }) }