mirror of
https://github.com/safing/portbase
synced 2025-09-04 11:40:23 +00:00
Improve notification handling and documentation
This commit is contained in:
parent
69330181db
commit
4688a8d490
2 changed files with 69 additions and 43 deletions
|
@ -8,8 +8,6 @@ import (
|
||||||
// AttachToModule attaches the notification to a module and changes to the
|
// AttachToModule attaches the notification to a module and changes to the
|
||||||
// notification will be reflected on the module failure status.
|
// notification will be reflected on the module failure status.
|
||||||
func (n *Notification) AttachToModule(m *modules.Module) {
|
func (n *Notification) AttachToModule(m *modules.Module) {
|
||||||
log.Errorf("notifications: attaching %q", n.EventID)
|
|
||||||
|
|
||||||
if m == nil {
|
if m == nil {
|
||||||
log.Warningf("notifications: cannot remove attached module from notification %s", n.EventID)
|
log.Warningf("notifications: cannot remove attached module from notification %s", n.EventID)
|
||||||
return
|
return
|
||||||
|
@ -46,8 +44,6 @@ func (n *Notification) AttachToModule(m *modules.Module) {
|
||||||
|
|
||||||
// resolveModuleFailure removes the notification from the module failure status.
|
// resolveModuleFailure removes the notification from the module failure status.
|
||||||
func (n *Notification) resolveModuleFailure() {
|
func (n *Notification) resolveModuleFailure() {
|
||||||
log.Errorf("notifications: resolving %q", n.EventID)
|
|
||||||
|
|
||||||
if n.belongsTo != nil {
|
if n.belongsTo != nil {
|
||||||
// Resolve failure in attached module.
|
// Resolve failure in attached module.
|
||||||
n.belongsTo.Resolve(n.EventID)
|
n.belongsTo.Resolve(n.EventID)
|
||||||
|
@ -63,8 +59,6 @@ func init() {
|
||||||
}
|
}
|
||||||
|
|
||||||
func mirrorModuleStatus(moduleFailure uint8, id, title, msg string) {
|
func mirrorModuleStatus(moduleFailure uint8, id, title, msg string) {
|
||||||
log.Errorf("notifications: mirroring %d %q %q %q", moduleFailure, id, title, msg)
|
|
||||||
|
|
||||||
// Ignore "resolve all" requests.
|
// Ignore "resolve all" requests.
|
||||||
if id == "" {
|
if id == "" {
|
||||||
return
|
return
|
||||||
|
@ -84,12 +78,30 @@ func mirrorModuleStatus(moduleFailure uint8, id, title, msg string) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// A notification for the given ID does not yet exists, create it.
|
// A notification for the given ID does not yet exists, create it.
|
||||||
|
n = &Notification{
|
||||||
|
EventID: id,
|
||||||
|
Title: title,
|
||||||
|
Message: msg,
|
||||||
|
}
|
||||||
|
|
||||||
switch moduleFailure {
|
switch moduleFailure {
|
||||||
case modules.FailureHint:
|
case modules.FailureHint:
|
||||||
NotifyInfo(id, title, msg)
|
n.Type = Info
|
||||||
case modules.FailureWarning:
|
case modules.FailureWarning:
|
||||||
NotifyWarn(id, title, msg)
|
n.Type = Warning
|
||||||
|
n.AvailableActions = []*Action{
|
||||||
|
{
|
||||||
|
Text: "Get Help",
|
||||||
|
Type: ActionTypeOpenURL,
|
||||||
|
Payload: "https://safing.io/support/",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
fallthrough
|
||||||
case modules.FailureError:
|
case modules.FailureError:
|
||||||
NotifyError(id, title, msg)
|
n.Type = Error
|
||||||
|
n.ShowOnSystem = true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Notify(n)
|
||||||
}
|
}
|
||||||
|
|
|
@ -73,7 +73,8 @@ type Notification struct {
|
||||||
// have any paramerized values replaced.
|
// have any paramerized values replaced.
|
||||||
Message string
|
Message string
|
||||||
// ShowOnSystem specifies if the notification should be also shown on the
|
// ShowOnSystem specifies if the notification should be also shown on the
|
||||||
// operating system.
|
// operating system. Notifications shown on the operating system level are
|
||||||
|
// more focus-intrusive and should only be used for important notifications.
|
||||||
ShowOnSystem bool
|
ShowOnSystem bool
|
||||||
// EventData contains an additional payload for the notification. This payload
|
// EventData contains an additional payload for the notification. This payload
|
||||||
// may contain contextual data and may be used by a localization framework
|
// may contain contextual data and may be used by a localization framework
|
||||||
|
@ -108,13 +109,19 @@ type Notification struct {
|
||||||
|
|
||||||
// Action describes an action that can be taken for a notification.
|
// Action describes an action that can be taken for a notification.
|
||||||
type Action struct {
|
type Action struct {
|
||||||
ID string
|
// ID specifies a unique ID for the action. If an action is selected, the ID
|
||||||
Text string
|
// is written to SelectedActionID and the notification is saved.
|
||||||
Type ActionType
|
// If the action type is not ActionTypeNone, the ID may be empty, signifying
|
||||||
|
// that this action is merely additional and selecting it does dismiss the
|
||||||
|
// notification.
|
||||||
|
ID string
|
||||||
|
// Text on the button.
|
||||||
|
Text string
|
||||||
|
// Type specifies the action type. Implementing interfaces should only
|
||||||
|
// display action types they can handle.
|
||||||
|
Type ActionType
|
||||||
|
// Payload holds additional data for special action types.
|
||||||
Payload interface{}
|
Payload interface{}
|
||||||
|
|
||||||
// Dismisses specifies if the notification is dismissed when this action is selected.
|
|
||||||
Dismisses bool
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// ActionType defines a specific type of action.
|
// ActionType defines a specific type of action.
|
||||||
|
@ -184,43 +191,60 @@ func Delete(id string) {
|
||||||
n, ok = nots[id]
|
n, ok = nots[id]
|
||||||
}
|
}
|
||||||
|
|
||||||
// NotifyInfo is a helper method for quickly showing a info
|
// NotifyInfo is a helper method for quickly showing an info notification.
|
||||||
// notification. The notification is already shown. If id is
|
// The notification will be activated immediately.
|
||||||
// an empty string a new UUIDv4 will be generated.
|
// If the provided id is empty, an id will derived from msg.
|
||||||
// ShowOnSystem is disabled.
|
// ShowOnSystem is disabled.
|
||||||
|
// If no actions are defined, a default "OK" (ID:"ack") action will be added.
|
||||||
func NotifyInfo(id, title, msg string, actions ...Action) *Notification {
|
func NotifyInfo(id, title, msg string, actions ...Action) *Notification {
|
||||||
return notify(Info, id, title, msg, false, actions...)
|
return notify(Info, id, title, msg, false, actions...)
|
||||||
}
|
}
|
||||||
|
|
||||||
// NotifyWarn is a helper method for quickly showing a warning
|
// NotifyWarn is a helper method for quickly showing a warning notification
|
||||||
// notification. The notification is already shown. If id is
|
// The notification will be activated immediately.
|
||||||
// an empty string a new UUIDv4 will be generated.
|
// If the provided id is empty, an id will derived from msg.
|
||||||
// ShowOnSystem is enabled.
|
// ShowOnSystem is enabled.
|
||||||
|
// If no actions are defined, a default "OK" (ID:"ack") action will be added.
|
||||||
func NotifyWarn(id, title, msg string, actions ...Action) *Notification {
|
func NotifyWarn(id, title, msg string, actions ...Action) *Notification {
|
||||||
return notify(Warning, id, title, msg, true, actions...)
|
return notify(Warning, id, title, msg, true, actions...)
|
||||||
}
|
}
|
||||||
|
|
||||||
// NotifyError is a helper method for quickly showing an error
|
// NotifyError is a helper method for quickly showing an error notification.
|
||||||
// notification. The notification is already shown. If id is
|
// The notification will be activated immediately.
|
||||||
// an empty string a new UUIDv4 will be generated.
|
// If the provided id is empty, an id will derived from msg.
|
||||||
// ShowOnSystem is enabled.
|
// ShowOnSystem is enabled.
|
||||||
|
// If no actions are defined, a default "OK" (ID:"ack") action will be added.
|
||||||
func NotifyError(id, title, msg string, actions ...Action) *Notification {
|
func NotifyError(id, title, msg string, actions ...Action) *Notification {
|
||||||
return notify(Error, id, title, msg, true, actions...)
|
return notify(Error, id, title, msg, true, actions...)
|
||||||
}
|
}
|
||||||
|
|
||||||
// NotifyPrompt is a helper method for quickly showing a prompt
|
// NotifyPrompt is a helper method for quickly showing a prompt notification.
|
||||||
// notification. The notification is already shown. If id is
|
// The notification will be activated immediately.
|
||||||
// an empty string a new UUIDv4 will be generated.
|
// If the provided id is empty, an id will derived from msg.
|
||||||
// ShowOnSystem is disabled.
|
// ShowOnSystem is disabled.
|
||||||
|
// If no actions are defined, a default "OK" (ID:"ack") action will be added.
|
||||||
func NotifyPrompt(id, title, msg string, actions ...Action) *Notification {
|
func NotifyPrompt(id, title, msg string, actions ...Action) *Notification {
|
||||||
return notify(Prompt, id, title, msg, false, actions...)
|
return notify(Prompt, id, title, msg, false, actions...)
|
||||||
}
|
}
|
||||||
|
|
||||||
func notify(nType Type, id, title, msg string, showOnSystem bool, actions ...Action) *Notification {
|
func notify(nType Type, id, title, msg string, showOnSystem bool, actions ...Action) *Notification {
|
||||||
acts := make([]*Action, len(actions))
|
// Process actions.
|
||||||
for idx := range actions {
|
var acts []*Action
|
||||||
a := actions[idx]
|
if len(actions) == 0 {
|
||||||
acts[idx] = &a
|
// Create ack action if there are no defined actions.
|
||||||
|
acts = []*Action{
|
||||||
|
{
|
||||||
|
ID: "ack",
|
||||||
|
Text: "OK",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// Reference given actions for notification.
|
||||||
|
acts = make([]*Action, len(actions))
|
||||||
|
for index := range actions {
|
||||||
|
a := actions[index]
|
||||||
|
acts[index] = &a
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return Notify(&Notification{
|
return Notify(&Notification{
|
||||||
|
@ -228,8 +252,8 @@ func notify(nType Type, id, title, msg string, showOnSystem bool, actions ...Act
|
||||||
Type: nType,
|
Type: nType,
|
||||||
Title: title,
|
Title: title,
|
||||||
Message: msg,
|
Message: msg,
|
||||||
AvailableActions: acts,
|
|
||||||
ShowOnSystem: showOnSystem,
|
ShowOnSystem: showOnSystem,
|
||||||
|
AvailableActions: acts,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -290,16 +314,6 @@ func (n *Notification) save(pushUpdate bool) {
|
||||||
n.GUID = utils.RandomUUID(n.EventID).String()
|
n.GUID = utils.RandomUUID(n.EventID).String()
|
||||||
}
|
}
|
||||||
|
|
||||||
// Make ack notification if there are no defined actions.
|
|
||||||
if len(n.AvailableActions) == 0 {
|
|
||||||
n.AvailableActions = []*Action{
|
|
||||||
{
|
|
||||||
ID: "ack",
|
|
||||||
Text: "OK",
|
|
||||||
},
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Make sure we always have a notification state assigned.
|
// Make sure we always have a notification state assigned.
|
||||||
if n.State == "" {
|
if n.State == "" {
|
||||||
n.State = Active
|
n.State = Active
|
||||||
|
|
Loading…
Add table
Reference in a new issue