From 4a1ed12598a69a0be69f7f322c9ac684f2aa3656 Mon Sep 17 00:00:00 2001 From: Daniel Date: Thu, 29 Oct 2020 22:50:35 +0100 Subject: [PATCH 1/2] Add Title and Category fields to Notification Also, improve on the notification handling a bit --- notifications/notification.go | 60 +++++++++++++++++++++++------------ 1 file changed, 40 insertions(+), 20 deletions(-) diff --git a/notifications/notification.go b/notifications/notification.go index b649cc9..5b8a0ac 100644 --- a/notifications/notification.go +++ b/notifications/notification.go @@ -60,6 +60,12 @@ type Notification struct { GUID string // Type is the notification type. It can be one of Info, Warning or Prompt. Type Type + // Title is an optional and very short title for the message that gives a + // hint about what the notification is about. + Title string + // Category is an optional category for the notification that allows for + // tagging and grouping notifications by category. + Category string // Message is the default message shown to the user if no localized version // of the notification is available. Note that the message should already // have any paramerized values replaced. @@ -129,43 +135,53 @@ func NotifyPrompt(id, msg string, actions ...Action) *Notification { return notify(Prompt, id, msg, actions...) } -func notify(nType Type, id string, msg string, actions ...Action) *Notification { +func notify(nType Type, id, msg string, actions ...Action) *Notification { acts := make([]*Action, len(actions)) for idx := range actions { a := actions[idx] acts[idx] = &a } - if id == "" { - id = utils.DerivedInstanceUUID(msg).String() - } - - n := Notification{ + return Notify(&Notification{ EventID: id, - Message: msg, Type: nType, + Message: msg, AvailableActions: acts, - } - - return n.Save() + }) } -// Save saves the notification and returns it. -func (n *Notification) Save() *Notification { - return n.save(true) +// Notify sends the given notification. +func Notify(n *Notification) *Notification { + // Derive missing information. + if n.Message == "" { + n.Title = n.Message + } + if n.EventID == "" { + n.EventID = utils.DerivedInstanceUUID(n.Message).String() + } + + n.save(true) + return n +} + +// Save saves the notification. +func (n *Notification) Save() { + n.save(true) } // save saves the notification to the internal storage. It locks the // notification, so it must not be locked when save is called. -func (n *Notification) save(pushUpdate bool) *Notification { +func (n *Notification) save(pushUpdate bool) { var id string // Delete notification after processing deletion. defer func() { - // Lock and save to notification storage. - notsLock.Lock() - defer notsLock.Unlock() - nots[id] = n + if id != "" { + // Lock and save to notification storage. + notsLock.Lock() + defer notsLock.Unlock() + nots[id] = n + } }() // We do not access EventData here, so it is enough to just lock the @@ -173,6 +189,12 @@ func (n *Notification) save(pushUpdate bool) *Notification { n.lock.Lock() defer n.lock.Unlock() + // Check if required data is present. + if n.EventID == "" || n.Message == "" { + log.Warning("notifications: ignoring notification without EventID and Message") + return + } + // Save ID for deletion id = n.EventID @@ -209,8 +231,6 @@ func (n *Notification) save(pushUpdate bool) *Notification { log.Tracef("notifications: pushing update for %s to subscribers", n.Key()) dbController.PushUpdate(n) } - - return n } // SetActionFunction sets a trigger function to be executed when the user reacted on the notification. From 505fcc89136ec78e9519a16420b47fc214e7b851 Mon Sep 17 00:00:00 2001 From: Daniel Date: Fri, 30 Oct 2020 12:05:50 +0100 Subject: [PATCH 2/2] Implement review suggestions --- config/option.go | 2 +- notifications/notification.go | 30 ++++++++++++++++++++---------- 2 files changed, 21 insertions(+), 11 deletions(-) diff --git a/config/option.go b/config/option.go index e391768..759eac3 100644 --- a/config/option.go +++ b/config/option.go @@ -135,7 +135,7 @@ type QuickSetting struct { Action QuickSettingsAction } -// ValueRequirement defines a requirement on another configuraiton option. +// ValueRequirement defines a requirement on another configuration option. type ValueRequirement struct { // Key is the key of the configuration option that is required. Key string diff --git a/notifications/notification.go b/notifications/notification.go index 5b8a0ac..0c2a6be 100644 --- a/notifications/notification.go +++ b/notifications/notification.go @@ -152,13 +152,9 @@ func notify(nType Type, id, msg string, actions ...Action) *Notification { // Notify sends the given notification. func Notify(n *Notification) *Notification { - // Derive missing information. - if n.Message == "" { - n.Title = n.Message - } - if n.EventID == "" { - n.EventID = utils.DerivedInstanceUUID(n.Message).String() - } + // While this function is very similar to Save(), it is much nicer to use in + // order to just fire off one notification, as it does not require some more + // uncommon Go syntax. n.save(true) return n @@ -174,7 +170,7 @@ func (n *Notification) Save() { func (n *Notification) save(pushUpdate bool) { var id string - // Delete notification after processing deletion. + // Save notification after pre-save processing. defer func() { if id != "" { // Lock and save to notification storage. @@ -189,12 +185,26 @@ func (n *Notification) save(pushUpdate bool) { n.lock.Lock() defer n.lock.Unlock() + // Move Title to Message, as that is the required field. + if n.Message == "" { + n.Message = n.Title + n.Title = "" + } + // Check if required data is present. - if n.EventID == "" || n.Message == "" { - log.Warning("notifications: ignoring notification without EventID and Message") + if n.Message == "" { + log.Warning("notifications: ignoring notification without Message") return } + // Derive EventID from Message if not given. + if n.EventID == "" { + n.EventID = fmt.Sprintf( + "unknown:%s", + utils.DerivedInstanceUUID(n.Message).String(), + ) + } + // Save ID for deletion id = n.EventID