From 66f723924e0d2d895cfe274ed02bfc6834eb0582 Mon Sep 17 00:00:00 2001 From: Martin Date: Sun, 14 Aug 2022 16:19:06 +0200 Subject: [PATCH] Bugfix operation in "server/hybrid" modes go.embed asset handling in production build call the OnStartup() callback when running the null frontend structure the app_hybrid_server.go to follow the structure and code of app_production.go --- v2/internal/app/app_hybrid_server.go | 143 ++++-------------- v2/internal/frontend/desktop/null/frontend.go | 23 ++- v2/internal/frontend/hybrid/server.go | 2 +- 3 files changed, 48 insertions(+), 120 deletions(-) diff --git a/v2/internal/app/app_hybrid_server.go b/v2/internal/app/app_hybrid_server.go index a9a7b135ec6..f1880edcf7c 100644 --- a/v2/internal/app/app_hybrid_server.go +++ b/v2/internal/app/app_hybrid_server.go @@ -5,12 +5,7 @@ package app import ( "context" - "embed" "fmt" - iofs "io/fs" - "os" - "path/filepath" - "github.com/wailsapp/wails/v2/internal/binding" "github.com/wailsapp/wails/v2/internal/frontend" "github.com/wailsapp/wails/v2/internal/frontend/desktop" @@ -18,10 +13,8 @@ import ( "github.com/wailsapp/wails/v2/internal/frontend/dispatcher" "github.com/wailsapp/wails/v2/internal/frontend/hybrid" "github.com/wailsapp/wails/v2/internal/frontend/runtime" - "github.com/wailsapp/wails/v2/internal/fs" "github.com/wailsapp/wails/v2/internal/logger" "github.com/wailsapp/wails/v2/internal/menumanager" - "github.com/wailsapp/wails/v2/internal/project" "github.com/wailsapp/wails/v2/pkg/options" ) @@ -42,6 +35,10 @@ type App struct { ctx context.Context } +func (a *App) Shutdown() { + a.frontend.Quit() +} + func (a *App) Run() error { err := a.frontend.Run(a.ctx) if a.shutdownCallback != nil { @@ -50,75 +47,49 @@ func (a *App) Run() error { return err } -func (a *App) Shutdown() { - if a.shutdownCallback != nil { - a.shutdownCallback(a.ctx) - } - a.frontend.Quit() -} - // CreateApp creates the app! func CreateApp(appoptions *options.App) (*App, error) { - // Set up logger - myLogger := logger.New(appoptions.Logger) - myLogger.SetLogLevel(appoptions.LogLevel) + var err error - // If no assetdir has been defined, let's try to infer it from the project root and the asset FS. - assetdir, err := tryInferAssetDirFromFS(appoptions.Assets) - if err != nil { - return nil, err - } + ctx := context.Background() - host := "localhost" - port := int32(3112) + host, port := "localhost", int32(3112) if appoptions.Server != nil { host = appoptions.Server.Host port = appoptions.Server.Port } serverURI := fmt.Sprintf("%s:%d", host, port) - ctx := context.Background() ctx = context.WithValue(ctx, "starturl", serverURI) - - // This is to enable a backend server - // ctx = context.WithValue(ctx, "frontenddevserverurl", serverURI) - - myLogger.Info("Frontend available at '%s'", serverURI) - - // configure devserver ctx = context.WithValue(ctx, "devserver", fmt.Sprintf("%s:%d", host, port)) - // Let's override the assets to serve from on disk, if needed - absdir, err := filepath.Abs(assetdir) - if err != nil { - return nil, err - } - - myLogger.Info("Serving assets from disk: %s", absdir) - appoptions.Assets = os.DirFS(absdir) + // Merge default options + options.MergeDefaults(appoptions) - ctx = context.WithValue(ctx, "assetdir", assetdir) + debug := IsDebug() + ctx = context.WithValue(ctx, "debug", debug) - // Attach logger to context + // Set up logger + myLogger := logger.New(appoptions.Logger) + myLogger.Info("Frontend available at 'http://%s'", serverURI) + if IsDebug() { + myLogger.SetLogLevel(appoptions.LogLevel) + } else { + myLogger.SetLogLevel(appoptions.LogLevelProduction) + } ctx = context.WithValue(ctx, "logger", myLogger) - ctx = context.WithValue(ctx, "buildtype", "hybrid") - // Preflight checks + // Preflight Checks err = PreflightChecks(appoptions, myLogger) if err != nil { return nil, err } - // Merge default options - - options.MergeDefaults(appoptions) - - var menuManager *menumanager.Manager + // Create the menu manager + menuManager := menumanager.NewManager() // Process the application menu if appoptions.Menu != nil { - // Create the menu manager - menuManager = menumanager.NewManager() err = menuManager.SetApplicationMenu(appoptions.Menu) if err != nil { return nil, err @@ -128,13 +99,15 @@ func CreateApp(appoptions *options.App) (*App, error) { // Create binding exemptions - Ugly hack. There must be a better way bindingExemptions := []interface{}{appoptions.OnStartup, appoptions.OnShutdown, appoptions.OnDomReady} appBindings := binding.NewBindings(myLogger, appoptions.Bind, bindingExemptions) - - err = generateBindings(appBindings) - if err != nil { - return nil, err - } eventHandler := runtime.NewEvents(myLogger) ctx = context.WithValue(ctx, "events", eventHandler) + // Attach logger to context + if debug { + ctx = context.WithValue(ctx, "buildtype", "debug") + } else { + ctx = context.WithValue(ctx, "buildtype", "production") + } + messageDispatcher := dispatcher.NewDispatcher(ctx, myLogger, appBindings, eventHandler) appFrontend := hybrid.NewFrontend(ctx, appoptions, myLogger, appBindings, messageDispatcher) eventHandler.AddFrontend(appFrontend) @@ -146,64 +119,10 @@ func CreateApp(appoptions *options.App) (*App, error) { menuManager: menuManager, startupCallback: appoptions.OnStartup, shutdownCallback: appoptions.OnShutdown, + debug: debug, + options: appoptions, } - result.options = appoptions - return result, nil } - -func generateBindings(bindings *binding.Bindings) error { - - cwd, err := os.Getwd() - if err != nil { - return err - } - projectConfig, err := project.Load(cwd) - if err != nil { - return err - } - - targetDir := filepath.Join(projectConfig.WailsJSDir, "wailsjs", "go") - err = os.RemoveAll(targetDir) - if err != nil { - return err - } - _ = fs.MkDirs(targetDir) - - err = bindings.GenerateGoBindings(targetDir) - if err != nil { - return err - } - return nil -} - -func tryInferAssetDirFromFS(assets iofs.FS) (string, error) { - if _, isEmbedFs := assets.(embed.FS); !isEmbedFs { - // We only infer the assetdir for embed.FS assets - return "", nil - } - - path, err := fs.FindPathToFile(assets, "index.html") - if err != nil { - return "", err - } - - path, err = filepath.Abs(path) - if err != nil { - return "", err - } - - if _, err := os.Stat(filepath.Join(path, "index.html")); err != nil { - if os.IsNotExist(err) { - err = fmt.Errorf( - "inferred assetdir '%s' does not exist or does not contain an 'index.html' file, "+ - "please specify it with -assetdir or set it in wails.json", - path) - } - return "", err - } - - return path, nil -} diff --git a/v2/internal/frontend/desktop/null/frontend.go b/v2/internal/frontend/desktop/null/frontend.go index fe19907af1b..b09a56b26d5 100644 --- a/v2/internal/frontend/desktop/null/frontend.go +++ b/v2/internal/frontend/desktop/null/frontend.go @@ -11,14 +11,17 @@ import ( // Frontend implements an empty Frontend that simply waits until the context is done. type Frontend struct { // Context - ctx context.Context + ctx context.Context + frontendOptions *options.App + done bool } // NewFrontend returns an initialized Frontend -func NewFrontend(ctx context.Context) *Frontend { +func NewFrontend(ctx context.Context, appoptions *options.App) *Frontend { return &Frontend{ - ctx: ctx, + frontendOptions: appoptions, + ctx: ctx, } } @@ -73,19 +76,25 @@ func (f *Frontend) WindowSetDarkTheme() { } // Run waits until the context is done and then exits -func (f *Frontend) Run(ctx context.Context) error { +func (f *Frontend) Run(ctx context.Context) (err error) { + err = nil + go func() { + if f.frontendOptions.OnStartup != nil { + f.frontendOptions.OnStartup(f.ctx) + } + }() for { select { case <-ctx.Done(): - break + return default: time.Sleep(1 * time.Millisecond) } if f.done { - break + return } } - return nil + } // WindowCenter does nothing diff --git a/v2/internal/frontend/hybrid/server.go b/v2/internal/frontend/hybrid/server.go index cd83fbf98aa..f4df3bd1cc3 100644 --- a/v2/internal/frontend/hybrid/server.go +++ b/v2/internal/frontend/hybrid/server.go @@ -17,5 +17,5 @@ import ( // New returns a new Server frontend // A server Frontend implementation contains a devserver.Frontend wrapping a null.Frontend func NewFrontend(ctx context.Context, appoptions *options.App, logger *logger.Logger, appBindings *binding.Bindings, dispatcher frontend.Dispatcher) frontend.Frontend { - return devserver.NewFrontend(ctx, appoptions, logger, appBindings, dispatcher, nil, null.NewFrontend(ctx)) + return devserver.NewFrontend(ctx, appoptions, logger, appBindings, dispatcher, nil, null.NewFrontend(ctx, appoptions)) }