Improve config and add a theme

This commit is contained in:
Andrew-71 2024-05-08 15:56:11 +03:00
parent bfee129443
commit 7830ae3217
8 changed files with 79 additions and 30 deletions

View file

@ -1,6 +1,16 @@
# Changelog
This file keeps track of changes in more human-readable fashion
## v0.4.0
* Customisation changes
* Added `title` option to config
* Controls the text in the header, "🌺 Hibiscus.txt" by default
* Added a nice `lavender` theme :)
* No longer ensuring config.Theme ends up inside `/public`, unsure what to do in that regard
* Technical changes to config
* Now only *some* default values are saved to file when creating initial config.txt
* Spaces in config options are now supported (basically just for `title`)
## v0.3.0
* Added themes
* Picked theme is set by `theme` key in config. Default is ...`default`

View file

@ -39,7 +39,9 @@ config
Deleting notes is done by clearing contents and clicking "Save" - the app deletes empty files when saving.
### Config options:
Below are defaults of config.txt. The settings are defined in newline separated key=value pairs.
Below are available configuration options and their defaults.
The settings are defined as newline separated key=value pairs in config.txt.
If you do not provide an option in your config, it will be using the default.
Please don't include the bash-style "comments" in your actual config,
they are provided purely for demonstration only and **will break the config if present**.
```

View file

@ -16,13 +16,14 @@ import (
var ConfigFile = "config/config.txt"
type Config struct {
Username string `config:"username" type:"string"`
Password string `config:"password" type:"string"`
Port int `config:"port" type:"int"`
Timezone *time.Location `config:"timezone" type:"location"`
Username string `config:"username" type:"string" mandatory:"true"`
Password string `config:"password" type:"string" mandatory:"true"`
Port int `config:"port" type:"int" mandatory:"true"`
Timezone *time.Location `config:"timezone" type:"location" mandatory:"true"`
GraceTime time.Duration `config:"grace_period" type:"duration"`
Language string `config:"language" type:"string"`
Language string `config:"language" type:"string" mandatory:"true"`
Theme string `config:"theme" type:"string"`
Title string `config:"title" type:"string"`
LogToFile bool `config:"log_to_file" type:"bool"`
LogFile string `config:"log_file" type:"string"`
Scram bool `config:"enable_scram" type:"bool"`
@ -31,15 +32,35 @@ type Config struct {
TelegramChat string `config:"tg_chat" type:"string"`
}
var DefaultConfig = Config{
Username: "admin",
Password: "admin",
Port: 7101,
Timezone: time.Local,
GraceTime: 0,
Language: "en",
Theme: "default",
Title: "🌺 Hibiscus.txt",
LogToFile: false,
LogFile: "config/log.txt",
Scram: false,
TelegramToken: "",
TelegramChat: "",
}
// Save puts modified and mandatory config options into the config.txt file
func (c *Config) Save() error {
output := ""
v := reflect.ValueOf(*c)
vDefault := reflect.ValueOf(DefaultConfig)
typeOfS := v.Type()
for i := 0; i < v.NumField(); i++ {
key := typeOfS.Field(i).Tag.Get("config")
value := v.Field(i).Interface()
if value != "" {
mandatory := typeOfS.Field(i).Tag.Get("mandatory")
if (mandatory == "true") || (value != vDefault.Field(i).Interface()) { // Only save non-default values
output += fmt.Sprintf("%s=%v\n", key, value)
}
}
@ -70,7 +91,7 @@ func (c *Config) Reload() error {
options := map[string]string{}
scanner := bufio.NewScanner(file)
for scanner.Scan() {
entry := strings.Split(strings.Replace(scanner.Text(), " ", "", -1), "=")
entry := strings.Split(strings.Trim(scanner.Text(), " \t"), "=")
if len(entry) != 2 {
continue
}
@ -134,18 +155,8 @@ func (c *Config) Reload() error {
}
// ConfigInit loads config on startup
// Some defaults are declared here
func ConfigInit() Config {
cfg := Config{
Port: 7101,
Username: "admin",
Password: "admin",
Timezone: time.Local,
Language: "en",
Theme: "default",
LogFile: "config/log.txt",
GraceTime: 0,
}
cfg := DefaultConfig
err := cfg.Reload()
if err != nil {
log.Fatal(err)

View file

@ -8,14 +8,14 @@ import (
var infoTemplate = template.Must(template.New("").Funcs(templateFuncs).ParseFiles("./pages/base.html", "./pages/info.html"))
type HibiscusInfo struct {
type AppInfo struct {
Version string
SourceLink string
}
// Info contains app information
var Info = HibiscusInfo{
Version: "0.3.0",
var Info = AppInfo{
Version: "0.4.0",
SourceLink: "https://git.a71.su/Andrew71/hibiscus",
}

View file

@ -1,6 +1,6 @@
{{define "header"}}
<header>
<h1>🌺 Hibiscus.txt</h1>
<h1>{{ config.Title }}</h1>
<p>{{translatableText "time.date"}} <span id="today-date">a place</span> <span id="grace" hidden>({{ translatableText "time.grace" }})</span></p>
</header>
{{end}}
@ -14,7 +14,7 @@
<link rel="manifest" href="/public/manifest.json" />
<link rel="icon" type="image/x-icon" href="/public/favicon.ico">
<link rel="stylesheet" href="/public/main.css">
<link rel="stylesheet" href="/public/themes/{{ hibiscusTheme }}.css">
<link rel="stylesheet" href="/public/themes/{{ config.Theme }}.css">
<script src="/public/date.js"></script>
<title>Hibiscus.txt</title>
</head>
@ -35,6 +35,6 @@
{{define "footer"}}
<footer>
<p><a href="/">{{ translatableText "link.today" }}</a> | <a href="/day">{{ translatableText "link.days" }}</a> | <a href="/notes">{{ translatableText "link.notes" }}</a>
<span style="float:right;"><a class="no-accent" href="/info" title="{{ translatableText "link.info" }}">{{ hibiscusVersion }}</a></span></p>
<span style="float:right;"><a class="no-accent" href="/info" title="{{ translatableText "link.info" }}">v{{ info.Version }}</a></span></p>
</footer>
{{end}}

View file

@ -1,7 +1,7 @@
{{define "main"}}
<h2>{{ translatableText "title.info" }}</h2>
<ul>
<li>{{ translatableText "info.version" }} - {{ .Version }} (<a href="{{ .SourceLink }}">{{ translatableText "info.version.link" }}</a>)</li>
<li>{{ translatableText "info.version" }} - {{ info.Version }} (<a href="{{ .SourceLink }}">{{ translatableText "info.version.link" }}</a>)</li>
<li><a href="/api/export" download="hibiscus">{{ translatableText "info.export" }}</a></li>
<li><a href="/readme">{{ translatableText "info.readme" }}</a></li>
<li><a href="/api/reload">{{ translatableText "info.reload" }}</a></li>

View file

@ -0,0 +1,26 @@
/* Tell me a secret. */
:root {
/* Light theme */
--text-light: #3c3836;
--bg-light: #e6dffa; /* d4c7fb*/
--clickable-light: #9975f5;
--clickable-hover-light: #765bef;
--clickable-label-light: #e2d8ff;
--text-hover-light: #665c54;
--textarea-bg-light: #f3ecff;
--textarea-border-light: #282828;
/* Dark theme */
--text-dark: #e6dffa;
--bg-dark: #25252a;
--clickable-dark: #9975f5;
--clickable-hover-dark: #765bef;
--clickable-label-dark: #e2d8ff;
--text-hover-dark: #a5a5b9;
--textarea-bg-dark: #27272f;
--textarea-border-dark: #3c3836;
}

View file

@ -7,7 +7,6 @@ import (
"log/slog"
"net/http"
"os"
"path"
"strings"
"time"
)
@ -28,8 +27,9 @@ type formatEntries func([]string) []Entry
var templateFuncs = map[string]interface{}{
"translatableText": TranslatableText,
"hibiscusVersion": func() string { return "v" + Info.Version },
"hibiscusTheme": func() string { return path.Clean(Cfg.Theme) }}
"info": func() AppInfo { return Info },
"config": func() Config { return Cfg },
}
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"))
@ -216,7 +216,7 @@ func PostNote(w http.ResponseWriter, r *http.Request) {
// GetReadme calls GetEntry for readme.txt
func GetReadme(w http.ResponseWriter, r *http.Request) {
GetEntry(w, r, "readme", "readme", true)
GetEntry(w, r, "readme.txt", "readme", true)
}
// PostReadme saves contents of readme.txt file