Skip to content

Commit 60ffe0d

Browse files
authored
[client] UI Refactor Icon Paths (#3420)
[client] UI Refactor Icon Paths (#3420)
1 parent bcc5824 commit 60ffe0d

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

46 files changed

+158
-122
lines changed

.github/workflows/release.yml

+2-2
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,7 @@ jobs:
7171
- name: Install goversioninfo
7272
run: go install github.com/josephspurrier/goversioninfo/cmd/goversioninfo@233067e
7373
- name: Generate windows syso amd64
74-
run: goversioninfo -icon client/ui/netbird.ico -manifest client/manifest.xml -product-name ${{ env.PRODUCT_NAME }} -copyright "${{ env.COPYRIGHT }}" -ver-major ${{ steps.semver_parser.outputs.major }} -ver-minor ${{ steps.semver_parser.outputs.minor }} -ver-patch ${{ steps.semver_parser.outputs.patch }} -ver-build 0 -file-version ${{ steps.semver_parser.outputs.fullversion }}.0 -product-version ${{ steps.semver_parser.outputs.fullversion }}.0 -o client/resources_windows_amd64.syso
74+
run: goversioninfo -icon client/ui/assets/netbird.ico -manifest client/manifest.xml -product-name ${{ env.PRODUCT_NAME }} -copyright "${{ env.COPYRIGHT }}" -ver-major ${{ steps.semver_parser.outputs.major }} -ver-minor ${{ steps.semver_parser.outputs.minor }} -ver-patch ${{ steps.semver_parser.outputs.patch }} -ver-build 0 -file-version ${{ steps.semver_parser.outputs.fullversion }}.0 -product-version ${{ steps.semver_parser.outputs.fullversion }}.0 -o client/resources_windows_amd64.syso
7575
- name: Run GoReleaser
7676
uses: goreleaser/goreleaser-action@v4
7777
with:
@@ -150,7 +150,7 @@ jobs:
150150
- name: Install goversioninfo
151151
run: go install github.com/josephspurrier/goversioninfo/cmd/goversioninfo@233067e
152152
- name: Generate windows syso amd64
153-
run: goversioninfo -64 -icon client/ui/netbird.ico -manifest client/ui/manifest.xml -product-name ${{ env.PRODUCT_NAME }}-"UI" -copyright "${{ env.COPYRIGHT }}" -ver-major ${{ steps.semver_parser.outputs.major }} -ver-minor ${{ steps.semver_parser.outputs.minor }} -ver-patch ${{ steps.semver_parser.outputs.patch }} -ver-build 0 -file-version ${{ steps.semver_parser.outputs.fullversion }}.0 -product-version ${{ steps.semver_parser.outputs.fullversion }}.0 -o client/ui/resources_windows_amd64.syso
153+
run: goversioninfo -64 -icon client/ui/assets/netbird.ico -manifest client/ui/manifest.xml -product-name ${{ env.PRODUCT_NAME }}-"UI" -copyright "${{ env.COPYRIGHT }}" -ver-major ${{ steps.semver_parser.outputs.major }} -ver-minor ${{ steps.semver_parser.outputs.minor }} -ver-patch ${{ steps.semver_parser.outputs.patch }} -ver-build 0 -file-version ${{ steps.semver_parser.outputs.fullversion }}.0 -product-version ${{ steps.semver_parser.outputs.fullversion }}.0 -o client/ui/resources_windows_amd64.syso
154154

155155
- name: Run GoReleaser
156156
uses: goreleaser/goreleaser-action@v4

.goreleaser_ui.yaml

+4-4
Original file line numberDiff line numberDiff line change
@@ -53,9 +53,9 @@ nfpms:
5353
scripts:
5454
postinstall: "release_files/ui-post-install.sh"
5555
contents:
56-
- src: client/ui/netbird.desktop
56+
- src: client/ui/build/netbird.desktop
5757
dst: /usr/share/applications/netbird.desktop
58-
- src: client/ui/netbird.png
58+
- src: client/ui/assets/netbird.png
5959
dst: /usr/share/pixmaps/netbird.png
6060
dependencies:
6161
- netbird
@@ -72,9 +72,9 @@ nfpms:
7272
scripts:
7373
postinstall: "release_files/ui-post-install.sh"
7474
contents:
75-
- src: client/ui/netbird.desktop
75+
- src: client/ui/build/netbird.desktop
7676
dst: /usr/share/applications/netbird.desktop
77-
- src: client/ui/netbird.png
77+
- src: client/ui/assets/netbird.png
7878
dst: /usr/share/pixmaps/netbird.png
7979
dependencies:
8080
- netbird

client/installer.nsis

+2-2
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,8 @@
66
!define DESCRIPTION "A WireGuard®-based mesh network that connects your devices into a single private network"
77
!define INSTALLER_NAME "netbird-installer.exe"
88
!define MAIN_APP_EXE "Netbird"
9-
!define ICON "ui\\netbird.ico"
10-
!define BANNER "ui\\banner.bmp"
9+
!define ICON "ui\\assets\\netbird.ico"
10+
!define BANNER "ui\\build\\banner.bmp"
1111
!define LICENSE_DATA "..\\LICENSE"
1212

1313
!define INSTALL_DIR "$PROGRAMFILES64\${APP_NAME}"

client/netbird.wxs

+1-1
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,7 @@
7171
</InstallExecuteSequence>
7272

7373
<!-- Icons -->
74-
<Icon Id="NetbirdIcon" SourceFile=".\client\ui\netbird.ico" />
74+
<Icon Id="NetbirdIcon" SourceFile=".\client\ui\assets\netbird.ico" />
7575
<Property Id="ARPPRODUCTICON" Value="NetbirdIcon" />
7676

7777
</Package>

client/resources.rc

+1-1
Original file line numberDiff line numberDiff line change
@@ -5,5 +5,5 @@
55
#define STRINGIZE(x) #x
66
#define EXPAND(x) STRINGIZE(x)
77
CREATEPROCESS_MANIFEST_RESOURCE_ID RT_MANIFEST manifest.xml
8-
7 ICON ui/netbird.ico
8+
7 ICON ui/assets/netbird.ico
99
wintun.dll RCDATA wintun.dll
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.

client/ui/client_ui.go

+103-82
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,9 @@ import (
3535
"github.com/netbirdio/netbird/client/proto"
3636
"github.com/netbirdio/netbird/client/ui/desktop"
3737
"github.com/netbirdio/netbird/client/ui/event"
38+
"github.com/netbirdio/netbird/client/ui/process"
3839
"github.com/netbirdio/netbird/util"
40+
3941
"github.com/netbirdio/netbird/version"
4042
)
4143

@@ -44,94 +46,125 @@ const (
4446
failFastTimeout = time.Second
4547
)
4648

49+
const (
50+
censoredPreSharedKey = "**********"
51+
)
52+
4753
func main() {
48-
var daemonAddr string
54+
daemonAddr, showSettings, showNetworks, errorMsg, saveLogsInFile := parseFlags()
55+
56+
// Initialize file logging if needed.
57+
if saveLogsInFile {
58+
if err := initLogFile(); err != nil {
59+
log.Errorf("error while initializing log: %v", err)
60+
return
61+
}
62+
}
63+
64+
// Create the Fyne application.
65+
a := app.NewWithID("NetBird")
66+
a.SetIcon(fyne.NewStaticResource("netbird", iconDisconnected))
67+
68+
// Show error message window if needed.
69+
if errorMsg != "" {
70+
showErrorMessage(errorMsg)
71+
return
72+
}
73+
74+
// Create the service client (this also builds the settings or networks UI if requested).
75+
client := newServiceClient(daemonAddr, a, showSettings, showNetworks)
4976

77+
// Watch for theme/settings changes to update the icon.
78+
go watchSettingsChanges(a, client)
79+
80+
// Run in window mode if any UI flag was set.
81+
if showSettings || showNetworks {
82+
a.Run()
83+
return
84+
}
85+
86+
// Check for another running process.
87+
running, err := process.IsAnotherProcessRunning()
88+
if err != nil {
89+
log.Errorf("error while checking process: %v", err)
90+
return
91+
}
92+
if running {
93+
log.Warn("another process is running")
94+
return
95+
}
96+
97+
client.setDefaultFonts()
98+
systray.Run(client.onTrayReady, client.onTrayExit)
99+
}
100+
101+
// parseFlags reads and returns all needed command-line flags.
102+
func parseFlags() (daemonAddr string, showSettings, showNetworks bool, errorMsg string, saveLogsInFile bool) {
50103
defaultDaemonAddr := "unix:///var/run/netbird.sock"
51104
if runtime.GOOS == "windows" {
52105
defaultDaemonAddr = "tcp://127.0.0.1:41731"
53106
}
54-
55-
flag.StringVar(
56-
&daemonAddr, "daemon-addr",
57-
defaultDaemonAddr,
58-
"Daemon service address to serve CLI requests [unix|tcp]://[path|host:port]")
59-
60-
var showSettings bool
61-
flag.BoolVar(&showSettings, "settings", false, "run settings windows")
62-
var showRoutes bool
63-
flag.BoolVar(&showRoutes, "networks", false, "run networks windows")
64-
var errorMSG string
65-
flag.StringVar(&errorMSG, "error-msg", "", "displays a error message window")
107+
flag.StringVar(&daemonAddr, "daemon-addr", defaultDaemonAddr, "Daemon service address to serve CLI requests [unix|tcp]://[path|host:port]")
108+
flag.BoolVar(&showSettings, "settings", false, "run settings window")
109+
flag.BoolVar(&showNetworks, "networks", false, "run networks window")
110+
flag.StringVar(&errorMsg, "error-msg", "", "displays an error message window")
66111

67112
tmpDir := "/tmp"
68113
if runtime.GOOS == "windows" {
69114
tmpDir = os.TempDir()
70115
}
71-
72-
var saveLogsInFile bool
73116
flag.BoolVar(&saveLogsInFile, "use-log-file", false, fmt.Sprintf("save logs in a file: %s/netbird-ui-PID.log", tmpDir))
74-
75117
flag.Parse()
118+
return
119+
}
76120

77-
if saveLogsInFile {
78-
logFile := path.Join(tmpDir, fmt.Sprintf("netbird-ui-%d.log", os.Getpid()))
79-
err := util.InitLog("trace", logFile)
80-
if err != nil {
81-
log.Errorf("error while initializing log: %v", err)
82-
return
83-
}
84-
}
85-
86-
a := app.NewWithID("NetBird")
87-
a.SetIcon(fyne.NewStaticResource("netbird", iconDisconnected))
88-
89-
if errorMSG != "" {
90-
showErrorMSG(errorMSG)
91-
return
121+
// initLogFile initializes logging into a file.
122+
func initLogFile() error {
123+
tmpDir := "/tmp"
124+
if runtime.GOOS == "windows" {
125+
tmpDir = os.TempDir()
92126
}
127+
logFile := path.Join(tmpDir, fmt.Sprintf("netbird-ui-%d.log", os.Getpid()))
128+
return util.InitLog("trace", logFile)
129+
}
93130

94-
client := newServiceClient(daemonAddr, a, showSettings, showRoutes)
131+
// watchSettingsChanges listens for Fyne theme/settings changes and updates the client icon.
132+
func watchSettingsChanges(a fyne.App, client *serviceClient) {
95133
settingsChangeChan := make(chan fyne.Settings)
96134
a.Settings().AddChangeListener(settingsChangeChan)
97-
go func() {
98-
for range settingsChangeChan {
99-
client.updateIcon()
100-
}
101-
}()
102-
103-
if showSettings || showRoutes {
104-
a.Run()
105-
} else {
106-
running, err := isAnotherProcessRunning()
107-
if err != nil {
108-
log.Errorf("error while checking process: %v", err)
109-
}
110-
if running {
111-
log.Warn("another process is running")
112-
return
113-
}
114-
client.setDefaultFonts()
115-
systray.Run(client.onTrayReady, client.onTrayExit)
135+
for range settingsChangeChan {
136+
client.updateIcon()
116137
}
117138
}
118139

119-
//go:embed netbird-systemtray-connected-macos.png
140+
// showErrorMessage displays an error message in a simple window.
141+
func showErrorMessage(msg string) {
142+
a := app.New()
143+
w := a.NewWindow("NetBird Error")
144+
label := widget.NewLabel(msg)
145+
label.Wrapping = fyne.TextWrapWord
146+
w.SetContent(label)
147+
w.Resize(fyne.NewSize(400, 100))
148+
w.Show()
149+
a.Run()
150+
}
151+
152+
//go:embed assets/netbird-systemtray-connected-macos.png
120153
var iconConnectedMacOS []byte
121154

122-
//go:embed netbird-systemtray-disconnected-macos.png
155+
//go:embed assets/netbird-systemtray-disconnected-macos.png
123156
var iconDisconnectedMacOS []byte
124157

125-
//go:embed netbird-systemtray-update-disconnected-macos.png
158+
//go:embed assets/netbird-systemtray-update-disconnected-macos.png
126159
var iconUpdateDisconnectedMacOS []byte
127160

128-
//go:embed netbird-systemtray-update-connected-macos.png
161+
//go:embed assets/netbird-systemtray-update-connected-macos.png
129162
var iconUpdateConnectedMacOS []byte
130163

131-
//go:embed netbird-systemtray-connecting-macos.png
164+
//go:embed assets/netbird-systemtray-connecting-macos.png
132165
var iconConnectingMacOS []byte
133166

134-
//go:embed netbird-systemtray-error-macos.png
167+
//go:embed assets/netbird-systemtray-error-macos.png
135168
var iconErrorMacOS []byte
136169

137170
type serviceClient struct {
@@ -301,18 +334,6 @@ func (s *serviceClient) showSettingsUI() {
301334
s.wSettings.Show()
302335
}
303336

304-
// showErrorMSG opens a fyne app window to display the supplied message
305-
func showErrorMSG(msg string) {
306-
app := app.New()
307-
w := app.NewWindow("NetBird Error")
308-
content := widget.NewLabel(msg)
309-
content.Wrapping = fyne.TextWrapWord
310-
w.SetContent(content)
311-
w.Resize(fyne.NewSize(400, 100))
312-
w.Show()
313-
app.Run()
314-
}
315-
316337
// getSettingsForm to embed it into settings window.
317338
func (s *serviceClient) getSettingsForm() *widget.Form {
318339
return &widget.Form{
@@ -328,7 +349,7 @@ func (s *serviceClient) getSettingsForm() *widget.Form {
328349
},
329350
SubmitText: "Save",
330351
OnSubmit: func() {
331-
if s.iPreSharedKey.Text != "" && s.iPreSharedKey.Text != "**********" {
352+
if s.iPreSharedKey.Text != "" && s.iPreSharedKey.Text != censoredPreSharedKey {
332353
// validate preSharedKey if it added
333354
if _, err := wgtypes.ParseKey(s.iPreSharedKey.Text); err != nil {
334355
dialog.ShowError(fmt.Errorf("Invalid Pre-shared Key Value"), s.wSettings)
@@ -366,7 +387,7 @@ func (s *serviceClient) getSettingsForm() *widget.Form {
366387
WireguardPort: &port,
367388
}
368389

369-
if s.iPreSharedKey.Text != "**********" {
390+
if s.iPreSharedKey.Text != censoredPreSharedKey {
370391
loginRequest.OptionalPreSharedKey = &s.iPreSharedKey.Text
371392
}
372393

@@ -588,21 +609,21 @@ func (s *serviceClient) onTrayReady() {
588609
s.mAdminPanel = systray.AddMenuItem("Admin Panel", "Netbird Admin Panel")
589610
systray.AddSeparator()
590611

591-
s.mSettings = systray.AddMenuItem("Settings", "Settings of the application")
592-
s.mAllowSSH = s.mSettings.AddSubMenuItemCheckbox("Allow SSH", "Allow SSH connections", false)
593-
s.mAutoConnect = s.mSettings.AddSubMenuItemCheckbox("Connect on Startup", "Connect automatically when the service starts", false)
594-
s.mEnableRosenpass = s.mSettings.AddSubMenuItemCheckbox("Enable Quantum-Resistance", "Enable post-quantum security via Rosenpass", false)
595-
s.mNotifications = s.mSettings.AddSubMenuItemCheckbox("Notifications", "Enable notifications", false)
596-
s.mAdvancedSettings = s.mSettings.AddSubMenuItem("Advanced Settings", "Advanced settings of the application")
597-
s.mCreateDebugBundle = s.mSettings.AddSubMenuItem("Create Debug Bundle", "Create and open debug information bundle")
612+
s.mSettings = systray.AddMenuItem("Settings", settingsMenuDescr)
613+
s.mAllowSSH = s.mSettings.AddSubMenuItemCheckbox("Allow SSH", allowSSHMenuDescr, false)
614+
s.mAutoConnect = s.mSettings.AddSubMenuItemCheckbox("Connect on Startup", autoConnectMenuDescr, false)
615+
s.mEnableRosenpass = s.mSettings.AddSubMenuItemCheckbox("Enable Quantum-Resistance", quantumResistanceMenuDescr, false)
616+
s.mNotifications = s.mSettings.AddSubMenuItemCheckbox("Notifications", notificationsMenuDescr, false)
617+
s.mAdvancedSettings = s.mSettings.AddSubMenuItem("Advanced Settings", advancedSettingsMenuDescr)
618+
s.mCreateDebugBundle = s.mSettings.AddSubMenuItem("Create Debug Bundle", debugBundleMenuDescr)
598619
s.loadSettings()
599620

600621
s.exitNodeMu.Lock()
601-
s.mExitNode = systray.AddMenuItem("Exit Node", "Select exit node for routing traffic")
622+
s.mExitNode = systray.AddMenuItem("Exit Node", exitNodeMenuDescr)
602623
s.mExitNode.Disable()
603624
s.exitNodeMu.Unlock()
604625

605-
s.mNetworks = systray.AddMenuItem("Networks", "Open the networks management window")
626+
s.mNetworks = systray.AddMenuItem("Networks", networksMenuDescr)
606627
s.mNetworks.Disable()
607628
systray.AddSeparator()
608629

@@ -619,11 +640,11 @@ func (s *serviceClient) onTrayReady() {
619640
s.mVersionDaemon.Disable()
620641
s.mVersionDaemon.Hide()
621642

622-
s.mUpdate = s.mAbout.AddSubMenuItem("Download latest version", "Download latest version")
643+
s.mUpdate = s.mAbout.AddSubMenuItem("Download latest version", latestVersionMenuDescr)
623644
s.mUpdate.Hide()
624645

625646
systray.AddSeparator()
626-
s.mQuit = systray.AddMenuItem("Quit", "Quit the client app")
647+
s.mQuit = systray.AddMenuItem("Quit", quitMenuDescr)
627648

628649
// update exit node menu in case service is already connected
629650
go s.updateExitNodes()

client/ui/const.go

+15
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
package main
2+
3+
const (
4+
settingsMenuDescr = "Settings of the application"
5+
allowSSHMenuDescr = "Allow SSH connections"
6+
autoConnectMenuDescr = "Connect automatically when the service starts"
7+
quantumResistanceMenuDescr = "Enable post-quantum security via Rosenpass"
8+
notificationsMenuDescr = "Enable notifications"
9+
advancedSettingsMenuDescr = "Advanced settings of the application"
10+
debugBundleMenuDescr = "Create and open debug information bundle"
11+
exitNodeMenuDescr = "Select exit node for routing traffic"
12+
networksMenuDescr = "Open the networks management window"
13+
latestVersionMenuDescr = "Download latest version"
14+
quitMenuDescr = "Quit the client app"
15+
)

0 commit comments

Comments
 (0)