mirror of
https://github.com/OliveTin/OliveTin
synced 2025-12-09 15:45:35 +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)
|
os.Exit(1)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
cfg.SetDir(path.Dir(viper.ConfigFileUsed()))
|
||||||
cfg.Sanitize()
|
cfg.Sanitize()
|
||||||
}
|
}
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
configDir := path.Dir(viper.ConfigFileUsed())
|
|
||||||
|
|
||||||
log.WithFields(log.Fields{
|
log.WithFields(log.Fields{
|
||||||
"configDir": configDir,
|
"configDir": cfg.GetDir(),
|
||||||
}).Infof("OliveTin started")
|
}).Infof("OliveTin started")
|
||||||
|
|
||||||
log.Debugf("Config: %+v", cfg)
|
log.Debugf("Config: %+v", cfg)
|
||||||
@@ -158,7 +157,7 @@ func main() {
|
|||||||
|
|
||||||
go entityfiles.SetupEntityFileWatchers(cfg)
|
go entityfiles.SetupEntityFileWatchers(cfg)
|
||||||
|
|
||||||
go updatecheck.StartUpdateChecker(version, commit, cfg, configDir)
|
go updatecheck.StartUpdateChecker(version, commit, cfg, cfg.GetDir())
|
||||||
|
|
||||||
go grpcapi.Start(cfg, executor)
|
go grpcapi.Start(cfg, executor)
|
||||||
|
|
||||||
|
|||||||
@@ -98,6 +98,8 @@ type Config struct {
|
|||||||
InsecureAllowDumpVars bool
|
InsecureAllowDumpVars bool
|
||||||
InsecureAllowDumpSos bool
|
InsecureAllowDumpSos bool
|
||||||
InsecureAllowDumpActionMap bool
|
InsecureAllowDumpActionMap bool
|
||||||
|
|
||||||
|
usedConfigDir string
|
||||||
}
|
}
|
||||||
|
|
||||||
type DashboardComponent struct {
|
type DashboardComponent struct {
|
||||||
|
|||||||
@@ -42,3 +42,11 @@ func (cfg *Config) FindAcl(aclTitle string) *AccessControlList {
|
|||||||
|
|
||||||
return nil
|
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"
|
"encoding/json"
|
||||||
// cors "github.com/OliveTin/OliveTin/internal/cors"
|
// cors "github.com/OliveTin/OliveTin/internal/cors"
|
||||||
log "github.com/sirupsen/logrus"
|
log "github.com/sirupsen/logrus"
|
||||||
|
"io/ioutil"
|
||||||
"net/http"
|
"net/http"
|
||||||
"os"
|
"os"
|
||||||
|
"path"
|
||||||
|
|
||||||
config "github.com/OliveTin/OliveTin/internal/config"
|
config "github.com/OliveTin/OliveTin/internal/config"
|
||||||
updatecheck "github.com/OliveTin/OliveTin/internal/updatecheck"
|
updatecheck "github.com/OliveTin/OliveTin/internal/updatecheck"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
customThemeCss []byte
|
||||||
|
customThemeCssRead = false
|
||||||
|
)
|
||||||
|
|
||||||
type webUISettings struct {
|
type webUISettings struct {
|
||||||
Rest string
|
Rest string
|
||||||
ThemeName string
|
|
||||||
ShowFooter bool
|
ShowFooter bool
|
||||||
ShowNavigation bool
|
ShowNavigation bool
|
||||||
ShowNewVersions bool
|
ShowNewVersions bool
|
||||||
@@ -52,10 +58,43 @@ func findWebuiDir() string {
|
|||||||
return "./webui" // Should not exist
|
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) {
|
func generateWebUISettings(w http.ResponseWriter, r *http.Request) {
|
||||||
jsonRet, _ := json.Marshal(webUISettings{
|
jsonRet, _ := json.Marshal(webUISettings{
|
||||||
Rest: cfg.ExternalRestAddress + "/api/",
|
Rest: cfg.ExternalRestAddress + "/api/",
|
||||||
ThemeName: cfg.ThemeName,
|
|
||||||
ShowFooter: cfg.ShowFooter,
|
ShowFooter: cfg.ShowFooter,
|
||||||
ShowNavigation: cfg.ShowNavigation,
|
ShowNavigation: cfg.ShowNavigation,
|
||||||
ShowNewVersions: cfg.ShowNewVersions,
|
ShowNewVersions: cfg.ShowNewVersions,
|
||||||
@@ -77,8 +116,12 @@ func startWebUIServer(cfg *config.Config) {
|
|||||||
"address": cfg.ListenAddressWebUI,
|
"address": cfg.ListenAddressWebUI,
|
||||||
}).Info("Starting WebUI server")
|
}).Info("Starting WebUI server")
|
||||||
|
|
||||||
|
setupCustomWebuiDir()
|
||||||
|
|
||||||
mux := http.NewServeMux()
|
mux := http.NewServeMux()
|
||||||
mux.Handle("/", http.FileServer(http.Dir(findWebuiDir())))
|
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)
|
mux.HandleFunc("/webUiSettings.json", generateWebUISettings)
|
||||||
|
|
||||||
srv := &http.Server{
|
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>
|
<title>OliveTin</title>
|
||||||
|
|
||||||
<link rel = "stylesheet" type = "text/css" href = "style.css" />
|
<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 = "shortcut icon" type = "image/png" href = "OliveTinLogo.png" />
|
||||||
|
|
||||||
<link rel = "apple-touch-icon" sizes="57x57" href="OliveTinLogo-57px.png" />
|
<link rel = "apple-touch-icon" sizes="57x57" href="OliveTinLogo-57px.png" />
|
||||||
|
|||||||
@@ -103,15 +103,6 @@ function processWebuiSettingsJson (settings) {
|
|||||||
|
|
||||||
window.restBaseUrl = settings.Rest
|
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
|
document.querySelector('#currentVersion').innerText = settings.CurrentVersion
|
||||||
|
|
||||||
if (settings.ShowNewVersions && settings.AvailableVersion !== 'none') {
|
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-node": "^11.1.0",
|
||||||
"eslint-plugin-promise": "^4.3.1",
|
"eslint-plugin-promise": "^4.3.1",
|
||||||
"parcel": "^2.11.0",
|
"parcel": "^2.11.0",
|
||||||
|
"parcel-resolver-ignore": "^2.2.0",
|
||||||
"stylelint": "^15.6.0",
|
"stylelint": "^15.6.0",
|
||||||
"stylelint-config-standard": "^33.0.0"
|
"stylelint-config-standard": "^33.0.0"
|
||||||
}
|
}
|
||||||
@@ -5132,6 +5133,21 @@
|
|||||||
"url": "https://opencollective.com/parcel"
|
"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": {
|
"node_modules/parent-module": {
|
||||||
"version": "1.0.1",
|
"version": "1.0.1",
|
||||||
"resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz",
|
"resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz",
|
||||||
@@ -9754,6 +9770,15 @@
|
|||||||
"get-port": "^4.2.0"
|
"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": {
|
"parent-module": {
|
||||||
"version": "1.0.1",
|
"version": "1.0.1",
|
||||||
"resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz",
|
"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-node": "^11.1.0",
|
||||||
"eslint-plugin-promise": "^4.3.1",
|
"eslint-plugin-promise": "^4.3.1",
|
||||||
"parcel": "^2.11.0",
|
"parcel": "^2.11.0",
|
||||||
|
"parcel-resolver-ignore": "^2.2.0",
|
||||||
"stylelint": "^15.6.0",
|
"stylelint": "^15.6.0",
|
||||||
"stylelint-config-standard": "^33.0.0"
|
"stylelint-config-standard": "^33.0.0"
|
||||||
},
|
},
|
||||||
@@ -18,5 +19,8 @@
|
|||||||
"test": "echo \"Error: no test specified\" && exit 1"
|
"test": "echo \"Error: no test specified\" && exit 1"
|
||||||
},
|
},
|
||||||
"author": "",
|
"author": "",
|
||||||
|
"parcelIgnore": [
|
||||||
|
"theme.css"
|
||||||
|
],
|
||||||
"license": "ISC"
|
"license": "ISC"
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user