emoji_favorites.go 1.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566
  1. package chat
  2. import (
  3. "encoding/json"
  4. "log/slog"
  5. "os"
  6. "path/filepath"
  7. "sync"
  8. "github.com/ayn2op/discordo/internal/consts"
  9. )
  10. const maxFavoriteEmoji = 10
  11. type emojiFavorites struct {
  12. Favorites []string `json:"favorites"`
  13. mu sync.RWMutex
  14. }
  15. var emojiFavoritesPath = filepath.Join(consts.CacheDir(), "emoji_favorites.json")
  16. func loadEmojiFavorites() *emojiFavorites {
  17. ef := &emojiFavorites{}
  18. data, err := os.ReadFile(emojiFavoritesPath)
  19. if err != nil {
  20. return ef
  21. }
  22. if err := json.Unmarshal(data, ef); err != nil {
  23. slog.Warn("failed to parse emoji favorites", "err", err)
  24. return &emojiFavorites{}
  25. }
  26. return ef
  27. }
  28. func (ef *emojiFavorites) save() {
  29. ef.mu.RLock()
  30. defer ef.mu.RUnlock()
  31. atomicSaveJSON(emojiFavoritesPath, ef)
  32. }
  33. func (ef *emojiFavorites) toggle(emoji string) {
  34. ef.mu.Lock()
  35. for i, e := range ef.Favorites {
  36. if e == emoji {
  37. ef.Favorites = append(ef.Favorites[:i], ef.Favorites[i+1:]...)
  38. ef.mu.Unlock()
  39. ef.save()
  40. return
  41. }
  42. }
  43. if len(ef.Favorites) >= maxFavoriteEmoji {
  44. ef.mu.Unlock()
  45. return
  46. }
  47. ef.Favorites = append(ef.Favorites, emoji)
  48. ef.mu.Unlock()
  49. ef.save()
  50. }
  51. func (ef *emojiFavorites) list() []string {
  52. ef.mu.RLock()
  53. defer ef.mu.RUnlock()
  54. out := make([]string, len(ef.Favorites))
  55. copy(out, ef.Favorites)
  56. return out
  57. }