mirror of
https://github.com/safing/portmaster
synced 2026-04-28 03:20:31 +00:00
feat(resolver): persist stale cache notification suppression
Add "Don't show again" action to the stale cache notification. Suppression state is stored in the database and checked on startup. System notification is shown only on first occurrence. Reset handler in broadcasts now also clears the suppression record. https://github.com/safing/portmaster/issues/2061
This commit is contained in:
parent
183ac069eb
commit
d07da4e350
2 changed files with 61 additions and 3 deletions
|
|
@ -11,6 +11,7 @@ import (
|
|||
"github.com/safing/portmaster/base/database"
|
||||
"github.com/safing/portmaster/base/database/accessor"
|
||||
"github.com/safing/portmaster/service/interop/ivpn"
|
||||
"github.com/safing/portmaster/service/resolver"
|
||||
)
|
||||
|
||||
func registerAPIEndpoints() error {
|
||||
|
|
@ -68,8 +69,9 @@ func handleResetState(ar *api.Request) (msg string, err error) {
|
|||
}
|
||||
|
||||
_ = db.Delete(ivpn.Notification_DB_ID_IvpnDetectSuppressed)
|
||||
_ = db.Delete(resolver.Notification_DB_ID_StaleCacheSuppressed)
|
||||
|
||||
return "Reset complete.", nil
|
||||
return "Reset complete. Some notifications require a restart to reappear.", nil
|
||||
}
|
||||
|
||||
func handleSimulate(ar *api.Request) (msg string, err error) {
|
||||
|
|
|
|||
|
|
@ -1,9 +1,13 @@
|
|||
package resolver
|
||||
|
||||
import (
|
||||
"context"
|
||||
"sync"
|
||||
"sync/atomic"
|
||||
"time"
|
||||
|
||||
"github.com/safing/portmaster/base/database"
|
||||
"github.com/safing/portmaster/base/database/record"
|
||||
"github.com/safing/portmaster/base/log"
|
||||
"github.com/safing/portmaster/base/notifications"
|
||||
"github.com/safing/portmaster/service/mgr"
|
||||
|
|
@ -47,11 +51,12 @@ func resetSlowQueriesSensorValue() {
|
|||
}
|
||||
|
||||
var suggestUsingStaleCacheNotification *notifications.Notification
|
||||
var isFirstNotification = true
|
||||
|
||||
func suggestUsingStaleCacheTask(_ *mgr.WorkerCtx) error {
|
||||
scheduleNextCall := true
|
||||
switch {
|
||||
case useStaleCache() || useStaleCacheConfigOption.IsSetByUser():
|
||||
case useStaleCache() || useStaleCacheConfigOption.IsSetByUser() || isNotificationSuppressed():
|
||||
// If setting is already active, disable task repeating.
|
||||
scheduleNextCall = false
|
||||
|
||||
|
|
@ -77,13 +82,15 @@ func suggestUsingStaleCacheTask(_ *mgr.WorkerCtx) error {
|
|||
getSlowQueriesSensorValue().Round(time.Millisecond),
|
||||
)
|
||||
|
||||
const actionSuppressID = "suppress"
|
||||
|
||||
// Notify user.
|
||||
suggestUsingStaleCacheNotification = ¬ifications.Notification{
|
||||
EventID: "resolver:suggest-using-stale-cache",
|
||||
Type: notifications.Info,
|
||||
Title: "Speed Up Website Loading",
|
||||
Message: "Portmaster has detected that websites may load slower because DNS queries are currently slower than expected. You may want to switch your DNS provider or enable using expired DNS cache entries for better performance.",
|
||||
ShowOnSystem: getSlowQueriesSensorValue() > 500*time.Millisecond,
|
||||
ShowOnSystem: isFirstNotification && getSlowQueriesSensorValue() > 500*time.Millisecond,
|
||||
Expires: time.Now().Add(10 * time.Minute).Unix(),
|
||||
AvailableActions: []*notifications.Action{
|
||||
{
|
||||
|
|
@ -92,6 +99,12 @@ func suggestUsingStaleCacheTask(_ *mgr.WorkerCtx) error {
|
|||
Payload: ¬ifications.ActionTypeOpenSettingPayload{
|
||||
Key: CfgOptionUseStaleCacheKey,
|
||||
},
|
||||
Visibility: notifications.ActionVisibilityInAppOnly,
|
||||
},
|
||||
{
|
||||
ID: actionSuppressID,
|
||||
Text: "Don't show again",
|
||||
Visibility: notifications.ActionVisibilityDetailed,
|
||||
},
|
||||
{
|
||||
ID: "ack",
|
||||
|
|
@ -99,6 +112,23 @@ func suggestUsingStaleCacheTask(_ *mgr.WorkerCtx) error {
|
|||
},
|
||||
},
|
||||
}
|
||||
// Only show the notification on the system for the first time,
|
||||
// and do not bother user with multiple system notifications
|
||||
isFirstNotification = false
|
||||
|
||||
suggestUsingStaleCacheNotification.SetActionFunction(func(_ context.Context, n *notifications.Notification) error {
|
||||
n.Lock()
|
||||
actionID := n.SelectedActionID
|
||||
n.Unlock()
|
||||
if actionID == actionSuppressID {
|
||||
if err := suppressNotification(); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
n.Delete()
|
||||
return nil
|
||||
})
|
||||
|
||||
notifications.Notify(suggestUsingStaleCacheNotification)
|
||||
}
|
||||
|
||||
|
|
@ -108,3 +138,29 @@ func suggestUsingStaleCacheTask(_ *mgr.WorkerCtx) error {
|
|||
resetSlowQueriesSensorValue()
|
||||
return nil
|
||||
}
|
||||
|
||||
// === Notification state persistence ===
|
||||
|
||||
// markerRecord is a minimal database record used as a presence-only marker.
|
||||
type markerRecord struct {
|
||||
record.Base
|
||||
sync.Mutex
|
||||
}
|
||||
|
||||
var db = database.NewInterface(&database.Options{Local: true, Internal: true})
|
||||
|
||||
// Database key used to persist the user's choice to suppress the stale cache notification.
|
||||
const Notification_DB_ID_StaleCacheSuppressed = "core:notifications/resolver/StaleCache/suppressed"
|
||||
|
||||
// isNotificationSuppressed returns true if the user has chosen to never see the stale cache notification.
|
||||
func isNotificationSuppressed() bool {
|
||||
_, err := db.Get(Notification_DB_ID_StaleCacheSuppressed)
|
||||
return err == nil
|
||||
}
|
||||
|
||||
// suppressNotification persists the user's decision to never show the notification again.
|
||||
func suppressNotification() error {
|
||||
m := &markerRecord{}
|
||||
m.SetKey(Notification_DB_ID_StaleCacheSuppressed)
|
||||
return db.Put(m)
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue