go-nativenotify

Native notifications in Go
Log | Files | Refs | README | LICENSE

notify_windows.go (2529B)


      1 package nativenotify
      2 
      3 import (
      4 	"fmt"
      5 	"strconv"
      6 	"strings"
      7 
      8 	windowsnotify "git.sr.ht/~jackmordaunt/go-toast/v2"
      9 )
     10 
     11 func setup(cfg Config) error {
     12 	windowsnotify.SetAppData(cfg.Windows)
     13 	windowsnotify.SetActivationCallback(func(args string, userdata []windowsnotify.UserData) {
     14 		parts := strings.Split(args, "-")
     15 
     16 		id, _ := take(&parts)
     17 
     18 		actionIDEncoded, _ := take(&parts)
     19 		actionArgsEncoded, _ := take(&parts)
     20 
     21 		actionID := decode(actionIDEncoded)
     22 		actionArgs := decode(actionArgsEncoded)
     23 
     24 		// If the action was a text input, or a selection, grab the value for it.
     25 		// If the action was a button, the actionArgs will contain the value.
     26 		for _, ud := range userdata {
     27 			if ud.Key == actionID {
     28 				actionArgs = ud.Value
     29 			}
     30 		}
     31 
     32 		fn, ok := callbacksTake(&callbacks, id)
     33 		if !ok || fn == nil {
     34 			return
     35 		}
     36 
     37 		fn(actionID, actionArgs)
     38 	})
     39 	return nil
     40 }
     41 
     42 // push the notification.
     43 //
     44 // Actions have the notification ID embedded in them so that we can retrieve the
     45 // correct procedure when actvited by Windows.
     46 //
     47 // Action IDs and payloads are hex encoded to escape them and decoded to plaintext
     48 // when received.
     49 func push(n Notification) (err error) {
     50 	id := nextID.Add(1)
     51 
     52 	var (
     53 		actions = make([]windowsnotify.Action, 0, len(n.ButtonActions))
     54 		inputs  = make([]windowsnotify.Input, 0, len(n.TextActions))
     55 	)
     56 
     57 	for _, a := range n.ButtonActions {
     58 		actions = append(actions, windowsnotify.Action{
     59 			Content:   a.LabelText,
     60 			Arguments: fmt.Sprintf("%d-%s-%s", id, encode(a.ID), encode(a.Value)),
     61 		})
     62 	}
     63 
     64 	for _, a := range n.TextActions {
     65 		inputs = append(inputs, windowsnotify.Input{
     66 			ID:          a.ID,
     67 			Title:       a.Title,
     68 			Placeholder: a.PlaceholderHint,
     69 		})
     70 		if a.ButtonLabel != "" {
     71 			actions = append(actions, windowsnotify.Action{
     72 				InputID:   a.ID,
     73 				Content:   a.ButtonLabel,
     74 				Arguments: fmt.Sprintf("%d-%s", id, encode(a.ID)),
     75 			})
     76 		}
     77 	}
     78 
     79 	tn := windowsnotify.Notification{
     80 		Title:               n.Title,
     81 		Body:                n.Body,
     82 		Icon:                n.Icon,
     83 		ActivationType:      windowsnotify.Foreground,
     84 		ActivationArguments: strconv.FormatInt(id, 10),
     85 		Actions:             actions,
     86 		Inputs:              inputs,
     87 	}
     88 
     89 	switch n.Windows {
     90 	case WindowsOptionIconCircleCrop:
     91 		tn.IconCrop = windowsnotify.CropStyleCircle
     92 	case WindowsOptionIconSquareCrop:
     93 		tn.IconCrop = windowsnotify.CropStyleSquare
     94 	case WindowsOptionIconHero:
     95 		tn.HeroIcon, tn.Icon = tn.Icon, ""
     96 	}
     97 
     98 	callbacksPut(&callbacks, strconv.FormatInt(id, 10), n.Callback)
     99 
    100 	return tn.Push()
    101 }