Rework date and grace indicator
This commit is contained in:
parent
5ea00b755b
commit
b1c3b90c75
9 changed files with 53 additions and 29 deletions
3
.gitignore
vendored
3
.gitignore
vendored
|
@ -25,4 +25,5 @@ hibiscus-txt
|
||||||
|
|
||||||
# Testing data
|
# Testing data
|
||||||
data/
|
data/
|
||||||
config/log.txt
|
config/log.txt
|
||||||
|
config/dev-config.txt
|
11
CHANGELOG.md
11
CHANGELOG.md
|
@ -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`)
|
||||||
|
|
|
@ -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
10
api.go
|
@ -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)
|
||||||
|
}
|
||||||
|
|
12
files.go
12
files.go
|
@ -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
|
||||||
|
|
|
@ -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>
|
||||||
|
|
|
@ -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);
|
|
||||||
}
|
}
|
|
@ -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"))
|
||||||
|
|
1
serve.go
1
serve.go
|
@ -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
|
||||||
|
|
Loading…
Reference in a new issue