diff options
| author | AlexanderCurl <alexc@alexc.hu> | 2026-04-18 17:46:06 +0100 |
|---|---|---|
| committer | AlexanderCurl <alexc@alexc.hu> | 2026-04-18 17:46:06 +0100 |
| commit | 70ca3fef77ee8bdc6e3ac28589a6fa08c024cc69 (patch) | |
| tree | ab1123d4067c1b086dd6faa7ee4ea643236b565a /raveos-hyprland-theme/theme-data/DankMaterialShell/core/internal/server/location | |
| parent | 5d94c0a7d44a2255b81815a52a7056a94a39842d (diff) | |
| download | RaveOS-PKGBUILD-70ca3fef77ee8bdc6e3ac28589a6fa08c024cc69.tar.gz RaveOS-PKGBUILD-70ca3fef77ee8bdc6e3ac28589a6fa08c024cc69.zip | |
Replaced file structures for themes in the correct format
Diffstat (limited to 'raveos-hyprland-theme/theme-data/DankMaterialShell/core/internal/server/location')
3 files changed, 264 insertions, 0 deletions
diff --git a/raveos-hyprland-theme/theme-data/DankMaterialShell/core/internal/server/location/handlers.go b/raveos-hyprland-theme/theme-data/DankMaterialShell/core/internal/server/location/handlers.go new file mode 100644 index 0000000..c9d556c --- /dev/null +++ b/raveos-hyprland-theme/theme-data/DankMaterialShell/core/internal/server/location/handlers.go @@ -0,0 +1,61 @@ +package location + +import ( + "encoding/json" + "fmt" + "net" + + "github.com/AvengeMedia/DankMaterialShell/core/internal/server/models" +) + +type LocationEvent struct { + Type string `json:"type"` + Data State `json:"data"` +} + +func HandleRequest(conn net.Conn, req models.Request, manager *Manager) { + switch req.Method { + case "location.getState": + handleGetState(conn, req, manager) + case "location.subscribe": + handleSubscribe(conn, req, manager) + + default: + models.RespondError(conn, req.ID, fmt.Sprintf("unknown method: %s", req.Method)) + } +} + +func handleGetState(conn net.Conn, req models.Request, manager *Manager) { + models.Respond(conn, req.ID, manager.GetState()) +} + +func handleSubscribe(conn net.Conn, req models.Request, manager *Manager) { + clientID := fmt.Sprintf("client-%p", conn) + stateChan := manager.Subscribe(clientID) + defer manager.Unsubscribe(clientID) + + initialState := manager.GetState() + event := LocationEvent{ + Type: "state_changed", + Data: initialState, + } + + if err := json.NewEncoder(conn).Encode(models.Response[LocationEvent]{ + ID: req.ID, + Result: &event, + }); err != nil { + return + } + + for state := range stateChan { + event := LocationEvent{ + Type: "state_changed", + Data: state, + } + if err := json.NewEncoder(conn).Encode(models.Response[LocationEvent]{ + Result: &event, + }); err != nil { + return + } + } +} diff --git a/raveos-hyprland-theme/theme-data/DankMaterialShell/core/internal/server/location/manager.go b/raveos-hyprland-theme/theme-data/DankMaterialShell/core/internal/server/location/manager.go new file mode 100644 index 0000000..24bcd95 --- /dev/null +++ b/raveos-hyprland-theme/theme-data/DankMaterialShell/core/internal/server/location/manager.go @@ -0,0 +1,175 @@ +package location + +import ( + "time" + + "github.com/AvengeMedia/DankMaterialShell/core/internal/geolocation" + "github.com/AvengeMedia/DankMaterialShell/core/internal/log" +) + +func NewManager(client geolocation.Client) (*Manager, error) { + currLocation, err := client.GetLocation() + if err != nil { + log.Warnf("Failed to get initial location: %v", err) + } + + m := &Manager{ + client: client, + dirty: make(chan struct{}), + stopChan: make(chan struct{}), + + state: &State{ + Latitude: currLocation.Latitude, + Longitude: currLocation.Longitude, + }, + } + + if err := m.startSignalPump(); err != nil { + return nil, err + } + + m.notifierWg.Add(1) + go m.notifier() + + return m, nil +} + +func (m *Manager) Close() { + close(m.stopChan) + m.notifierWg.Wait() + + m.sigWG.Wait() + + m.subscribers.Range(func(key string, ch chan State) bool { + close(ch) + m.subscribers.Delete(key) + return true + }) +} + +func (m *Manager) Subscribe(id string) chan State { + ch := make(chan State, 64) + m.subscribers.Store(id, ch) + return ch +} + +func (m *Manager) Unsubscribe(id string) { + if ch, ok := m.subscribers.LoadAndDelete(id); ok { + close(ch) + } +} + +func (m *Manager) startSignalPump() error { + m.sigWG.Add(1) + go func() { + defer m.sigWG.Done() + + subscription := m.client.Subscribe("locationManager") + defer m.client.Unsubscribe("locationManager") + + for { + select { + case <-m.stopChan: + return + case location, ok := <-subscription: + if !ok { + return + } + + m.handleLocationChange(location) + } + } + }() + + return nil +} + +func (m *Manager) handleLocationChange(location geolocation.Location) { + m.stateMutex.Lock() + defer m.stateMutex.Unlock() + + m.state.Latitude = location.Latitude + m.state.Longitude = location.Longitude + + m.notifySubscribers() +} + +func (m *Manager) notifySubscribers() { + select { + case m.dirty <- struct{}{}: + default: + } +} + +func (m *Manager) GetState() State { + m.stateMutex.RLock() + defer m.stateMutex.RUnlock() + if m.state == nil { + return State{ + Latitude: 0.0, + Longitude: 0.0, + } + } + stateCopy := *m.state + return stateCopy +} + +func (m *Manager) notifier() { + defer m.notifierWg.Done() + const minGap = 200 * time.Millisecond + timer := time.NewTimer(minGap) + timer.Stop() + var pending bool + + for { + select { + case <-m.stopChan: + timer.Stop() + return + case <-m.dirty: + if pending { + continue + } + pending = true + timer.Reset(minGap) + case <-timer.C: + if !pending { + continue + } + + currentState := m.GetState() + + if m.lastNotified != nil && !stateChanged(m.lastNotified, ¤tState) { + pending = false + continue + } + + m.subscribers.Range(func(key string, ch chan State) bool { + select { + case ch <- currentState: + default: + log.Warn("Location: subscriber channel full, dropping update") + } + return true + }) + + stateCopy := currentState + m.lastNotified = &stateCopy + pending = false + } + } +} + +func stateChanged(old, new *State) bool { + if old == nil || new == nil { + return true + } + if old.Latitude != new.Latitude { + return true + } + if old.Longitude != new.Longitude { + return true + } + + return false +} diff --git a/raveos-hyprland-theme/theme-data/DankMaterialShell/core/internal/server/location/types.go b/raveos-hyprland-theme/theme-data/DankMaterialShell/core/internal/server/location/types.go new file mode 100644 index 0000000..1f3d518 --- /dev/null +++ b/raveos-hyprland-theme/theme-data/DankMaterialShell/core/internal/server/location/types.go @@ -0,0 +1,28 @@ +package location + +import ( + "sync" + + "github.com/AvengeMedia/DankMaterialShell/core/internal/geolocation" + "github.com/AvengeMedia/DankMaterialShell/core/pkg/syncmap" +) + +type State struct { + Latitude float64 `json:"latitude"` + Longitude float64 `json:"longitude"` +} + +type Manager struct { + state *State + stateMutex sync.RWMutex + + client geolocation.Client + + stopChan chan struct{} + sigWG sync.WaitGroup + + subscribers syncmap.Map[string, chan State] + dirty chan struct{} + notifierWg sync.WaitGroup + lastNotified *State +} |