39 lines
1.1 KiB
Go
39 lines
1.1 KiB
Go
// Package icon carries the talk icon for the desktop: the PNG is embedded
|
|||
|
|
// in the binary and written next to the config so the OS can show it in
|
||
|
|
// notifications (Windows toast identity, freedesktop app_icon). The source
|
||
|
|
// is assets/icon/talk.svg; `go run assets/icon/gen.go` renders it, the
|
||
|
|
// Windows .ico and the resource objects for talk.exe.
|
||
|
|
package icon
|
||
|
|
|
||
|
|
import (
|
||
|
|
"bytes"
|
||
|
|
_ "embed"
|
||
|
|
"errors"
|
||
|
|
"os"
|
||
|
|
"path/filepath"
|
||
|
|
)
|
||
|
|
|
||
|
|
//go:embed talk.png
|
||
|
|
var PNG []byte
|
||
|
|
|
||
|
|
// FileName is the icon's name in the config directory.
|
||
|
|
const FileName = "talk.png"
|
||
|
|
|
||
|
|
// Install writes the icon into dir (if missing or outdated) and returns its
|
||
|
|
// path. Idempotent: an unchanged file is not touched.
|
||
|
|
func Install(dir string) (string, error) {
|
||
|
|
if dir == "" {
|
||
|
|
return "", errors.New("icon: no directory")
|
||
|
|
}
|
||
|
|
path := filepath.Join(dir, FileName)
|
||
|
|
if cur, err := os.ReadFile(path); err == nil && bytes.Equal(cur, PNG) {
|
||
|
|
return path, nil
|
||
|
|
}
|
||
|
|
if err := os.MkdirAll(dir, 0o755); err != nil {
|
||
|
|
return "", err
|
||
|
|
}
|
||
|
|
if err := os.WriteFile(path, PNG, 0o644); err != nil {
|
||
|
|
return "", err
|
||
|
|
}
|
||
|
|
return path, nil
|
||
|
|
}
|