mirror of
https://github.com/OliveTin/OliveTin
synced 2025-12-07 14:45:32 +00:00
custom-webui and faster theme loading (#262)
* feature: custom-webui and faster theme loading * feature: custom-webui and faster theme loading
This commit is contained in:
@@ -136,14 +136,13 @@ func reloadConfig() {
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
cfg.SetDir(path.Dir(viper.ConfigFileUsed()))
|
||||
cfg.Sanitize()
|
||||
}
|
||||
|
||||
func main() {
|
||||
configDir := path.Dir(viper.ConfigFileUsed())
|
||||
|
||||
log.WithFields(log.Fields{
|
||||
"configDir": configDir,
|
||||
"configDir": cfg.GetDir(),
|
||||
}).Infof("OliveTin started")
|
||||
|
||||
log.Debugf("Config: %+v", cfg)
|
||||
@@ -158,7 +157,7 @@ func main() {
|
||||
|
||||
go entityfiles.SetupEntityFileWatchers(cfg)
|
||||
|
||||
go updatecheck.StartUpdateChecker(version, commit, cfg, configDir)
|
||||
go updatecheck.StartUpdateChecker(version, commit, cfg, cfg.GetDir())
|
||||
|
||||
go grpcapi.Start(cfg, executor)
|
||||
|
||||
|
||||
@@ -98,6 +98,8 @@ type Config struct {
|
||||
InsecureAllowDumpVars bool
|
||||
InsecureAllowDumpSos bool
|
||||
InsecureAllowDumpActionMap bool
|
||||
|
||||
usedConfigDir string
|
||||
}
|
||||
|
||||
type DashboardComponent struct {
|
||||
|
||||
@@ -42,3 +42,11 @@ func (cfg *Config) FindAcl(aclTitle string) *AccessControlList {
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (cfg *Config) SetDir(dir string) {
|
||||
cfg.usedConfigDir = dir
|
||||
}
|
||||
|
||||
func (cfg *Config) GetDir() string {
|
||||
return cfg.usedConfigDir
|
||||
}
|
||||
|
||||
@@ -4,16 +4,22 @@ import (
|
||||
"encoding/json"
|
||||
// cors "github.com/OliveTin/OliveTin/internal/cors"
|
||||
log "github.com/sirupsen/logrus"
|
||||
"io/ioutil"
|
||||
"net/http"
|
||||
"os"
|
||||
"path"
|
||||
|
||||
config "github.com/OliveTin/OliveTin/internal/config"
|
||||
updatecheck "github.com/OliveTin/OliveTin/internal/updatecheck"
|
||||
)
|
||||
|
||||
var (
|
||||
customThemeCss []byte
|
||||
customThemeCssRead = false
|
||||
)
|
||||
|
||||
type webUISettings struct {
|
||||
Rest string
|
||||
ThemeName string
|
||||
ShowFooter bool
|
||||
ShowNavigation bool
|
||||
ShowNewVersions bool
|
||||
@@ -52,10 +58,43 @@ func findWebuiDir() string {
|
||||
return "./webui" // Should not exist
|
||||
}
|
||||
|
||||
func findCustomWebuiDir() string {
|
||||
dir := path.Join(cfg.GetDir(), "custom-webui")
|
||||
|
||||
return dir
|
||||
}
|
||||
|
||||
func setupCustomWebuiDir() {
|
||||
dir := findCustomWebuiDir()
|
||||
|
||||
err := os.MkdirAll(path.Join(dir, "themes/"), 0775)
|
||||
|
||||
if err != nil {
|
||||
log.Warnf("Could not create themes directory: %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
func generateThemeCss(w http.ResponseWriter, r *http.Request) {
|
||||
themeCssFilename := path.Join(findCustomWebuiDir(), "themes", cfg.ThemeName, "theme.css")
|
||||
|
||||
if !customThemeCssRead {
|
||||
customThemeCssRead = true
|
||||
|
||||
if _, err := os.Stat(themeCssFilename); err == nil {
|
||||
customThemeCss, err = ioutil.ReadFile(themeCssFilename)
|
||||
} else {
|
||||
log.Debugf("Theme CSS not read: %v", err)
|
||||
customThemeCss = []byte("/* not found */")
|
||||
}
|
||||
}
|
||||
|
||||
w.Header().Add("Content-Type", "text/css")
|
||||
w.Write(customThemeCss)
|
||||
}
|
||||
|
||||
func generateWebUISettings(w http.ResponseWriter, r *http.Request) {
|
||||
jsonRet, _ := json.Marshal(webUISettings{
|
||||
Rest: cfg.ExternalRestAddress + "/api/",
|
||||
ThemeName: cfg.ThemeName,
|
||||
ShowFooter: cfg.ShowFooter,
|
||||
ShowNavigation: cfg.ShowNavigation,
|
||||
ShowNewVersions: cfg.ShowNewVersions,
|
||||
@@ -77,8 +116,12 @@ func startWebUIServer(cfg *config.Config) {
|
||||
"address": cfg.ListenAddressWebUI,
|
||||
}).Info("Starting WebUI server")
|
||||
|
||||
setupCustomWebuiDir()
|
||||
|
||||
mux := http.NewServeMux()
|
||||
mux.Handle("/", http.FileServer(http.Dir(findWebuiDir())))
|
||||
mux.Handle("/custom-webui/", http.FileServer(http.Dir(findCustomWebuiDir())))
|
||||
mux.HandleFunc("/theme.css", generateThemeCss)
|
||||
mux.HandleFunc("/webUiSettings.json", generateWebUISettings)
|
||||
|
||||
srv := &http.Server{
|
||||
|
||||
4
webui.dev/.parcelrc
Normal file
4
webui.dev/.parcelrc
Normal file
@@ -0,0 +1,4 @@
|
||||
{
|
||||
"extends": "@parcel/config-default",
|
||||
"resolvers": ["parcel-resolver-ignore", "..."]
|
||||
}
|
||||
@@ -8,6 +8,7 @@
|
||||
<title>OliveTin</title>
|
||||
|
||||
<link rel = "stylesheet" type = "text/css" href = "style.css" />
|
||||
<link rel = "stylesheet" type = "text/css" href = "theme.css" />
|
||||
<link rel = "shortcut icon" type = "image/png" href = "OliveTinLogo.png" />
|
||||
|
||||
<link rel = "apple-touch-icon" sizes="57x57" href="OliveTinLogo-57px.png" />
|
||||
|
||||
@@ -103,15 +103,6 @@ function processWebuiSettingsJson (settings) {
|
||||
|
||||
window.restBaseUrl = settings.Rest
|
||||
|
||||
if (settings.ThemeName) {
|
||||
const themeCss = document.createElement('link')
|
||||
themeCss.setAttribute('rel', 'stylesheet')
|
||||
themeCss.setAttribute('type', 'text/css')
|
||||
themeCss.setAttribute('href', '/themes/' + settings.ThemeName + '/theme.css')
|
||||
|
||||
document.head.appendChild(themeCss)
|
||||
}
|
||||
|
||||
document.querySelector('#currentVersion').innerText = settings.CurrentVersion
|
||||
|
||||
if (settings.ShowNewVersions && settings.AvailableVersion !== 'none') {
|
||||
|
||||
25
webui.dev/package-lock.json
generated
25
webui.dev/package-lock.json
generated
@@ -15,6 +15,7 @@
|
||||
"eslint-plugin-node": "^11.1.0",
|
||||
"eslint-plugin-promise": "^4.3.1",
|
||||
"parcel": "^2.11.0",
|
||||
"parcel-resolver-ignore": "^2.2.0",
|
||||
"stylelint": "^15.6.0",
|
||||
"stylelint-config-standard": "^33.0.0"
|
||||
}
|
||||
@@ -5132,6 +5133,21 @@
|
||||
"url": "https://opencollective.com/parcel"
|
||||
}
|
||||
},
|
||||
"node_modules/parcel-resolver-ignore": {
|
||||
"version": "2.2.0",
|
||||
"resolved": "https://registry.npmjs.org/parcel-resolver-ignore/-/parcel-resolver-ignore-2.2.0.tgz",
|
||||
"integrity": "sha512-srQwekxRIiKVvAf9ljoFTw3WCrZVOhOcxOgHsWJ6FBK4yCD/w+7eNHvqWgtACVwVGkjyU6eVcy9eN9m2+Co6GA==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"@parcel/plugin": "^2.10.3"
|
||||
},
|
||||
"engines": {
|
||||
"parcel": ">=2.9.0"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://ko-fi.com/vladimirmikulic"
|
||||
}
|
||||
},
|
||||
"node_modules/parent-module": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz",
|
||||
@@ -9754,6 +9770,15 @@
|
||||
"get-port": "^4.2.0"
|
||||
}
|
||||
},
|
||||
"parcel-resolver-ignore": {
|
||||
"version": "2.2.0",
|
||||
"resolved": "https://registry.npmjs.org/parcel-resolver-ignore/-/parcel-resolver-ignore-2.2.0.tgz",
|
||||
"integrity": "sha512-srQwekxRIiKVvAf9ljoFTw3WCrZVOhOcxOgHsWJ6FBK4yCD/w+7eNHvqWgtACVwVGkjyU6eVcy9eN9m2+Co6GA==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@parcel/plugin": "^2.10.3"
|
||||
}
|
||||
},
|
||||
"parent-module": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz",
|
||||
|
||||
@@ -11,6 +11,7 @@
|
||||
"eslint-plugin-node": "^11.1.0",
|
||||
"eslint-plugin-promise": "^4.3.1",
|
||||
"parcel": "^2.11.0",
|
||||
"parcel-resolver-ignore": "^2.2.0",
|
||||
"stylelint": "^15.6.0",
|
||||
"stylelint-config-standard": "^33.0.0"
|
||||
},
|
||||
@@ -18,5 +19,8 @@
|
||||
"test": "echo \"Error: no test specified\" && exit 1"
|
||||
},
|
||||
"author": "",
|
||||
"parcelIgnore": [
|
||||
"theme.css"
|
||||
],
|
||||
"license": "ISC"
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user