Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feat support windows #3

Merged
merged 1 commit into from
Jun 2, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Binary file added .DS_Store
Binary file not shown.
27 changes: 27 additions & 0 deletions .github/actions/generate-icons/action.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
name: "Generate icons"
description: "Generate icons and push it as an artifact"

inputs:
upload_artifact:
description: 'Upload artifact'
default: 'true'

runs:
using: composite
steps:
- uses: actions/setup-go@v5
with:
go-version: '1.22'
- name: Compiled icons
shell: bash
run: |
GOPATH=$(go env GOPATH)
export GOPATH
go get github.com/cratonica/2goarray
go install github.com/cratonica/2goarray
./generate-icons.sh
- uses: actions/upload-artifact@v4
if: ${{ inputs.upload_artifact == 'true' }}
with:
name: icons
path: icons/*.go
19 changes: 18 additions & 1 deletion .github/workflows/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,14 +8,26 @@ permissions:
contents: read

jobs:
generate-icons:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: ./.github/actions/generate-icons

windows-build:
runs-on: windows-latest
needs: [ generate-icons ]
steps:
- uses: actions/checkout@v4
- uses: actions/setup-go@v5
with:
go-version: '1.22'
- run: go build -o ipingtray.exe
- uses: actions/download-artifact@v4
with:
name: icons
path: icons

- run: go build -ldflags -H=windowsgui -o ipingtray.exe

- name: Set up NSIS
run: choco install nsis
Expand All @@ -33,11 +45,16 @@ jobs:

macos-build:
runs-on: macos-13
needs: [ generate-icons ]
steps:
- uses: actions/checkout@v4
- uses: actions/setup-go@v5
with:
go-version: '1.22'
- uses: actions/download-artifact@v4
with:
name: icons
path: icons

- run: go build -o ipingtray
- run: go install github.com/machinebox/appify@latest
Expand Down
5 changes: 5 additions & 0 deletions .github/workflows/pull_request.yml
Original file line number Diff line number Diff line change
Expand Up @@ -21,10 +21,15 @@ jobs:
with:
fetch-depth: 0

- uses: ./.github/actions/generate-icons
with:
upload_artifact: false

- name: Super-linter
uses: super-linter/super-linter@v6.5.1
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
VALIDATE_GO_MODULES: false # @see https://github.com/cratonica/2goarray/issues/14
commitlint:
runs-on: ubuntu-latest
steps:
Expand Down
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
vendor
vendor
icons/*.go
22 changes: 20 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,11 +22,11 @@ this option cannot be configured at this time)

## Start app automatically on boot

###  MacOS
###  macOS

You can follow the article from Apple which explain how to start the app automatically at boot:

https://support.apple.com/guide/mac-help/open-items-automatically-when-you-log-in-mh15189
<https://support.apple.com/guide/mac-help/open-items-automatically-when-you-log-in-mh15189>

### Thresholds

Expand All @@ -41,6 +41,24 @@ https://support.apple.com/guide/mac-help/open-items-automatically-when-you-log-i

![./docs/screenshot.png](/docs/screenshot.png)

## Development

### Generate icons

If you wish to update the icons, you need to run the `generate-icons.sh` which gonna generate
golang []bytes array representing the icon.

To generate icons, you also need to install [`2goarray`](https://github.com/cratonica/2goarray)

```bash
go get github.com/cratonica/2goarray
go install github.com/cratonica/2goarray
```

> ⚠️ We use .ico file because it's the only supported format on windows, according to
> [@ZGGSONG](https://github.com/getlantern/systray/issues/154#issuecomment-1207607136)


## Contribution

Feel free to contribute !
7 changes: 6 additions & 1 deletion build/windows/installer.nsi
Original file line number Diff line number Diff line change
Expand Up @@ -13,11 +13,16 @@ Section "Install"
File /r "ipingtray.exe"

CreateShortCut "$SMSTARTUP\iPingTray.lnk" "$INSTDIR\ipingtray.exe"
CreateShortCut "$SMPROGRAMS\iPingTray.lnk" "$INSTDIR\ipingtray.exe" "" "$INSTDIR\ipingtray.exe" 0

WriteUninstaller "$INSTDIR\uninstall.exe"
SectionEnd

Section "Uninstall"
Delete "$INSTDIR\ipingtray.exe"

Delete "$SMSTARTUP\iPingTray.lnk"
RMDir /r "$INSTDIR"
Delete "$SMPROGRAMS\iPingTray.lnk"

RMDir "$INSTDIR"
SectionEnd
8 changes: 8 additions & 0 deletions generate-icons.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
#!/bin/bash
set -x

for icon in icons/*.ico; do
icon_name=$(basename "${icon%.*}")
capitalized_name=$(echo "${icon_name:0:1}" | tr '[:lower:]' '[:upper:]')${icon_name:1}
"${GOPATH}/bin/2goarray" "${capitalized_name}" icons <"${icon}" >"icons/${icon_name}.go"
done
Binary file added icons/green.ico
Binary file not shown.
Binary file added icons/orange.ico
Binary file not shown.
Binary file added icons/red.ico
Binary file not shown.
Binary file added icons/white.ico
Binary file not shown.
38 changes: 21 additions & 17 deletions main.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,68 +3,63 @@ package main
import (
"fmt"
"log"
"runtime"
"strings"

"fyne.io/systray"
probing "github.com/prometheus-community/pro-bing"
)

var pinger *probing.Pinger
"ipingtray/icons"
)

func main() {
systray.Run(onReady, onExit)
}

func onReady() {
systray.SetTitle("Initializing...")
systray.SetIcon(icons.White)

mLatencyLabel := systray.AddMenuItem("Latency", "Current Latency")
mLatencyLabel.Disable()

systray.AddSeparator()
mQuit := systray.AddMenuItem("Quit", "Quit the app")

var err error
pinger, err = probing.NewPinger("8.8.8.8")
if err != nil {
panic(err)
}
pinger.SetLogger(nil)

// Update tray title
pinger.OnRecv = func(pkt *probing.Packet) {
latency := pkt.Rtt.Milliseconds()
icon := icons.Red

switch {
case latency < 50:
systray.SetTitle(fmt.Sprintf("🟢 %d ms", latency))
icon = icons.Green
case latency < 75:
systray.SetTitle(fmt.Sprintf("🟠 %d ms", latency))
default:
systray.SetTitle(fmt.Sprintf("🔴 %d ms", latency))
icon = icons.Orange
}

updateTray(fmt.Sprintf("%d ms", latency), icon)
mLatencyLabel.SetTitle(fmt.Sprintf("%s: %d ms", pinger.IPAddr().String(), latency))
}

pinger.OnSendError = func(_ *probing.Packet, err error) {
systray.SetTitle("🔴 Network unavailable")
updateTray("Network Unavailable", icons.Red)

if strings.Contains(err.Error(), "sendto") {
parts := strings.Split(err.Error(), ": ")
if len(parts) >= 2 {
mLatencyLabel.SetTitle(fmt.Sprintf("8.8.8.8: %s", parts[len(parts)-1]))
mLatencyLabel.SetTitle(fmt.Sprintf("%s: %s", pinger.Addr(), parts[len(parts)-1]))
return
}
}

mLatencyLabel.SetTitle(fmt.Sprintf("8.8.8.8: %s", err.Error()))
mLatencyLabel.SetTitle(fmt.Sprintf("%s: %s", pinger.Addr(), err.Error()))
}

// Running the ping
go func() {
if err := pinger.Run(); err != nil {
log.Println("Pinger has crashed")
log.Printf("pinger has crashed: %v\n", err)
systray.Quit()
}
}()
Expand All @@ -76,6 +71,15 @@ func onReady() {
}()
}

func updateTray(title string, icon []byte) {
systray.SetTitle(title)
systray.SetIcon(icon)

if runtime.GOOS == "windows" {
systray.SetTooltip(title)
}
}

func onExit() {
pinger.Stop()
}
23 changes: 23 additions & 0 deletions ping.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
package main

import (
"runtime"

probing "github.com/prometheus-community/pro-bing"
)

var pinger *probing.Pinger

func init() {
var err error
pinger, err = probing.NewPinger("8.8.8.8")
if err != nil {
panic(err)
}

pinger.SetLogger(nil)

if runtime.GOOS == "windows" {
pinger.SetPrivileged(true)
}
}