aboutsummaryrefslogtreecommitdiffstats
path: root/internal/notify/files.go
diff options
context:
space:
mode:
authorDanilo M. <danix@danix.xyz>2026-09-15 17:59:35 +0200
committerDanilo M. <danix@danix.xyz>2026-09-15 17:59:35 +0200
commit3b8a0e0f4a5c28394ac578e8559bf57ae82d3fd2 (patch)
treefafa293256cca4615e4725553a391bf8dfdee99b /internal/notify/files.go
parenta248608721e813d5e6d19fc79d2505a2a8c2716a (diff)
downloadnotifyd-3b8a0e0f4a5c28394ac578e8559bf57ae82d3fd2.tar.gz
notifyd-3b8a0e0f4a5c28394ac578e8559bf57ae82d3fd2.zip
feat(notify): add the image field and its cleanup
Popup gains image, and the store calls an injected removeImage when an entry is dismissed, evicted, replaced or expired, so a daemon-written PNG does not outlive its balloon. The service decides what is daemon-owned; the store only names the path. NewStore now takes the callback as a third parameter, so the service wires its removeImage in (unlinking only under ImagesDir) and the existing call sites pass nil.
Diffstat (limited to 'internal/notify/files.go')
-rw-r--r--internal/notify/files.go34
1 files changed, 34 insertions, 0 deletions
diff --git a/internal/notify/files.go b/internal/notify/files.go
index 53e7f3f..e4da336 100644
--- a/internal/notify/files.go
+++ b/internal/notify/files.go
@@ -15,6 +15,7 @@ import (
"encoding/json"
"os"
"path/filepath"
+ "strconv"
)
// RuntimeDir is where the daemon publishes. It is tmpfs, so a reboot clears
@@ -45,6 +46,39 @@ func Publish(dir string, live, history []Popup) error {
return writeJSON(filepath.Join(dir, "history.json"), history)
}
+// ImagesDir is where the daemon writes decoded image-data.
+func ImagesDir(dir string) string {
+ return filepath.Join(dir, "img")
+}
+
+// WriteImage writes a decoded image as <id>.png under the image directory.
+func WriteImage(dir string, id uint32, data []byte) (string, error) {
+ imgDir := ImagesDir(dir)
+ if err := os.MkdirAll(imgDir, 0o700); err != nil {
+ return "", err
+ }
+ path := filepath.Join(imgDir, strconv.FormatUint(uint64(id), 10)+".png")
+ tmp, err := os.CreateTemp(imgDir, ".img-*")
+ if err != nil {
+ return "", err
+ }
+ tmpName := tmp.Name()
+ if _, err := tmp.Write(data); err != nil {
+ tmp.Close()
+ os.Remove(tmpName)
+ return "", err
+ }
+ if err := tmp.Close(); err != nil {
+ os.Remove(tmpName)
+ return "", err
+ }
+ if err := os.Rename(tmpName, path); err != nil {
+ os.Remove(tmpName)
+ return "", err
+ }
+ return path, nil
+}
+
func writeJSON(path string, v any) error {
data, err := json.Marshal(v)
if err != nil {