fix(tray-apps): SPA routing, TypeScript fixes, and deferred onboarding
- Add spaHandler() to both BugSETI and Core IDE for Angular client-side routing (AssetFileServerFS doesn't fallback to index.html) - Fix jellyfin.component.ts sanitizer initialization order (both apps) - Fix chat.component.ts Event/KeyboardEvent type mismatch - Defer onboarding window to ApplicationStarted event hook Co-Authored-By: Virgil <virgil@lethean.io>
This commit is contained in:
parent
4127509ccd
commit
f85aecb073
5 changed files with 58 additions and 12 deletions
|
|
@ -145,10 +145,12 @@ export class JellyfinComponent {
|
|||
apiKey = '';
|
||||
mediaSourceId = '';
|
||||
|
||||
safeWebUrl: SafeResourceUrl = this.sanitizer.bypassSecurityTrustResourceUrl('https://media.lthn.ai/web/index.html');
|
||||
safeWebUrl!: SafeResourceUrl;
|
||||
streamUrl = '';
|
||||
|
||||
constructor(private sanitizer: DomSanitizer) {}
|
||||
constructor(private sanitizer: DomSanitizer) {
|
||||
this.safeWebUrl = this.sanitizer.bypassSecurityTrustResourceUrl('https://media.lthn.ai/web/index.html');
|
||||
}
|
||||
|
||||
load(): void {
|
||||
const base = this.normalizeBase(this.serverUrl);
|
||||
|
|
|
|||
|
|
@ -12,12 +12,15 @@ import (
|
|||
"embed"
|
||||
"io/fs"
|
||||
"log"
|
||||
"net/http"
|
||||
"runtime"
|
||||
"strings"
|
||||
|
||||
"github.com/host-uk/core/cmd/bugseti/icons"
|
||||
"github.com/host-uk/core/internal/bugseti"
|
||||
"github.com/host-uk/core/internal/bugseti/updater"
|
||||
"github.com/wailsapp/wails/v3/pkg/application"
|
||||
"github.com/wailsapp/wails/v3/pkg/events"
|
||||
)
|
||||
|
||||
//go:embed all:frontend/dist/bugseti/browser
|
||||
|
|
@ -80,7 +83,7 @@ func main() {
|
|||
Description: "Distributed Bug Fixing - like SETI@home but for code",
|
||||
Services: services,
|
||||
Assets: application.AssetOptions{
|
||||
Handler: application.AssetFileServerFS(staticAssets),
|
||||
Handler: spaHandler(staticAssets),
|
||||
},
|
||||
Mac: application.MacOptions{
|
||||
ActivationPolicy: application.ActivationPolicyAccessory,
|
||||
|
|
@ -236,9 +239,31 @@ func setupSystemTray(app *application.App, fetcher *bugseti.FetcherService, queu
|
|||
|
||||
systray.SetMenu(trayMenu)
|
||||
|
||||
// Check if onboarding needed
|
||||
if !config.IsOnboarded() {
|
||||
onboardingWindow.Show()
|
||||
onboardingWindow.Focus()
|
||||
}
|
||||
// Check if onboarding needed (deferred until app is running)
|
||||
app.Event.RegisterApplicationEventHook(events.Common.ApplicationStarted, func(event *application.ApplicationEvent) {
|
||||
if !config.IsOnboarded() {
|
||||
onboardingWindow.Show()
|
||||
onboardingWindow.Focus()
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
// spaHandler wraps an fs.FS to serve static files with SPA fallback.
|
||||
// If the requested path doesn't match a real file, it serves index.html
|
||||
// so Angular's client-side router can handle the route.
|
||||
func spaHandler(fsys fs.FS) http.Handler {
|
||||
fileServer := http.FileServer(http.FS(fsys))
|
||||
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
path := strings.TrimPrefix(r.URL.Path, "/")
|
||||
if path == "" {
|
||||
path = "index.html"
|
||||
}
|
||||
|
||||
// Check if the file exists
|
||||
if _, err := fs.Stat(fsys, path); err != nil {
|
||||
// File doesn't exist — serve index.html for SPA routing
|
||||
r.URL.Path = "/"
|
||||
}
|
||||
fileServer.ServeHTTP(w, r)
|
||||
})
|
||||
}
|
||||
|
|
|
|||
|
|
@ -51,7 +51,7 @@ import { Subscription } from 'rxjs';
|
|||
<textarea
|
||||
class="form-textarea"
|
||||
[(ngModel)]="draft"
|
||||
(keydown.enter)="sendMessage($event)"
|
||||
(keydown.enter)="sendMessage($any($event))"
|
||||
placeholder="Type a message... (Enter to send)"
|
||||
rows="2"
|
||||
></textarea>
|
||||
|
|
|
|||
|
|
@ -133,10 +133,12 @@ export class JellyfinComponent {
|
|||
apiKey = '';
|
||||
mediaSourceId = '';
|
||||
|
||||
safeWebUrl: SafeResourceUrl = this.sanitizer.bypassSecurityTrustResourceUrl('https://media.lthn.ai/web/index.html');
|
||||
safeWebUrl!: SafeResourceUrl;
|
||||
streamUrl = '';
|
||||
|
||||
constructor(private sanitizer: DomSanitizer) {}
|
||||
constructor(private sanitizer: DomSanitizer) {
|
||||
this.safeWebUrl = this.sanitizer.bypassSecurityTrustResourceUrl('https://media.lthn.ai/web/index.html');
|
||||
}
|
||||
|
||||
load(): void {
|
||||
const base = this.normalizeBase(this.serverUrl);
|
||||
|
|
|
|||
|
|
@ -9,7 +9,9 @@ import (
|
|||
"embed"
|
||||
"io/fs"
|
||||
"log"
|
||||
"net/http"
|
||||
"runtime"
|
||||
"strings"
|
||||
|
||||
"github.com/host-uk/core/cmd/core-ide/icons"
|
||||
"github.com/host-uk/core/pkg/mcp/ide"
|
||||
|
|
@ -50,7 +52,7 @@ func main() {
|
|||
application.NewService(buildService),
|
||||
},
|
||||
Assets: application.AssetOptions{
|
||||
Handler: application.AssetFileServerFS(staticAssets),
|
||||
Handler: spaHandler(staticAssets),
|
||||
},
|
||||
Mac: application.MacOptions{
|
||||
ActivationPolicy: application.ActivationPolicyAccessory,
|
||||
|
|
@ -149,3 +151,18 @@ func setupSystemTray(app *application.App, ideService *IDEService) {
|
|||
|
||||
systray.SetMenu(trayMenu)
|
||||
}
|
||||
|
||||
// spaHandler wraps an fs.FS to serve static files with SPA fallback.
|
||||
func spaHandler(fsys fs.FS) http.Handler {
|
||||
fileServer := http.FileServer(http.FS(fsys))
|
||||
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
path := strings.TrimPrefix(r.URL.Path, "/")
|
||||
if path == "" {
|
||||
path = "index.html"
|
||||
}
|
||||
if _, err := fs.Stat(fsys, path); err != nil {
|
||||
r.URL.Path = "/"
|
||||
}
|
||||
fileServer.ServeHTTP(w, r)
|
||||
})
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue