Rework date and grace indicator

This commit is contained in:
Andrew-71 2024-05-06 14:53:18 +03:00
parent 5ea00b755b
commit b1c3b90c75
9 changed files with 53 additions and 29 deletions

3
.gitignore vendored
View file

@ -25,4 +25,5 @@ hibiscus-txt
# Testing data # Testing data
data/ data/
config/log.txt config/log.txt
config/dev-config.txt

View file

@ -1,7 +1,16 @@
# Changelog # Changelog
This file keeps track of changes in more human-readable fashion This file keeps track of changes in more human-readable fashion
# 5 May 2024 ## 6 May 2024
* Grace period is now non-inclusive (so `4h` means the switch will happen right at `4:00`, not `4:01`)
* Added API method to check if grace period is active
* Made changes to date display on frontend
* The date is now updated every minute, instead of every hour.
* Now using the API to dynamically update the grace indicator
* I kinda dislike this change, since it complicates the structure a *bit*.
But I think it's fine.
## 5 May 2024
* Added this changelog * Added this changelog
* Added grace period (as per suggestions) * Added grace period (as per suggestions)
* Set in config like `grace_period=3h26m` (via Go's `time.ParseDuration`) * Set in config like `grace_period=3h26m` (via Go's `time.ParseDuration`)

View file

@ -96,4 +96,6 @@ GET /export - get .zip archive of entire data directory
GET /readme - get file contents for readme.txt in data dir's root GET /readme - get file contents for readme.txt in data dir's root
POST /readme - save request body into readme.txt POST /readme - save request body into readme.txt
GET /grace - "true" if grace period is active, otherwise "false"
``` ```

10
api.go
View file

@ -106,3 +106,13 @@ func PostNoteApi(w http.ResponseWriter, r *http.Request) {
} }
PostFile("notes/"+noteString, w, r) PostFile("notes/"+noteString, w, r)
} }
// GraceActiveApi returns "true" if grace period is active, and "false" otherwise
func GraceActiveApi(w http.ResponseWriter, r *http.Request) {
value := "false"
if GraceActive() {
value = "true"
}
HandleWrite(w.Write([]byte(value)))
w.WriteHeader(http.StatusOK)
}

View file

@ -77,16 +77,20 @@ func ListFiles(directory string) ([]string, error) {
// GraceActive returns whether the grace period (Cfg.GraceTime) is active // GraceActive returns whether the grace period (Cfg.GraceTime) is active
func GraceActive() bool { func GraceActive() bool {
return (60*time.Now().In(Cfg.Timezone).Hour() + time.Now().In(Cfg.Timezone).Minute()) <= int(Cfg.GraceTime.Minutes()) t := time.Now().In(Cfg.Timezone)
active := (60*t.Hour() + t.Minute()) < int(Cfg.GraceTime.Minutes())
if active {
slog.Debug("grace period active",
"time", 60*t.Hour()+t.Minute(),
"grace", Cfg.GraceTime.Minutes())
}
return active
} }
// TodayDate returns today's formatted date. It accounts for Config.GraceTime // TodayDate returns today's formatted date. It accounts for Config.GraceTime
func TodayDate() string { func TodayDate() string {
dateFormatted := time.Now().In(Cfg.Timezone).Format(time.DateOnly) dateFormatted := time.Now().In(Cfg.Timezone).Format(time.DateOnly)
if GraceActive() { if GraceActive() {
slog.Debug("grace period active",
"time", 60*time.Now().In(Cfg.Timezone).Hour()+time.Now().In(Cfg.Timezone).Minute(),
"grace", Cfg.GraceTime.Minutes())
dateFormatted = time.Now().In(Cfg.Timezone).AddDate(0, 0, -1).Format(time.DateOnly) dateFormatted = time.Now().In(Cfg.Timezone).AddDate(0, 0, -1).Format(time.DateOnly)
} }
return dateFormatted return dateFormatted

View file

@ -25,8 +25,7 @@
{{template "footer" .}} {{template "footer" .}}
<script defer> <script defer>
const langName="{{ translatableText "lang" }}"; const langName="{{ translatableText "lang" }}";
const graceActive={{ graceActive }}; beginTimeUpdater()
updateDate();beginDateUpdater()
</script> </script>
</body> </body>
</html> </html>

View file

@ -8,29 +8,27 @@ function formatDate(date) {
return dateFormat.format(date) return dateFormat.format(date)
} }
// Set today's date async function graceActive() {
function updateDate() { const response = await fetch("/api/grace");
let timeField = document.getElementById("today-date") const active = await response.text();
if (graceActive) { return active === "true"
let graceField = document.getElementById("grace")
graceField.hidden = false
}
timeField.innerText = formatDate(Date.now())
} }
// Start interval to update today's date every hour at 00:00 // Set today's date and grace status
function callEveryHour() { function updateTime() {
setInterval(updateDate, 1000 * 60 * 60); document.getElementById("today-date").innerText = formatDate(Date.now());
graceActive().then(v => document.getElementById("grace").hidden = !v)
}
// Start interval to update time at start of every minute
function callEveryMinute() {
setInterval(updateTime, 1000 * 60);
} }
// Begin above interval // Begin above interval
function beginDateUpdater() { function beginTimeUpdater() {
let nextDate = new Date(); const difference = (60 - new Date().getSeconds()) * 1000;
nextDate.setHours(nextDate.getHours() + 1); setTimeout(callEveryMinute, difference);
nextDate.setMinutes(0); setTimeout(updateTime, difference);
nextDate.setSeconds(0); updateTime();
const difference = nextDate - new Date();
setTimeout(callEveryHour, difference);
} }

View file

@ -25,7 +25,7 @@ type Entry struct {
type formatEntries func([]string) []Entry type formatEntries func([]string) []Entry
var templateFuncs = map[string]interface{}{"translatableText": TranslatableText, "graceActive": GraceActive} var templateFuncs = map[string]interface{}{"translatableText": TranslatableText}
var editTemplate = template.Must(template.New("").Funcs(templateFuncs).ParseFiles("./pages/base.html", "./pages/edit.html")) var editTemplate = template.Must(template.New("").Funcs(templateFuncs).ParseFiles("./pages/base.html", "./pages/edit.html"))
var viewTemplate = template.Must(template.New("").Funcs(templateFuncs).ParseFiles("./pages/base.html", "./pages/entry.html")) var viewTemplate = template.Must(template.New("").Funcs(templateFuncs).ParseFiles("./pages/base.html", "./pages/entry.html"))
var listTemplate = template.Must(template.New("").Funcs(templateFuncs).ParseFiles("./pages/base.html", "./pages/list.html")) var listTemplate = template.Must(template.New("").Funcs(templateFuncs).ParseFiles("./pages/base.html", "./pages/list.html"))

View file

@ -40,6 +40,7 @@ func Serve() {
apiRouter.Get("/today", GetTodayApi) apiRouter.Get("/today", GetTodayApi)
apiRouter.Post("/today", PostTodayApi) apiRouter.Post("/today", PostTodayApi)
apiRouter.Get("/export", GetExport) apiRouter.Get("/export", GetExport)
apiRouter.Get("/grace", GraceActiveApi)
r.Mount("/api", apiRouter) r.Mount("/api", apiRouter)
// Static files // Static files