emoji_favorites.go 1.8 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889
  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. data, err := json.Marshal(ef)
  31. ef.mu.RUnlock()
  32. if err != nil {
  33. slog.Error("failed to marshal emoji favorites", "err", err)
  34. return
  35. }
  36. tmpPath := emojiFavoritesPath + ".tmp"
  37. if err := os.WriteFile(tmpPath, data, 0600); err != nil {
  38. slog.Error("failed to write emoji favorites", "err", err)
  39. return
  40. }
  41. if err := os.Rename(tmpPath, emojiFavoritesPath); err != nil {
  42. slog.Error("failed to rename emoji favorites file", "err", err)
  43. }
  44. }
  45. func (ef *emojiFavorites) isFavorite(emoji string) bool {
  46. ef.mu.RLock()
  47. defer ef.mu.RUnlock()
  48. for _, e := range ef.Favorites {
  49. if e == emoji {
  50. return true
  51. }
  52. }
  53. return false
  54. }
  55. func (ef *emojiFavorites) toggle(emoji string) {
  56. ef.mu.Lock()
  57. for i, e := range ef.Favorites {
  58. if e == emoji {
  59. ef.Favorites = append(ef.Favorites[:i], ef.Favorites[i+1:]...)
  60. ef.mu.Unlock()
  61. ef.save()
  62. return
  63. }
  64. }
  65. if len(ef.Favorites) >= maxFavoriteEmoji {
  66. ef.mu.Unlock()
  67. return
  68. }
  69. ef.Favorites = append(ef.Favorites, emoji)
  70. ef.mu.Unlock()
  71. ef.save()
  72. }
  73. func (ef *emojiFavorites) list() []string {
  74. ef.mu.RLock()
  75. defer ef.mu.RUnlock()
  76. out := make([]string, len(ef.Favorites))
  77. copy(out, ef.Favorites)
  78. return out
  79. }