ironnotify-go/queue.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)
}