125 lines
2.5 KiB
Go
125 lines
2.5 KiB
Go
package ironnotify
|
|
|
|
import (
|
|
"encoding/json"
|
|
"fmt"
|
|
"os"
|
|
"path/filepath"
|
|
"sync"
|
|
)
|
|
|
|
// OfflineQueue stores notifications when offline.
|
|
type OfflineQueue struct {
|
|
maxSize int
|
|
debug bool
|
|
queue []NotificationPayload
|
|
storagePath string
|
|
mu sync.Mutex
|
|
}
|
|
|
|
// NewOfflineQueue creates a new OfflineQueue.
|
|
func NewOfflineQueue(maxSize int, debug bool) *OfflineQueue {
|
|
homeDir, _ := os.UserHomeDir()
|
|
storagePath := filepath.Join(homeDir, ".ironnotify", "offline_queue.json")
|
|
|
|
q := &OfflineQueue{
|
|
maxSize: maxSize,
|
|
debug: debug,
|
|
queue: make([]NotificationPayload, 0),
|
|
storagePath: storagePath,
|
|
}
|
|
|
|
q.loadFromStorage()
|
|
return q
|
|
}
|
|
|
|
// Add adds a notification to the queue.
|
|
func (q *OfflineQueue) Add(payload NotificationPayload) {
|
|
q.mu.Lock()
|
|
defer q.mu.Unlock()
|
|
|
|
if len(q.queue) >= q.maxSize {
|
|
q.queue = q.queue[1:]
|
|
if q.debug {
|
|
fmt.Println("[IronNotify] Offline queue full, dropping oldest notification")
|
|
}
|
|
}
|
|
|
|
q.queue = append(q.queue, payload)
|
|
q.saveToStorage()
|
|
|
|
if q.debug {
|
|
fmt.Printf("[IronNotify] Notification queued for later: %s\n", payload.EventType)
|
|
}
|
|
}
|
|
|
|
// GetAll returns all queued notifications.
|
|
func (q *OfflineQueue) GetAll() []NotificationPayload {
|
|
q.mu.Lock()
|
|
defer q.mu.Unlock()
|
|
|
|
result := make([]NotificationPayload, len(q.queue))
|
|
copy(result, q.queue)
|
|
return result
|
|
}
|
|
|
|
// Remove removes a notification at the given index.
|
|
func (q *OfflineQueue) Remove(index int) {
|
|
q.mu.Lock()
|
|
defer q.mu.Unlock()
|
|
|
|
if index >= 0 && index < len(q.queue) {
|
|
q.queue = append(q.queue[:index], q.queue[index+1:]...)
|
|
q.saveToStorage()
|
|
}
|
|
}
|
|
|
|
// Clear clears the queue.
|
|
func (q *OfflineQueue) Clear() {
|
|
q.mu.Lock()
|
|
defer q.mu.Unlock()
|
|
|
|
q.queue = make([]NotificationPayload, 0)
|
|
q.saveToStorage()
|
|
}
|
|
|
|
// Size returns the queue size.
|
|
func (q *OfflineQueue) Size() int {
|
|
q.mu.Lock()
|
|
defer q.mu.Unlock()
|
|
return len(q.queue)
|
|
}
|
|
|
|
// IsEmpty checks if the queue is empty.
|
|
func (q *OfflineQueue) IsEmpty() bool {
|
|
q.mu.Lock()
|
|
defer q.mu.Unlock()
|
|
return len(q.queue) == 0
|
|
}
|
|
|
|
func (q *OfflineQueue) loadFromStorage() {
|
|
data, err := os.ReadFile(q.storagePath)
|
|
if err != nil {
|
|
return
|
|
}
|
|
|
|
var queue []NotificationPayload
|
|
if err := json.Unmarshal(data, &queue); err == nil {
|
|
q.queue = queue
|
|
}
|
|
}
|
|
|
|
func (q *OfflineQueue) saveToStorage() {
|
|
dir := filepath.Dir(q.storagePath)
|
|
if err := os.MkdirAll(dir, 0755); err != nil {
|
|
return
|
|
}
|
|
|
|
data, err := json.Marshal(q.queue)
|
|
if err != nil {
|
|
return
|
|
}
|
|
|
|
_ = os.WriteFile(q.storagePath, data, 0644)
|
|
}
|