-
-
Notifications
You must be signed in to change notification settings - Fork 9
/
main.go
131 lines (108 loc) · 3.34 KB
/
main.go
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
124
125
126
127
128
129
130
131
// Copyright 2021 the Paw Authors. All rights reserved.
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
package main
import (
"fmt"
"os"
"runtime"
"fyne.io/fyne/v2"
"fyne.io/fyne/v2/app"
"lucor.dev/paw/internal/agent"
"lucor.dev/paw/internal/browser"
"lucor.dev/paw/internal/cli"
"lucor.dev/paw/internal/icon"
"lucor.dev/paw/internal/paw"
"lucor.dev/paw/internal/ui"
)
// appType detects the application type from the command line arguments and the runtime
type appType struct {
args []string
}
// IsCLI returns true if the application is a CLI app
func (a *appType) IsCLI() bool {
return len(a.args) > 1 && a.args[1] == "cli"
}
// IsGUI returns true if the application is a GUI app
func (a *appType) IsGUI() bool {
return !a.IsCLI()
}
// IsMessageFromBrowserExtension returns true if the application is a message from the browser extension
func (a *appType) IsMessageFromBrowserExtension() bool {
return len(a.args) > 1 && browser.MessageFromExtension(a.args[1:])
}
// IsMobile returns true if the application is running on a mobile device
func (a *appType) IsMobile() bool {
return runtime.GOOS == "android" || runtime.GOOS == "ios"
}
// IsWindowsOS returns true if the application is running on Windows
func (a *appType) IsWindowsOS() bool {
return runtime.GOOS == "windows"
}
func main() {
at := &appType{args: os.Args}
// handle application start: CLI, GUI
if at.IsCLI() && at.IsMobile() {
fmt.Fprintln(os.Stderr, "CLI app is unsupported on this OS")
os.Exit(1)
}
if !at.IsCLI() && at.IsWindowsOS() {
// On Windows, to ship a single binary for GUI and CLI we need to build as
// "console binary" and detach the console when running as GUI
ui.DetachConsole()
}
fyneApp := app.NewWithID(ui.AppID)
fyneApp.SetIcon(icon.PawIcon)
s, err := makeStorage(at, fyneApp)
if err != nil {
fmt.Println(err)
os.Exit(1)
}
// Write the native manifests to support browser native messaging for the current OS
// TODO: this should be once at installation time
browser.WriteNativeManifests()
// Handle message from browser extension
if at.IsMessageFromBrowserExtension() {
browser.HandleNativeMessage(s)
return
}
if at.IsCLI() {
// Run the CLI app
cli.Run(os.Args, s)
return
}
// check for running instance looking at the health service
if ui.HealthServiceCheck(s.LockFilePath()) {
fmt.Fprintln(os.Stderr, "Paw GUI is already running")
os.Exit(1)
}
// start the health service
go ui.HealthService(s.LockFilePath())
// agent could be already running (e.g. from CLI)
// if not, start it
var agentType agent.Type
c, err := agent.NewClient(s.SocketAgentPath())
if err == nil {
agentType, _ = c.Type()
}
// start the GUI agent if not already running
if agentType.IsZero() {
go agent.Run(agent.NewGUI(), s.SocketAgentPath())
}
// create window and run the app
w := fyneApp.NewWindow(ui.AppTitle)
w.SetMaster()
w.Resize(fyne.NewSize(400, 600))
w.SetContent(ui.MakeApp(s, w))
w.ShowAndRun()
}
// makeStorage create the storage
func makeStorage(at *appType, fyneApp fyne.App) (paw.Storage, error) {
if at.IsMobile() {
// Mobile app returns the Fyne storage
return paw.NewFyneStorage(fyneApp.Storage())
}
// Otherwise returns the OS storage
return paw.NewOSStorage()
}