diff --git a/protocol/communities/community.go b/protocol/communities/community.go index 1973bf456..f0f053fd3 100644 --- a/protocol/communities/community.go +++ b/protocol/communities/community.go @@ -450,19 +450,20 @@ func (o *Community) CommunityTokensMetadata() []*protobuf.CommunityTokenMetadata } func (o *Community) Tags() []CommunityTag { - if o != nil && - o.config != nil && - o.config.CommunityDescription != nil { - var result []CommunityTag - for _, t := range o.config.CommunityDescription.Tags { - result = append(result, CommunityTag{ - Name: t, - Emoji: requests.TagsEmojies[t], - }) - } - return result + if o == nil || + o.config == nil || + o.config.CommunityDescription == nil { + return nil } - return nil + + result := make([]CommunityTag, 0, len(o.config.CommunityDescription.Tags)) + for _, t := range o.config.CommunityDescription.Tags { + result = append(result, CommunityTag{ + Name: t, + Emoji: requests.TagEmoji(t), + }) + } + return result } func (o *Community) TagsRaw() []string { @@ -470,17 +471,10 @@ func (o *Community) TagsRaw() []string { } func (o *Community) TagsIndices() []uint32 { - indices := []uint32{} + var indices []uint32 for _, t := range o.config.CommunityDescription.Tags { - i := uint32(0) - for k := range requests.TagsEmojies { - if k == t { - indices = append(indices, i) - } - i++ - } + indices = append(indices, requests.TagIndex(t)) } - return indices } diff --git a/protocol/messenger_share_urls_test.go b/protocol/messenger_share_urls_test.go index bc4f085aa..50fee7ba2 100644 --- a/protocol/messenger_share_urls_test.go +++ b/protocol/messenger_share_urls_test.go @@ -41,9 +41,10 @@ func (s *MessengerShareUrlsSuite) createCommunity() *communities.Community { Name: "status", Color: "#ffffff", Description: "status community description", + Tags: RandomCommunityTags(3), } - // Create an community chat + // Create a community chat response, err := s.m.CreateCommunity(description, false) s.Require().NoError(err) s.Require().NotNil(response) @@ -245,6 +246,13 @@ func (s *MessengerShareUrlsSuite) TestShareCommunityURLWithData() { expectedURL := fmt.Sprintf("%s/c/%s#%s", baseShareURL, communityData, chatKey) s.Require().Equal(expectedURL, url) + + response, err := ParseSharedURL(url) + s.Require().NoError(err) + s.Require().NotNil(response) + s.Require().NotNil(response.Community) + s.Require().Equal(community.IDString(), response.Community.CommunityID) + s.Require().Equal(community.TagsIndices(), response.Community.TagIndices) } func (s *MessengerShareUrlsSuite) TestParseCommunityURLWithData() { diff --git a/protocol/messenger_testing_utils.go b/protocol/messenger_testing_utils.go index 63f016950..dca4ca37a 100644 --- a/protocol/messenger_testing_utils.go +++ b/protocol/messenger_testing_utils.go @@ -6,6 +6,7 @@ import ( "errors" "fmt" "math/big" + mathRand "math/rand" "sync" "time" @@ -16,8 +17,6 @@ import ( "github.com/status-im/status-go/eth-node/types" waku2 "github.com/status-im/status-go/wakuv2" - "golang.org/x/exp/maps" - "github.com/stretchr/testify/suite" "github.com/status-im/status-go/protocol/common" @@ -391,20 +390,20 @@ func RandomColor() string { } func RandomCommunityTags(count int) []string { - all := maps.Keys(requests.TagsEmojies) - tags := make([]string, 0, count) - indexes := map[int]struct{}{} + availableTagsCount := requests.AvailableTagsCount() - for len(indexes) != count { - index := randomInt(len(all)) - indexes[index] = struct{}{} + if count > availableTagsCount { + count = availableTagsCount } - for index := range indexes { - tags = append(tags, all[index]) + //source := mathRand.New(mathRand.NewSource(time.Now().UnixNano())) + indices := mathRand.Perm(availableTagsCount) + shuffled := make([]string, count) + for i := 0; i < count; i++ { + shuffled[i] = requests.TagByIndex(uint32(indices[i])) } - return tags + return shuffled } func RandomBytes(length int) []byte { diff --git a/protocol/requests/community_tags.go b/protocol/requests/community_tags.go index 0e50b19a7..df988e8f3 100644 --- a/protocol/requests/community_tags.go +++ b/protocol/requests/community_tags.go @@ -1,66 +1,24 @@ package requests -var TagsEmojies map[string]string +var tags []string +var tagsEmojis map[string]string +var tagsIndices map[string]uint32 func init() { - TagsEmojies = make(map[string]string) - TagsEmojies["Activism"] = "โœŠ" - TagsEmojies["Art"] = "๐ŸŽจ" - TagsEmojies["Blockchain"] = "๐Ÿ”—" - TagsEmojies["Books & blogs"] = "๐Ÿ“š" - TagsEmojies["Career"] = "๐Ÿ’ผ" - TagsEmojies["Collaboration"] = "๐Ÿค" - TagsEmojies["Commerce"] = "๐Ÿ›’" - TagsEmojies["Culture"] = "๐ŸŽŽ" - TagsEmojies["DAO"] = "๐Ÿš€" - TagsEmojies["DeFi"] = "๐Ÿ“ˆ" - TagsEmojies["Design"] = "๐Ÿงฉ" - TagsEmojies["DIY"] = "๐Ÿ”จ" - TagsEmojies["Environment"] = "๐ŸŒฟ" - TagsEmojies["Education"] = "๐ŸŽ’" - TagsEmojies["Entertainment"] = "๐Ÿฟ" - TagsEmojies["Ethereum"] = "ฮž" - TagsEmojies["Event"] = "๐Ÿ—“" - TagsEmojies["Fantasy"] = "๐Ÿง™โ€โ™‚๏ธ" - TagsEmojies["Fashion"] = "๐Ÿงฆ" - TagsEmojies["Food"] = "๐ŸŒถ" - TagsEmojies["Gaming"] = "๐ŸŽฎ" - TagsEmojies["Global"] = "๐ŸŒ" - TagsEmojies["Health"] = "๐Ÿง " - TagsEmojies["Hobby"] = "๐Ÿ“" - TagsEmojies["Innovation"] = "๐Ÿงช" - TagsEmojies["Language"] = "๐Ÿ“œ" - TagsEmojies["Lifestyle"] = "โœจ" - TagsEmojies["Local"] = "๐Ÿ“" - TagsEmojies["Love"] = "โค๏ธ" - TagsEmojies["Markets"] = "๐Ÿ’Ž" - TagsEmojies["Movies & TV"] = "๐ŸŽž" - TagsEmojies["Music"] = "๐ŸŽถ" - TagsEmojies["News"] = "๐Ÿ—ž" - TagsEmojies["NFT"] = "๐Ÿ–ผ" - TagsEmojies["Non-profit"] = "๐Ÿ™" - TagsEmojies["NSFW"] = "๐Ÿ†" - TagsEmojies["Org"] = "๐Ÿข" - TagsEmojies["Pets"] = "๐Ÿถ" - TagsEmojies["Play"] = "๐ŸŽฒ" - TagsEmojies["Podcast"] = "๐ŸŽ™๏ธ" - TagsEmojies["Politics"] = "๐Ÿ—ณ๏ธ" - TagsEmojies["Product"] = "๐Ÿฑ" - TagsEmojies["Psyche"] = "๐Ÿ" - TagsEmojies["Privacy"] = "๐Ÿ‘ป" - TagsEmojies["Security"] = "๐Ÿ”’" - TagsEmojies["Social"] = "โ˜•" - TagsEmojies["Software dev"] = "๐Ÿ‘ฉโ€๐Ÿ’ป" - TagsEmojies["Sports"] = "โšฝ๏ธ" - TagsEmojies["Tech"] = "๐Ÿ“ฑ" - TagsEmojies["Travel"] = "๐Ÿ—บ" - TagsEmojies["Vehicles"] = "๐Ÿš•" - TagsEmojies["Web3"] = "๐ŸŒ" + tags = make([]string, 0, len(allTags)) + tagsEmojis = make(map[string]string, len(allTags)) + tagsIndices = make(map[string]uint32, len(allTags)) + + for i, pair := range allTags { + tags = append(tags, pair[0]) + tagsEmojis[pair[0]] = pair[1] + tagsIndices[pair[0]] = uint32(i) + } } func ValidateTags(input []string) bool { for _, t := range input { - _, ok := TagsEmojies[t] + _, ok := tagsEmojis[t] if !ok { return false } @@ -73,7 +31,7 @@ func ValidateTags(input []string) bool { func RemoveUnknownAndDeduplicateTags(input []string) []string { var result []string for _, t := range input { - _, ok := TagsEmojies[t] + _, ok := tagsEmojis[t] if ok { result = append(result, t) } @@ -92,3 +50,83 @@ func unique(slice []string) []string { } return uniqSlice } + +func TagByIndex(i uint32) string { + return tags[i] +} + +func TagEmoji(tag string) string { + return tagsEmojis[tag] +} + +func TagIndex(tag string) uint32 { + return tagsIndices[tag] +} + +func AvailableTagsCount() int { + return len(tags) +} + +func AvailableTagsEmojis() map[string]string { + // Make a deep copy of the map to keep it immutable + emojis := make(map[string]string, len(tagsEmojis)) + for t, e := range tagsEmojis { + emojis[t] = e + } + return emojis +} + +var allTags = [][]string{ + {"Activism", "โœŠ"}, + {"Art", "๐ŸŽจ"}, + {"Blockchain", "๐Ÿ”—"}, + {"Books & blogs", "๐Ÿ“š"}, + {"Career", "๐Ÿ’ผ"}, + {"Collaboration", "๐Ÿค"}, + {"Commerce", "๐Ÿ›’"}, + {"Culture", "๐ŸŽŽ"}, + {"DAO", "๐Ÿš€"}, + {"DeFi", "๐Ÿ“ˆ"}, + {"Design", "๐Ÿงฉ"}, + {"DIY", "๐Ÿ”จ"}, + {"Environment", "๐ŸŒฟ"}, + {"Education", "๐ŸŽ’"}, + {"Entertainment", "๐Ÿฟ"}, + {"Ethereum", "ฮž"}, + {"Event", "๐Ÿ—“"}, + {"Fantasy", "๐Ÿง™โ€โ™‚๏ธ"}, + {"Fashion", "๐Ÿงฆ"}, + {"Food", "๐ŸŒถ"}, + {"Gaming", "๐ŸŽฎ"}, + {"Global", "๐ŸŒ"}, + {"Health", "๐Ÿง "}, + {"Hobby", "๐Ÿ“"}, + {"Innovation", "๐Ÿงช"}, + {"Language", "๐Ÿ“œ"}, + {"Lifestyle", "โœจ"}, + {"Local", "๐Ÿ“"}, + {"Love", "โค๏ธ"}, + {"Markets", "๐Ÿ’Ž"}, + {"Movies & TV", "๐ŸŽž"}, + {"Music", "๐ŸŽถ"}, + {"News", "๐Ÿ—ž"}, + {"NFT", "๐Ÿ–ผ"}, + {"Non-profit", "๐Ÿ™"}, + {"NSFW", "๐Ÿ†"}, + {"Org", "๐Ÿข"}, + {"Pets", "๐Ÿถ"}, + {"Play", "๐ŸŽฒ"}, + {"Podcast", "๐ŸŽ™๏ธ"}, + {"Politics", "๐Ÿ—ณ๏ธ"}, + {"Product", "๐Ÿฑ"}, + {"Psyche", "๐Ÿ"}, + {"Privacy", "๐Ÿ‘ป"}, + {"Security", "๐Ÿ”’"}, + {"Social", "โ˜•"}, + {"Software dev", "๐Ÿ‘ฉโ€๐Ÿ’ป"}, + {"Sports", "โšฝ๏ธ"}, + {"Tech", "๐Ÿ“ฑ"}, + {"Travel", "๐Ÿ—บ"}, + {"Vehicles", "๐Ÿš•"}, + {"Web3", "๐ŸŒ"}, +} diff --git a/services/ext/api.go b/services/ext/api.go index 36d2057f4..01232e7c8 100644 --- a/services/ext/api.go +++ b/services/ext/api.go @@ -408,7 +408,7 @@ func (api *PublicAPI) IsDisplayNameDupeOfCommunityMember(name string) (bool, err // CommunityTags return the list of possible community tags func (api *PublicAPI) CommunityTags(parent context.Context) map[string]string { - return requests.TagsEmojies + return requests.AvailableTagsEmojis() } // CuratedCommunities returns the list of curated communities stored in the smart contract. If a community is