package server import ( "io/fs" "net/http" "strings" "sync" "github.com/go-chi/chi/v5" "gitlab.com/wpetit/goweb/api" _ "embed" ) type App struct { ID string `json:"id"` Title map[string]string `json:"title"` Description map[string]string `json:"description"` Icon string `json:"icon"` FS fs.FS `json:"-"` Hidden bool `json:"hidden"` } func (s *Server) handleDefaultApp(w http.ResponseWriter, r *http.Request) { http.Redirect(w, r, "/apps/"+s.defaultApp+"/", http.StatusTemporaryRedirect) } func (s *Server) handleApps(w http.ResponseWriter, r *http.Request) { api.DataResponse(w, http.StatusOK, struct { DefaultApp string `json:"defaultApp"` Apps []App `json:"apps"` }{ DefaultApp: s.defaultApp, Apps: s.apps, }) } var ( indexedAppFilesystems map[string]fs.FS indexAppsOnce sync.Once ) func (s *Server) handleAppFilesystem(w http.ResponseWriter, r *http.Request) { indexAppsOnce.Do(func() { indexedAppFilesystems = make(map[string]fs.FS, len(s.apps)) for _, app := range s.apps { indexedAppFilesystems[app.ID] = app.FS } }) appID := chi.URLParam(r, "appID") fs, exists := indexedAppFilesystems[appID] if !exists { http.Error(w, http.StatusText(http.StatusNotFound), http.StatusNotFound) return } name := strings.TrimPrefix(r.URL.Path, "/apps/"+appID) http.ServeFileFS(w, r, fs, name) }