mirror of
https://github.com/netbirdio/netbird.git
synced 2026-08-26 17:41:30 +02:00
Files move directly between peers over the overlay, with no server in the path. The receiver listens on the WireGuard address only, so the port is unreachable from outside the tunnel, and every offer is matched to a known peer before anything is read. Consent is the default: an offer carries metadata alone, and no payload moves until the receiver accepts. Policy is per profile and device-local — off, ask, or auto-accept, with per-sender exceptions on top. Policy and history live in the profile's preferences, so removing a profile takes its file drop state with it. Transfers interrupted by a restart are settled on load; nothing survives to finish them, and left alone they would sit in the log as permanently pending. The Android bindings pull payload bytes through a chunk-returning stream: gomobile copies a []byte argument into a fresh Java array and never copies it back, so a fill-my-buffer method would hand back the right length with no data.
110 lines
3.4 KiB
Go
110 lines
3.4 KiB
Go
//go:build !android && !ios && !freebsd && !js
|
|
|
|
package main
|
|
|
|
import (
|
|
"context"
|
|
"errors"
|
|
"sync/atomic"
|
|
|
|
log "github.com/sirupsen/logrus"
|
|
"github.com/wailsapp/wails/v3/pkg/application"
|
|
"github.com/wailsapp/wails/v3/pkg/services/notifications"
|
|
)
|
|
|
|
var errNotificationsUnavailable = errors.New("notifications unavailable")
|
|
|
|
// Notifier wraps the Wails notification service so an unavailable backend
|
|
// disables notifications instead of aborting the app. Startup fails for
|
|
// environment reasons (a bare unbundled binary on macOS has no bundle
|
|
// identifier, a headless Linux session has no D-Bus session bus), and Wails
|
|
// treats a service startup error as fatal. After a failed startup every call
|
|
// is a no-op: on macOS, touching UNUserNotificationCenter without a bundle
|
|
// identifier raises an Objective-C exception that recover() cannot catch.
|
|
type Notifier struct {
|
|
inner *notifications.NotificationService
|
|
available atomic.Bool
|
|
}
|
|
|
|
func newNotifier() *Notifier {
|
|
return &Notifier{inner: notifications.New()}
|
|
}
|
|
|
|
// ServiceName implements the Wails service-name hook for startup logs.
|
|
func (n *Notifier) ServiceName() string {
|
|
return n.inner.ServiceName()
|
|
}
|
|
|
|
// ServiceStartup starts the platform notifier, downgrading failure to a
|
|
// warning so the app keeps running without notifications.
|
|
func (n *Notifier) ServiceStartup(ctx context.Context, options application.ServiceOptions) error {
|
|
if err := n.inner.ServiceStartup(ctx, options); err != nil {
|
|
log.Warnf("notifications disabled: %v", err)
|
|
return nil
|
|
}
|
|
n.available.Store(true)
|
|
return nil
|
|
}
|
|
|
|
func (n *Notifier) ServiceShutdown() error {
|
|
if !n.available.Load() {
|
|
return nil
|
|
}
|
|
return n.inner.ServiceShutdown()
|
|
}
|
|
|
|
func (n *Notifier) CheckNotificationAuthorization() (bool, error) {
|
|
if !n.available.Load() {
|
|
return false, errNotificationsUnavailable
|
|
}
|
|
return n.inner.CheckNotificationAuthorization()
|
|
}
|
|
|
|
func (n *Notifier) RequestNotificationAuthorization() (bool, error) {
|
|
if !n.available.Load() {
|
|
return false, errNotificationsUnavailable
|
|
}
|
|
return n.inner.RequestNotificationAuthorization()
|
|
}
|
|
|
|
// SendNotification delivers a notification, silently dropping it when the
|
|
// backend never started (notifications are best-effort everywhere).
|
|
func (n *Notifier) SendNotification(options notifications.NotificationOptions) error {
|
|
if !n.available.Load() {
|
|
log.Debugf("notifications disabled, dropping %q", options.ID)
|
|
return nil
|
|
}
|
|
return n.inner.SendNotification(options)
|
|
}
|
|
|
|
func (n *Notifier) SendNotificationWithActions(options notifications.NotificationOptions) error {
|
|
if !n.available.Load() {
|
|
log.Debugf("notifications disabled, dropping %q", options.ID)
|
|
return nil
|
|
}
|
|
return n.inner.SendNotificationWithActions(options)
|
|
}
|
|
|
|
// RemoveNotification withdraws a delivered notification, a no-op without a backend.
|
|
func (n *Notifier) RemoveNotification(identifier string) error {
|
|
if !n.available.Load() {
|
|
return nil
|
|
}
|
|
return n.inner.RemoveNotification(identifier)
|
|
}
|
|
|
|
func (n *Notifier) RegisterNotificationCategory(category notifications.NotificationCategory) error {
|
|
if !n.available.Load() {
|
|
return nil
|
|
}
|
|
return n.inner.RegisterNotificationCategory(category)
|
|
}
|
|
|
|
// OnNotificationResponse registers the response callback. Pure Go state, so
|
|
// it is safe (and simply inert) when the backend never started.
|
|
//
|
|
//wails:ignore
|
|
func (n *Notifier) OnNotificationResponse(callback func(result notifications.NotificationResult)) {
|
|
n.inner.OnNotificationResponse(callback)
|
|
}
|