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 }