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

1
.gitignore vendored
View file

@ -26,3 +26,4 @@ hibiscus-txt
# Testing data
data/
config/log.txt
config/dev-config.txt

View file

@ -1,7 +1,16 @@
# Changelog
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 grace period (as per suggestions)
* 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
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)
}
// 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
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
func TodayDate() string {
dateFormatted := time.Now().In(Cfg.Timezone).Format(time.DateOnly)
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)
}
return dateFormatted

View file

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

View file

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

View file

@ -25,7 +25,7 @@ type Entry struct {
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 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"))

View file

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