summaryrefslogtreecommitdiff
path: root/main.go
blob: 841f801bca5fdc7961f0392effa4ba736b70dc22 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
package main

import (
	"flag"
	"fmt"
	"os"
	"runtime"
	"runtime/pprof"
	"time"

	"fyne.io/fyne/v2"
	"fyne.io/fyne/v2/app"
	"fyne.io/fyne/v2/dialog"

	"github.com/shiv/assets"
	"github.com/shiv/internal/events"
	"github.com/shiv/internal/logger"
	"github.com/shiv/internal/plugin"
	"github.com/shiv/internal/proxy"
	"github.com/shiv/internal/store"
	"github.com/shiv/internal/ui"
)

func main() {
	verbose := flag.Bool("verbose", false, "enable verbose debug logging")
	profile := flag.Bool("profile", false, "enable memory profiling")
	flag.Parse()

	if *profile {
		go func() {
			for {
				time.Sleep(30 * time.Second)
				runtime.GC()
				f, err := os.Create("heap.prof")
				if err != nil {
					println("err:", err.Error())
					continue
				}
				pprof.WriteHeapProfile(f)
				f.Close()

				var m runtime.MemStats
				runtime.ReadMemStats(&m)
				println("heap:", m.HeapAlloc)
			}
		}()
	}
	logger.Init(*verbose)

	fyneApp := app.NewWithID("net.shivapp")
	fyneApp.SetIcon(fyne.NewStaticResource("logo.png", assets.Logo))

	var openProject func(string, fyne.Window)
	openProject = func(projectPath string, launchWin fyne.Window) {
		if projectPath == "" {
			fyneApp.Quit()
			return
		}

		projectStore, err := store.Open(projectPath)
		if err != nil {
			fmt.Fprintf(os.Stderr, "[shiv] fatal: %v\n", err)
			fyneApp.Quit()
			return
		}

		bus := events.NewBus()
		bus.Register(projectStore.Intercept)
		bus.Register(projectStore)

		prefs := fyneApp.Preferences()

		pluginsDir := prefs.StringWithFallback("plugins_dir", fyneApp.Storage().RootURI().Path()+"/plugins")
		engine, err := plugin.NewEngine(pluginsDir, projectStore, bus)
		if err != nil {
			logger.Error("plugin engine: %v", err)
		} else if engine != nil {
			bus.Register(engine)
		}

		proxyAddr := fmt.Sprintf("%s:%d",
			prefs.StringWithFallback("proxy_host", "127.0.0.1"),
			prefs.IntWithFallback("proxy_port", 9090),
		)
		proxyServer, err := proxy.New(proxyAddr, bus)
		if err != nil {
			fmt.Fprintf(os.Stderr, "[shiv] fatal: %v\n", err)
			projectStore.Close()
			fyneApp.Quit()
			return
		}

		if proxyServer.CA().Fresh() && launchWin != nil {
			go func() {
				msg, err := proxyServer.CA().InstallCA()
				fyne.Do(func() {
					if err != nil {
						dialog.ShowError(fmt.Errorf("CA install failed — import it manually from your system config dir:\n%v", err), launchWin)
					} else {
						dialog.ShowInformation("CA Installed", msg+"\n\nRestart your browser for changes to take effect.", launchWin)
					}
				})
			}()
		}

		if prefs.BoolWithFallback("proxy_enabled", true) {
			bus.EmitProxyRestart(events.ProxyRestartEvent{Addr: proxyAddr})
		}

		ui.ShowMainWindow(fyneApp, projectStore, bus, launchWin, func(newPath string) {
			bus.EmitProxyStop(events.ProxyStopEvent{})
			if engine != nil {
				engine.Close()
			}
			projectStore.Close()
			openProject(newPath, nil)
		})
	}

	ui.ShowLaunchScreen(fyneApp, openProject)

	fyneApp.Run()
}