package chat import ( "encoding/json" "log/slog" "os" "path/filepath" "sync" "github.com/ayn2op/discordo/internal/consts" ) const maxFavoriteEmoji = 10 type emojiFavorites struct { Favorites []string `json:"favorites"` mu sync.RWMutex } var emojiFavoritesPath = filepath.Join(consts.CacheDir(), "emoji_favorites.json") func loadEmojiFavorites() *emojiFavorites { ef := &emojiFavorites{} data, err := os.ReadFile(emojiFavoritesPath) if err != nil { return ef } if err := json.Unmarshal(data, ef); err != nil { slog.Warn("failed to parse emoji favorites", "err", err) return &emojiFavorites{} } return ef } func (ef *emojiFavorites) save() { ef.mu.RLock() defer ef.mu.RUnlock() atomicSaveJSON(emojiFavoritesPath, ef) } func (ef *emojiFavorites) toggle(emoji string) { ef.mu.Lock() for i, e := range ef.Favorites { if e == emoji { ef.Favorites = append(ef.Favorites[:i], ef.Favorites[i+1:]...) ef.mu.Unlock() ef.save() return } } if len(ef.Favorites) >= maxFavoriteEmoji { ef.mu.Unlock() return } ef.Favorites = append(ef.Favorites, emoji) ef.mu.Unlock() ef.save() } func (ef *emojiFavorites) list() []string { ef.mu.RLock() defer ef.mu.RUnlock() out := make([]string, len(ef.Favorites)) copy(out, ef.Favorites) return out }