diff --git a/server/app/app.go b/server/app/app.go
index 25d9b66a5..749f7dd97 100644
--- a/server/app/app.go
+++ b/server/app/app.go
@@ -49,6 +49,7 @@ func (app *Router) routes() http.Handler {
})
// Serve UI app assets
+ r.Handle("/", ServeIndex(app.ds))
r.Handle("/*", http.StripPrefix(app.path, http.FileServer(assets.AssetFile())))
return r
diff --git a/server/app/serve_index.go b/server/app/serve_index.go
new file mode 100644
index 000000000..cd3a5a992
--- /dev/null
+++ b/server/app/serve_index.go
@@ -0,0 +1,43 @@
+package app
+
+import (
+ "encoding/json"
+ "html/template"
+ "io/ioutil"
+ "net/http"
+
+ "github.com/deluan/navidrome/assets"
+ "github.com/deluan/navidrome/log"
+ "github.com/deluan/navidrome/model"
+)
+
+// Injects the `firstTime` config in the `index.html` template
+func ServeIndex(ds model.DataStore) http.HandlerFunc {
+ return func(w http.ResponseWriter, r *http.Request) {
+ c, err := ds.User(r.Context()).CountAll()
+ firstTime := c == 0 && err == nil
+
+ t := template.New("initial state")
+ fs := assets.AssetFile()
+ indexHtml, err := fs.Open("index.html")
+ if err != nil {
+ log.Error(r, "Could not find `index.html` template", err)
+ }
+ indexStr, err := ioutil.ReadAll(indexHtml)
+ if err != nil {
+ log.Error(r, "Could not read from `index.html`", err)
+ }
+ t, _ = t.Parse(string(indexStr))
+ appConfig := map[string]interface{}{
+ "firstTime": firstTime,
+ }
+ j, _ := json.Marshal(appConfig)
+ data := map[string]interface{}{
+ "AppConfig": string(j),
+ }
+ err = t.Execute(w, data)
+ if err != nil {
+ log.Error(r, "Could not execute `index.html` template", err)
+ }
+ }
+}
diff --git a/ui/public/index.html b/ui/public/index.html
index 12d88a620..43d1a58fb 100644
--- a/ui/public/index.html
+++ b/ui/public/index.html
@@ -25,6 +25,9 @@
Learn how to configure a non-root public URL by running `npm run build`.
-->
Navidrome
+
diff --git a/ui/src/App.js b/ui/src/App.js
index 28de38f3d..e3f12e730 100644
--- a/ui/src/App.js
+++ b/ui/src/App.js
@@ -1,4 +1,4 @@
-import React, { useState } from 'react'
+import React from 'react'
import { Admin, resolveBrowserLocale, Resource } from 'react-admin'
import dataProvider from './dataProvider'
import authProvider from './authProvider'
@@ -19,48 +19,35 @@ const i18nProvider = polyglotI18nProvider(
resolveBrowserLocale()
)
-const App = () => (
-
- {(permissions) => [
- ,
- ,
- ,
- permissions === 'admin' ? : null,
-
- ]}
-
-)
+const App = () => {
+ try {
+ const appConfig = JSON.parse(window.__APP_CONFIG__)
-// TODO: This is a complicated way to force a first check for initial setup. A better way would be to send this info
-// set in the `window` object in the index.html
-const AppWrapper = () => {
- const [checked, setChecked] = useState(false)
+ // This flags to the login process that it should create the first account instead
+ if (appConfig.firstTime) {
+ localStorage.setItem('initialAccountCreation', 'true')
+ }
+ } catch (e) {}
- if (!checked) {
- dataProvider
- .getOne('keepalive', { id: new Date().getTime() })
- .then(() => setChecked(true))
- .catch((err) => {
- authProvider
- .checkError(err)
- .then(() => {
- setChecked(true)
- })
- .catch(() => {
- setChecked(true)
- })
- })
- return null
- }
- return
+ return (
+
+ {(permissions) => [
+ ,
+ ,
+ ,
+ permissions === 'admin' ? : null,
+
+ ]}
+
+ )
}
-export default AppWrapper
+export default App
diff --git a/ui/src/authProvider.js b/ui/src/authProvider.js
index 3a4e561b4..675faaa33 100644
--- a/ui/src/authProvider.js
+++ b/ui/src/authProvider.js
@@ -56,11 +56,7 @@ const authProvider = {
checkAuth: () =>
localStorage.getItem('token') ? Promise.resolve() : Promise.reject(),
- checkError: (error) => {
- const { status, message } = error
- if (message === 'no users created') {
- localStorage.setItem('initialAccountCreation', 'true')
- }
+ checkError: ({ status }) => {
if (status === 401 || status === 403) {
removeItems()
return Promise.reject()