Skip to content

Commit

Permalink
Adding notifications support for windows
Browse files Browse the repository at this point in the history
Invoking PowerShell is slow (around 5 second delay) but I can't find a better way.
Contributions welcome\!
  • Loading branch information
andydotxyz committed Apr 28, 2020
1 parent 36bb808 commit 2e7ee28
Show file tree
Hide file tree
Showing 2 changed files with 67 additions and 1 deletion.
52 changes: 51 additions & 1 deletion app/app_windows.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,15 +5,34 @@
package app

import (
"fmt"
"io/ioutil"
"log"
"net/url"
"os"
"os/exec"
"path/filepath"
"strings"
"syscall"

"fyne.io/fyne"
"fyne.io/fyne/theme"
)

const notificationTemplate = `$title = "%s"
$content = "%s"
[Windows.UI.Notifications.ToastNotificationManager, Windows.UI.Notifications, ContentType = WindowsRuntime] > $null
$template = [Windows.UI.Notifications.ToastNotificationManager]::GetTemplateContent([Windows.UI.Notifications.ToastTemplateType]::ToastText02)
$toastXml = [xml] $template.GetXml()
$toastXml.GetElementsByTagName("text")[0].AppendChild($toastXml.CreateTextNode($title)) > $null
$toastXml.GetElementsByTagName("text")[1].AppendChild($toastXml.CreateTextNode($content)) > $null
$xml = New-Object Windows.Data.Xml.Dom.XmlDocument
$xml.LoadXml($toastXml.OuterXml)
$toast = [Windows.UI.Notifications.ToastNotification]::new($xml)
[Windows.UI.Notifications.ToastNotificationManager]::CreateToastNotifier("appID").Show($toast);`

func defaultTheme() fyne.Theme {
return theme.DarkTheme()
}
Expand All @@ -31,6 +50,37 @@ func (app *fyneApp) OpenURL(url *url.URL) error {
return cmd.Run()
}

var scriptNum = 0

func (app *fyneApp) SendNotification(notify *fyne.Notification) {
log.Println("NOT YET IMPLEMENTED") // TODO
title := escapeNotifyString(notify.Title)
content := escapeNotifyString(notify.Content)

script := fmt.Sprintf(notificationTemplate, title, content)
go runScript("notify", script)
}

func escapeNotifyString(in string) string {
noSlash := strings.ReplaceAll(in, "`", "``")
return strings.ReplaceAll(noSlash, "\"", "`\"")
}

func runScript(name, script string) {
scriptNum++
appID := fyne.CurrentApp().UniqueID()
fileName := fmt.Sprintf("fyne-%s-%s-%d.ps1", appID, name, scriptNum)
log.Println(fileName)

tmpFilePath := filepath.Join(os.TempDir(), fileName)
err := ioutil.WriteFile(tmpFilePath, []byte(script), 0600)
if err != nil {
fyne.LogError("Could not write script to show notification", err)
return
}
log.Println("PATH", tmpFilePath)
defer os.Remove(tmpFilePath)

cmd := exec.Command("PowerShell", "-ExecutionPolicy", "Bypass", "-File", tmpFilePath)
cmd.SysProcAttr = &syscall.SysProcAttr{HideWindow: true}
err = cmd.Run()
}
16 changes: 16 additions & 0 deletions app/app_windows_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
package app

import (
"testing"

"github.com/stretchr/testify/assert"
)

func TestEscapeNotifyString(t *testing.T) {
assert.Equal(t, "normal", escapeNotifyString("normal"))
assert.Equal(t, "isn't", escapeNotifyString("isn't"))
assert.Equal(t, "`\"mine`\"", escapeNotifyString(`"mine"`))
assert.Equal(t, "sla\\sh", escapeNotifyString(`sla\sh`))
assert.Equal(t, "qu``ote", escapeNotifyString("qu`ote"))
assert.Equal(t, "escaped ```\" string", escapeNotifyString("escaped `\" string"))
}

0 comments on commit 2e7ee28

Please sign in to comment.