Community categories (#2228)
* create and edit community categories * edit categories order * adding category to chat * Adding categories to json
This commit is contained in:
parent
beacc3233c
commit
92032c7158
|
@ -176,7 +176,7 @@ func (d *pathDecoder) parseSeparator() error {
|
|||
return d.saveSegment()
|
||||
}
|
||||
|
||||
return fmt.Errorf("expected %s, got %s", string(tokenSeparator), string(b))
|
||||
return fmt.Errorf("expected %s, got %s", string(rune(tokenSeparator)), string(b))
|
||||
}
|
||||
|
||||
func (d *pathDecoder) parseSegment() error {
|
||||
|
|
1
go.mod
1
go.mod
|
@ -78,6 +78,7 @@ require (
|
|||
golang.org/x/tools v0.0.0-20200211045251-2de505fc5306 // indirect
|
||||
google.golang.org/genproto v0.0.0-20191115221424-83cc0476cb11 // indirect
|
||||
google.golang.org/grpc v1.25.1 // indirect
|
||||
google.golang.org/protobuf v1.26.0-rc.1
|
||||
gopkg.in/go-playground/assert.v1 v1.2.1 // indirect
|
||||
gopkg.in/go-playground/validator.v9 v9.31.0
|
||||
gopkg.in/natefinch/lumberjack.v2 v2.0.0
|
||||
|
|
10
go.sum
10
go.sum
|
@ -202,6 +202,8 @@ github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMyw
|
|||
github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
|
||||
github.com/google/go-cmp v0.4.0 h1:xsAVV57WRhGj6kEIi8ReJzQlHHqcBYCElAvkovg3B/4=
|
||||
github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/google/go-cmp v0.5.5 h1:Khx7svrCpmxxtHBq5j2mp/xVjsi8hQMfNLvJFAlrGgU=
|
||||
github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/google/go-github v17.0.0+incompatible/go.mod h1:zLgOLi98H3fifZn+44m+umXrS52loVEgC2AApnigrVQ=
|
||||
github.com/google/go-querystring v1.0.0/go.mod h1:odCYkC5MyYFN7vkCjXpyrEuKhc/BUO6wN/zVPAxq5ck=
|
||||
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
|
||||
|
@ -850,23 +852,20 @@ google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiq
|
|||
google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg=
|
||||
google.golang.org/grpc v1.25.1 h1:wdKvqQk7IttEw92GoRyKG2IDrUIpgpj6H6m81yfeMW0=
|
||||
google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY=
|
||||
google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw=
|
||||
gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/check.v1 v1.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15 h1:YR8cESwS4TdDjEe65xsg0ogRM/Nc3DYOhEAlW+xobZo=
|
||||
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI=
|
||||
gopkg.in/fsnotify.v1 v1.4.7 h1:xOHLXZwVvI9hhs+cLKq5+I5onOuwQLhQwiu63xxlHs4=
|
||||
gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys=
|
||||
gopkg.in/go-playground/assert.v1 v1.2.1 h1:xoYuJVE7KT85PYWrN730RguIQO0ePzVRfFMXadIrXTM=
|
||||
gopkg.in/go-playground/assert.v1 v1.2.1/go.mod h1:9RXL0bg/zibRAgZUYszZSwO/z8Y/a8bDuhia5mkpMnE=
|
||||
gopkg.in/go-playground/validator.v9 v9.31.0 h1:bmXmP2RSNtFES+bn4uYuHT7iJFJv7Vj+an+ZQdDaD1M=
|
||||
gopkg.in/go-playground/validator.v9 v9.31.0/go.mod h1:+c9/zcJMFNgbLvly1L1V+PpxWdVbfP1avr/N00E2vyQ=
|
||||
gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw=
|
||||
gopkg.in/natefinch/lumberjack.v2 v2.0.0 h1:1Lc07Kr7qY4U2YPouBjpCLxpiyxIVoxqXgkXLknAOE8=
|
||||
gopkg.in/natefinch/lumberjack.v2 v2.0.0/go.mod h1:l0ndWWf7gzL7RNwBG7wST/UCcT4T24xpD6X8LsfU/+k=
|
||||
gopkg.in/natefinch/npipe.v2 v2.0.0-20160621034901-c1b8fa8bdcce h1:+JknDZhAj8YMt7GC73Ei8pv4MzjDUNPHgQWJdtMAaDU=
|
||||
gopkg.in/natefinch/npipe.v2 v2.0.0-20160621034901-c1b8fa8bdcce/go.mod h1:5AcXVHNjg+BDxry382+8OKon8SEWiKktQR07RKPsv1c=
|
||||
gopkg.in/olebedev/go-duktape.v3 v3.0.0-20180302121509-abf0ba0be5d5/go.mod h1:uAJfkITjFhyEEuUfm7bsmCZRbW5WRq8s9EY8HZ6hCns=
|
||||
gopkg.in/olebedev/go-duktape.v3 v3.0.0-20190709231704-1e4459ed25ff h1:uuol9OUzSvZntY1v963NAbVd7A+PHLMz1FlCe3Lorcs=
|
||||
|
@ -874,7 +873,6 @@ gopkg.in/olebedev/go-duktape.v3 v3.0.0-20190709231704-1e4459ed25ff/go.mod h1:uAJ
|
|||
gopkg.in/sourcemap.v1 v1.0.5/go.mod h1:2RlvNNSMglmRrcvhfuzp4hQHwOtjxlbjX7UPY/GXb78=
|
||||
gopkg.in/src-d/go-cli.v0 v0.0.0-20181105080154-d492247bbc0d/go.mod h1:z+K8VcOYVYcSwSjGebuDL6176A1XskgbtNl64NSg+n8=
|
||||
gopkg.in/src-d/go-log.v1 v1.0.1/go.mod h1:GN34hKP0g305ysm2/hctJ0Y8nWP3zxXXJ8GFabTyABE=
|
||||
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ=
|
||||
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw=
|
||||
gopkg.in/urfave/cli.v1 v1.20.0 h1:NdAVW6RYxDif9DhDHaAortIu956m2c0v+09AZBPTbE0=
|
||||
gopkg.in/urfave/cli.v1 v1.20.0/go.mod h1:vuBzUtMdQeixQj8LVd+/98pzhxNGQoyuPBlsXHOQNO0=
|
||||
|
@ -884,13 +882,11 @@ gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
|||
gopkg.in/yaml.v2 v2.2.5/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
gopkg.in/yaml.v2 v2.2.6 h1:97YCGUei5WVbkKfogoJQsLwUJ17cWvpLrgNvlcbxikE=
|
||||
gopkg.in/yaml.v2 v2.2.6/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
gotest.tools v2.2.0+incompatible h1:VsBPFP1AI068pPrMxtb/S8Zkgf9xEmTLJjfM+P5UIEo=
|
||||
gotest.tools v2.2.0+incompatible/go.mod h1:DsYFclhRJ6vuDpmuTbkuFWG+y2sxOXAzmJt81HFBacw=
|
||||
honnef.co/go/tools v0.0.0-20180728063816-88497007e858/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
||||
honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
||||
honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
||||
honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
||||
honnef.co/go/tools v0.0.1-2019.2.3 h1:3JgtbtFHMiCmsznwGVTUWbgGov+pVqnlf1dEJTNAXeM=
|
||||
honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg=
|
||||
modernc.org/b v1.0.0/go.mod h1:uZWcZfRj1BpYzfN9JTerzlNUnnPsV9O2ZA8JsRcubNg=
|
||||
modernc.org/db v1.0.0/go.mod h1:kYD/cO29L/29RM0hXYl4i3+Q5VojL31kTUVpVJDw0s8=
|
||||
|
|
|
@ -85,6 +85,10 @@ type Chat struct {
|
|||
|
||||
// CommunityID is the id of the community it belongs to
|
||||
CommunityID string `json:"communityId,omitempty"`
|
||||
|
||||
// CategoryID is the id of the community category this chat belongs to.
|
||||
CategoryID string `json:"categoryId,omitempty"`
|
||||
|
||||
// Joined is a timestamp that indicates when the chat was joined
|
||||
Joined int64 `json:"joined,omitempty"`
|
||||
|
||||
|
@ -305,6 +309,7 @@ func CreateCommunityChat(orgID, chatID string, orgChat *protobuf.CommunityChat,
|
|||
|
||||
return &Chat{
|
||||
CommunityID: orgID,
|
||||
CategoryID: orgChat.CategoryId,
|
||||
Name: orgChat.Identity.DisplayName,
|
||||
Active: true,
|
||||
Color: color,
|
||||
|
|
|
@ -62,6 +62,14 @@ type CommunityChat struct {
|
|||
Members map[string]*protobuf.CommunityMember `json:"members"`
|
||||
Permissions *protobuf.CommunityPermissions `json:"permissions"`
|
||||
CanPost bool `json:"canPost"`
|
||||
Position int `json:"position"`
|
||||
CategoryID string `json:"categoryID"`
|
||||
}
|
||||
|
||||
type CommunityCategory struct {
|
||||
ID string `json:"id"`
|
||||
Name string `json:"name"`
|
||||
Position int `json:"position"` // Position is used to sort the categories
|
||||
}
|
||||
|
||||
func (o *Community) MarshalJSON() ([]byte, error) {
|
||||
|
@ -77,6 +85,7 @@ func (o *Community) MarshalJSON() ([]byte, error) {
|
|||
Name string `json:"name"`
|
||||
Description string `json:"description"`
|
||||
Chats map[string]CommunityChat `json:"chats"`
|
||||
Categories map[string]CommunityCategory `json:"categories"`
|
||||
Images map[string]images.IdentityImage `json:"images"`
|
||||
Permissions *protobuf.CommunityPermissions `json:"permissions"`
|
||||
Members map[string]*protobuf.CommunityMember `json:"members"`
|
||||
|
@ -91,6 +100,7 @@ func (o *Community) MarshalJSON() ([]byte, error) {
|
|||
Admin: o.IsAdmin(),
|
||||
Verified: o.config.Verified,
|
||||
Chats: make(map[string]CommunityChat),
|
||||
Categories: make(map[string]CommunityCategory),
|
||||
Joined: o.config.Joined,
|
||||
CanRequestAccess: o.CanRequestAccess(o.config.MemberIdentity),
|
||||
CanJoin: o.canJoin(),
|
||||
|
@ -99,6 +109,14 @@ func (o *Community) MarshalJSON() ([]byte, error) {
|
|||
IsMember: o.isMember(),
|
||||
}
|
||||
if o.config.CommunityDescription != nil {
|
||||
for id, c := range o.config.CommunityDescription.Categories {
|
||||
category := CommunityCategory{
|
||||
ID: id,
|
||||
Name: c.Name,
|
||||
Position: int(c.Position),
|
||||
}
|
||||
communityItem.Categories[id] = category
|
||||
}
|
||||
for id, c := range o.config.CommunityDescription.Chats {
|
||||
canPost, err := o.CanPost(o.config.MemberIdentity, id, nil)
|
||||
if err != nil {
|
||||
|
@ -110,6 +128,8 @@ func (o *Community) MarshalJSON() ([]byte, error) {
|
|||
Permissions: c.Permissions,
|
||||
Members: c.Members,
|
||||
CanPost: canPost,
|
||||
CategoryID: c.CategoryId,
|
||||
Position: int(c.Position),
|
||||
}
|
||||
communityItem.Chats[id] = chat
|
||||
}
|
||||
|
@ -169,8 +189,10 @@ func (o *Community) initialize() {
|
|||
}
|
||||
|
||||
type CommunityChatChanges struct {
|
||||
MembersAdded map[string]*protobuf.CommunityMember
|
||||
MembersRemoved map[string]*protobuf.CommunityMember
|
||||
MembersAdded map[string]*protobuf.CommunityMember
|
||||
MembersRemoved map[string]*protobuf.CommunityMember
|
||||
CategoryModified string
|
||||
PositionModified int
|
||||
}
|
||||
|
||||
type CommunityChanges struct {
|
||||
|
@ -182,6 +204,10 @@ type CommunityChanges struct {
|
|||
ChatsAdded map[string]*protobuf.CommunityChat `json:"chatsAdded"`
|
||||
ChatsModified map[string]*CommunityChatChanges `json:"chatsModified"`
|
||||
|
||||
CategoriesRemoved []string `json:"categoriesRemoved"`
|
||||
CategoriesAdded map[string]*protobuf.CommunityCategory `json:"categoriesAdded"`
|
||||
CategoriesModified map[string]*protobuf.CommunityCategory `json:"categoriesModified"`
|
||||
|
||||
// ShouldMemberJoin indicates whether the user should join this community
|
||||
// automatically
|
||||
ShouldMemberJoin bool `json:"memberAdded"`
|
||||
|
@ -233,6 +259,14 @@ func (o *Community) CreateChat(chatID string, chat *protobuf.CommunityChat) (*Co
|
|||
return nil, ErrChatAlreadyExists
|
||||
}
|
||||
|
||||
// Sets the chat position to be the last within its category
|
||||
chat.Position = 0
|
||||
for _, c := range o.config.CommunityDescription.Chats {
|
||||
if c.CategoryId == chat.CategoryId {
|
||||
chat.Position++
|
||||
}
|
||||
}
|
||||
|
||||
o.config.CommunityDescription.Chats[chatID] = chat
|
||||
|
||||
o.increaseClock()
|
||||
|
@ -253,6 +287,15 @@ func (o *Community) DeleteChat(chatID string) (*protobuf.CommunityDescription, e
|
|||
if o.config.CommunityDescription.Chats == nil {
|
||||
o.config.CommunityDescription.Chats = make(map[string]*protobuf.CommunityChat)
|
||||
}
|
||||
|
||||
changes := o.emptyCommunityChanges()
|
||||
|
||||
if chat, exists := o.config.CommunityDescription.Chats[chatID]; exists {
|
||||
tmpCatID := chat.CategoryId
|
||||
chat.CategoryId = ""
|
||||
o.SortCategoryChats(changes, tmpCatID)
|
||||
}
|
||||
|
||||
delete(o.config.CommunityDescription.Chats, chatID)
|
||||
|
||||
o.increaseClock()
|
||||
|
@ -570,6 +613,7 @@ func (o *Community) UpdateCommunityDescription(signer *ecdsa.PublicKey, descript
|
|||
if o.config.CommunityDescription.Chats == nil {
|
||||
o.config.CommunityDescription.Chats = make(map[string]*protobuf.CommunityChat)
|
||||
}
|
||||
|
||||
if _, ok := o.config.CommunityDescription.Chats[chatID]; !ok {
|
||||
if response.ChatsAdded == nil {
|
||||
response.ChatsAdded = make(map[string]*protobuf.CommunityChat)
|
||||
|
@ -606,6 +650,65 @@ func (o *Community) UpdateCommunityDescription(signer *ecdsa.PublicKey, descript
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Check for categories that were removed
|
||||
for categoryID := range o.config.CommunityDescription.Categories {
|
||||
if description.Categories == nil {
|
||||
description.Categories = make(map[string]*protobuf.CommunityCategory)
|
||||
}
|
||||
|
||||
if description.Chats == nil {
|
||||
description.Chats = make(map[string]*protobuf.CommunityChat)
|
||||
}
|
||||
|
||||
if _, ok := description.Categories[categoryID]; !ok {
|
||||
response.CategoriesRemoved = append(response.CategoriesRemoved, categoryID)
|
||||
}
|
||||
|
||||
if o.config.CommunityDescription.Chats == nil {
|
||||
o.config.CommunityDescription.Chats = make(map[string]*protobuf.CommunityChat)
|
||||
}
|
||||
}
|
||||
|
||||
// Check for categories that were added
|
||||
for categoryID, category := range description.Categories {
|
||||
if o.config.CommunityDescription.Categories == nil {
|
||||
o.config.CommunityDescription.Categories = make(map[string]*protobuf.CommunityCategory)
|
||||
}
|
||||
if _, ok := o.config.CommunityDescription.Categories[categoryID]; !ok {
|
||||
if response.CategoriesAdded == nil {
|
||||
response.CategoriesAdded = make(map[string]*protobuf.CommunityCategory)
|
||||
}
|
||||
|
||||
response.CategoriesAdded[categoryID] = category
|
||||
} else {
|
||||
if o.config.CommunityDescription.Categories[categoryID].Name != category.Name || o.config.CommunityDescription.Categories[categoryID].Position != category.Position {
|
||||
response.CategoriesModified[categoryID] = category
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Check for chat categories that were modified
|
||||
for chatID, chat := range description.Chats {
|
||||
if o.config.CommunityDescription.Chats == nil {
|
||||
o.config.CommunityDescription.Chats = make(map[string]*protobuf.CommunityChat)
|
||||
}
|
||||
|
||||
if _, ok := o.config.CommunityDescription.Chats[chatID]; !ok {
|
||||
continue // It's a new chat
|
||||
}
|
||||
|
||||
if o.config.CommunityDescription.Chats[chatID].CategoryId != chat.CategoryId {
|
||||
if response.ChatsModified[chatID] == nil {
|
||||
response.ChatsModified[chatID] = &CommunityChatChanges{
|
||||
MembersAdded: make(map[string]*protobuf.CommunityMember),
|
||||
MembersRemoved: make(map[string]*protobuf.CommunityMember),
|
||||
}
|
||||
}
|
||||
|
||||
response.ChatsModified[chatID].CategoryModified = chat.CategoryId
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
o.config.CommunityDescription = description
|
||||
|
@ -765,6 +868,17 @@ func (o *Community) Chats() map[string]*protobuf.CommunityChat {
|
|||
return response
|
||||
}
|
||||
|
||||
func (o *Community) Categories() map[string]*protobuf.CommunityCategory {
|
||||
o.mutex.Lock()
|
||||
defer o.mutex.Unlock()
|
||||
|
||||
response := make(map[string]*protobuf.CommunityCategory)
|
||||
for k, v := range o.config.CommunityDescription.Categories {
|
||||
response[k] = v
|
||||
}
|
||||
return response
|
||||
}
|
||||
|
||||
func (o *Community) VerifyGrantSignature(data []byte) (*protobuf.Grant, error) {
|
||||
if len(data) <= signatureLength {
|
||||
return nil, ErrInvalidGrant
|
||||
|
@ -1015,5 +1129,28 @@ func emptyCommunityChanges() *CommunityChanges {
|
|||
ChatsRemoved: make(map[string]*protobuf.CommunityChat),
|
||||
ChatsAdded: make(map[string]*protobuf.CommunityChat),
|
||||
ChatsModified: make(map[string]*CommunityChatChanges),
|
||||
|
||||
CategoriesRemoved: []string{},
|
||||
CategoriesAdded: make(map[string]*protobuf.CommunityCategory),
|
||||
CategoriesModified: make(map[string]*protobuf.CommunityCategory),
|
||||
}
|
||||
}
|
||||
|
||||
type sortSlice []sorterHelperIdx
|
||||
type sorterHelperIdx struct {
|
||||
pos int32
|
||||
catID string
|
||||
chatID string
|
||||
}
|
||||
|
||||
func (d sortSlice) Len() int {
|
||||
return len(d)
|
||||
}
|
||||
|
||||
func (d sortSlice) Swap(i, j int) {
|
||||
d[i], d[j] = d[j], d[i]
|
||||
}
|
||||
|
||||
func (d sortSlice) Less(i, j int) bool {
|
||||
return d[i].pos < d[j].pos
|
||||
}
|
||||
|
|
|
@ -0,0 +1,359 @@
|
|||
package communities
|
||||
|
||||
import (
|
||||
"sort"
|
||||
|
||||
"github.com/status-im/status-go/protocol/protobuf"
|
||||
)
|
||||
|
||||
func (o *Community) CreateCategory(categoryID string, categoryName string, chatIDs []string) (*CommunityChanges, error) {
|
||||
o.mutex.Lock()
|
||||
defer o.mutex.Unlock()
|
||||
|
||||
if o.config.PrivateKey == nil {
|
||||
return nil, ErrNotAdmin
|
||||
}
|
||||
|
||||
if o.config.CommunityDescription.Categories == nil {
|
||||
o.config.CommunityDescription.Categories = make(map[string]*protobuf.CommunityCategory)
|
||||
}
|
||||
if _, ok := o.config.CommunityDescription.Categories[categoryID]; ok {
|
||||
return nil, ErrCategoryAlreadyExists
|
||||
}
|
||||
|
||||
for _, cid := range chatIDs {
|
||||
c, exists := o.config.CommunityDescription.Chats[cid]
|
||||
if !exists {
|
||||
return nil, ErrChatNotFound
|
||||
}
|
||||
|
||||
if exists && c.CategoryId != categoryID && c.CategoryId != "" {
|
||||
return nil, ErrChatAlreadyAssigned
|
||||
}
|
||||
}
|
||||
|
||||
changes := o.emptyCommunityChanges()
|
||||
|
||||
o.config.CommunityDescription.Categories[categoryID] = &protobuf.CommunityCategory{
|
||||
CategoryId: categoryID,
|
||||
Name: categoryName,
|
||||
Position: int32(len(o.config.CommunityDescription.Categories)),
|
||||
}
|
||||
|
||||
for i, cid := range chatIDs {
|
||||
o.config.CommunityDescription.Chats[cid].CategoryId = categoryID
|
||||
o.config.CommunityDescription.Chats[cid].Position = int32(i)
|
||||
}
|
||||
|
||||
o.SortCategoryChats(changes, "")
|
||||
|
||||
o.increaseClock()
|
||||
|
||||
changes.CategoriesAdded[categoryID] = o.config.CommunityDescription.Categories[categoryID]
|
||||
for i, cid := range chatIDs {
|
||||
changes.ChatsModified[cid] = &CommunityChatChanges{
|
||||
MembersAdded: make(map[string]*protobuf.CommunityMember),
|
||||
MembersRemoved: make(map[string]*protobuf.CommunityMember),
|
||||
CategoryModified: categoryID,
|
||||
PositionModified: i,
|
||||
}
|
||||
}
|
||||
|
||||
return changes, nil
|
||||
}
|
||||
|
||||
func (o *Community) EditCategory(categoryID string, categoryName string, chatIDs []string) (*CommunityChanges, error) {
|
||||
o.mutex.Lock()
|
||||
defer o.mutex.Unlock()
|
||||
|
||||
if o.config.PrivateKey == nil {
|
||||
return nil, ErrNotAdmin
|
||||
}
|
||||
|
||||
if o.config.CommunityDescription.Categories == nil {
|
||||
o.config.CommunityDescription.Categories = make(map[string]*protobuf.CommunityCategory)
|
||||
}
|
||||
if _, ok := o.config.CommunityDescription.Categories[categoryID]; !ok {
|
||||
return nil, ErrCategoryNotFound
|
||||
}
|
||||
|
||||
for _, cid := range chatIDs {
|
||||
c, exists := o.config.CommunityDescription.Chats[cid]
|
||||
if !exists {
|
||||
return nil, ErrChatNotFound
|
||||
}
|
||||
|
||||
if exists && c.CategoryId != categoryID && c.CategoryId != "" {
|
||||
return nil, ErrChatAlreadyAssigned
|
||||
}
|
||||
}
|
||||
|
||||
changes := o.emptyCommunityChanges()
|
||||
|
||||
emptyCatLen := o.getCategoryChatCount("")
|
||||
|
||||
// remove any chat that might have been assigned before and now it's not part of the category
|
||||
var chatsToRemove []string
|
||||
for k, chat := range o.config.CommunityDescription.Chats {
|
||||
if chat.CategoryId == categoryID {
|
||||
found := false
|
||||
for _, c := range chatIDs {
|
||||
if k == c {
|
||||
found = true
|
||||
}
|
||||
}
|
||||
if !found {
|
||||
chat.CategoryId = ""
|
||||
chatsToRemove = append(chatsToRemove, k)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
o.config.CommunityDescription.Categories[categoryID].Name = categoryName
|
||||
|
||||
for i, cid := range chatIDs {
|
||||
o.config.CommunityDescription.Chats[cid].CategoryId = categoryID
|
||||
o.config.CommunityDescription.Chats[cid].Position = int32(i)
|
||||
}
|
||||
|
||||
for i, cid := range chatsToRemove {
|
||||
o.config.CommunityDescription.Chats[cid].Position = int32(emptyCatLen + i)
|
||||
changes.ChatsModified[cid] = &CommunityChatChanges{
|
||||
MembersAdded: make(map[string]*protobuf.CommunityMember),
|
||||
MembersRemoved: make(map[string]*protobuf.CommunityMember),
|
||||
CategoryModified: "",
|
||||
PositionModified: int(o.config.CommunityDescription.Chats[cid].Position),
|
||||
}
|
||||
}
|
||||
|
||||
o.SortCategoryChats(changes, "")
|
||||
|
||||
o.increaseClock()
|
||||
|
||||
changes.CategoriesModified[categoryID] = o.config.CommunityDescription.Categories[categoryID]
|
||||
for i, cid := range chatIDs {
|
||||
changes.ChatsModified[cid] = &CommunityChatChanges{
|
||||
MembersAdded: make(map[string]*protobuf.CommunityMember),
|
||||
MembersRemoved: make(map[string]*protobuf.CommunityMember),
|
||||
CategoryModified: categoryID,
|
||||
PositionModified: i,
|
||||
}
|
||||
}
|
||||
|
||||
return changes, nil
|
||||
}
|
||||
|
||||
func (o *Community) ReorderCategories(categoryID string, newPosition int) (*CommunityChanges, error) {
|
||||
o.mutex.Lock()
|
||||
defer o.mutex.Unlock()
|
||||
|
||||
if o.config.PrivateKey == nil {
|
||||
return nil, ErrNotAdmin
|
||||
}
|
||||
|
||||
if newPosition > 0 && newPosition >= len(o.config.CommunityDescription.Categories) {
|
||||
newPosition = len(o.config.CommunityDescription.Categories) - 1
|
||||
} else if newPosition < 0 {
|
||||
newPosition = 0
|
||||
}
|
||||
|
||||
o.config.CommunityDescription.Categories[categoryID].Position = int32(newPosition)
|
||||
|
||||
s := make(sortSlice, 0, len(o.config.CommunityDescription.Categories))
|
||||
for catID, category := range o.config.CommunityDescription.Categories {
|
||||
|
||||
position := category.Position
|
||||
if category.CategoryId != categoryID && position >= int32(newPosition) {
|
||||
position = position + 1
|
||||
}
|
||||
|
||||
s = append(s, sorterHelperIdx{
|
||||
pos: position,
|
||||
catID: catID,
|
||||
})
|
||||
}
|
||||
|
||||
changes := o.emptyCommunityChanges()
|
||||
|
||||
o.setModifiedCategories(changes, s)
|
||||
|
||||
o.increaseClock()
|
||||
|
||||
return changes, nil
|
||||
}
|
||||
|
||||
func (o *Community) setModifiedCategories(changes *CommunityChanges, s sortSlice) {
|
||||
sort.Sort(s)
|
||||
for i, catSortHelper := range s {
|
||||
if o.config.CommunityDescription.Categories[catSortHelper.catID].Position != int32(i) {
|
||||
o.config.CommunityDescription.Categories[catSortHelper.catID].Position = int32(i)
|
||||
changes.CategoriesModified[catSortHelper.catID] = o.config.CommunityDescription.Categories[catSortHelper.catID]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (o *Community) ReorderChat(categoryID string, chatID string, newPosition int) (*CommunityChanges, error) {
|
||||
o.mutex.Lock()
|
||||
defer o.mutex.Unlock()
|
||||
|
||||
if o.config.PrivateKey == nil {
|
||||
return nil, ErrNotAdmin
|
||||
}
|
||||
|
||||
if _, exists := o.config.CommunityDescription.Categories[categoryID]; !exists {
|
||||
return nil, ErrCategoryNotFound
|
||||
}
|
||||
|
||||
var chat *protobuf.CommunityChat
|
||||
var exists bool
|
||||
if chat, exists = o.config.CommunityDescription.Chats[chatID]; !exists {
|
||||
return nil, ErrChatNotFound
|
||||
}
|
||||
|
||||
oldCategoryID := chat.CategoryId
|
||||
chat.CategoryId = categoryID
|
||||
|
||||
changes := o.emptyCommunityChanges()
|
||||
|
||||
o.SortCategoryChats(changes, oldCategoryID)
|
||||
o.insertAndSort(changes, categoryID, chat, newPosition)
|
||||
|
||||
o.increaseClock()
|
||||
|
||||
return changes, nil
|
||||
}
|
||||
|
||||
func (o *Community) SortCategoryChats(changes *CommunityChanges, categoryID string) {
|
||||
var catChats []string
|
||||
for k, c := range o.config.CommunityDescription.Chats {
|
||||
if c.CategoryId == categoryID {
|
||||
catChats = append(catChats, k)
|
||||
}
|
||||
}
|
||||
|
||||
sortedChats := make(sortSlice, 0, len(catChats))
|
||||
for _, k := range catChats {
|
||||
sortedChats = append(sortedChats, sorterHelperIdx{
|
||||
pos: o.config.CommunityDescription.Chats[k].Position,
|
||||
chatID: k,
|
||||
})
|
||||
}
|
||||
|
||||
sort.Sort(sortedChats)
|
||||
|
||||
for i, chatSortHelper := range sortedChats {
|
||||
if o.config.CommunityDescription.Chats[chatSortHelper.chatID].Position != int32(i) {
|
||||
o.config.CommunityDescription.Chats[chatSortHelper.chatID].Position = int32(i)
|
||||
if changes.ChatsModified[chatSortHelper.chatID] != nil {
|
||||
changes.ChatsModified[chatSortHelper.chatID].PositionModified = i
|
||||
} else {
|
||||
changes.ChatsModified[chatSortHelper.chatID] = &CommunityChatChanges{
|
||||
PositionModified: i,
|
||||
MembersAdded: make(map[string]*protobuf.CommunityMember),
|
||||
MembersRemoved: make(map[string]*protobuf.CommunityMember),
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (o *Community) insertAndSort(changes *CommunityChanges, categoryID string, chat *protobuf.CommunityChat, newPosition int) {
|
||||
var catChats []string
|
||||
for k, c := range o.config.CommunityDescription.Chats {
|
||||
if c.CategoryId == categoryID {
|
||||
catChats = append(catChats, k)
|
||||
}
|
||||
}
|
||||
|
||||
if newPosition > 0 && newPosition >= len(catChats) {
|
||||
newPosition = len(catChats) - 1
|
||||
} else if newPosition < 0 {
|
||||
newPosition = 0
|
||||
}
|
||||
|
||||
sortedChats := make(sortSlice, 0, len(catChats))
|
||||
for _, k := range catChats {
|
||||
position := chat.Position
|
||||
if o.config.CommunityDescription.Chats[k] != chat && position >= int32(newPosition) {
|
||||
position = position + 1
|
||||
}
|
||||
|
||||
sortedChats = append(sortedChats, sorterHelperIdx{
|
||||
pos: position,
|
||||
chatID: k,
|
||||
})
|
||||
}
|
||||
|
||||
sort.Sort(sortedChats)
|
||||
|
||||
for i, chatSortHelper := range sortedChats {
|
||||
if o.config.CommunityDescription.Chats[chatSortHelper.chatID].Position != int32(i) {
|
||||
o.config.CommunityDescription.Chats[chatSortHelper.chatID].Position = int32(i)
|
||||
if changes.ChatsModified[chatSortHelper.chatID] != nil {
|
||||
changes.ChatsModified[chatSortHelper.chatID].PositionModified = i
|
||||
} else {
|
||||
changes.ChatsModified[chatSortHelper.chatID] = &CommunityChatChanges{
|
||||
MembersAdded: make(map[string]*protobuf.CommunityMember),
|
||||
MembersRemoved: make(map[string]*protobuf.CommunityMember),
|
||||
PositionModified: i,
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (o *Community) getCategoryChatCount(categoryID string) int {
|
||||
result := 0
|
||||
for _, chat := range o.config.CommunityDescription.Chats {
|
||||
if chat.CategoryId == categoryID {
|
||||
result = result + 1
|
||||
}
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
func (o *Community) DeleteCategory(categoryID string) (*CommunityChanges, error) {
|
||||
o.mutex.Lock()
|
||||
defer o.mutex.Unlock()
|
||||
|
||||
if o.config.PrivateKey == nil {
|
||||
return nil, ErrNotAdmin
|
||||
}
|
||||
|
||||
if _, exists := o.config.CommunityDescription.Categories[categoryID]; !exists {
|
||||
return nil, ErrCategoryNotFound
|
||||
}
|
||||
|
||||
changes := o.emptyCommunityChanges()
|
||||
|
||||
emptyCategoryChatCount := o.getCategoryChatCount("")
|
||||
i := 0
|
||||
for _, chat := range o.config.CommunityDescription.Chats {
|
||||
if chat.CategoryId == categoryID {
|
||||
i++
|
||||
chat.CategoryId = ""
|
||||
chat.Position = int32(emptyCategoryChatCount + i)
|
||||
}
|
||||
}
|
||||
|
||||
o.SortCategoryChats(changes, "")
|
||||
|
||||
delete(o.config.CommunityDescription.Categories, categoryID)
|
||||
|
||||
changes.CategoriesRemoved = append(changes.CategoriesRemoved, categoryID)
|
||||
|
||||
// Reorder
|
||||
s := make(sortSlice, 0, len(o.config.CommunityDescription.Categories))
|
||||
for _, cat := range o.config.CommunityDescription.Categories {
|
||||
s = append(s, sorterHelperIdx{
|
||||
pos: cat.Position,
|
||||
catID: cat.CategoryId,
|
||||
})
|
||||
}
|
||||
|
||||
o.setModifiedCategories(changes, s)
|
||||
|
||||
o.increaseClock()
|
||||
|
||||
return changes, nil
|
||||
}
|
|
@ -0,0 +1,246 @@
|
|||
package communities
|
||||
|
||||
import (
|
||||
"github.com/status-im/status-go/protocol/protobuf"
|
||||
)
|
||||
|
||||
func (s *CommunitySuite) TestCreateCategory() {
|
||||
newCategoryID := "new-category-id"
|
||||
newCategoryName := "new-category-name"
|
||||
|
||||
org := s.buildCommunity(&s.identity.PublicKey)
|
||||
org.config.PrivateKey = nil
|
||||
|
||||
_, err := org.CreateCategory(newCategoryID, newCategoryName, []string{})
|
||||
s.Require().Equal(ErrNotAdmin, err)
|
||||
|
||||
org.config.PrivateKey = s.identity
|
||||
|
||||
changes, err := org.CreateCategory(newCategoryID, newCategoryName, []string{})
|
||||
|
||||
description := org.config.CommunityDescription
|
||||
|
||||
s.Require().NoError(err)
|
||||
s.Require().NotNil(description.Categories)
|
||||
s.Require().NotNil(description.Categories[newCategoryID])
|
||||
s.Require().Equal(newCategoryName, description.Categories[newCategoryID].Name)
|
||||
s.Require().Equal(newCategoryID, description.Categories[newCategoryID].CategoryId)
|
||||
s.Require().Equal(int32(len(description.Categories)-1), description.Categories[newCategoryID].Position)
|
||||
s.Require().NotNil(changes)
|
||||
s.Require().NotNil(changes.CategoriesAdded[newCategoryID])
|
||||
s.Require().Equal(description.Categories[newCategoryID], changes.CategoriesAdded[newCategoryID])
|
||||
s.Require().Nil(changes.CategoriesModified[newCategoryID])
|
||||
|
||||
_, err = org.CreateCategory(newCategoryID, newCategoryName, []string{})
|
||||
s.Require().Equal(ErrCategoryAlreadyExists, err)
|
||||
|
||||
newCategoryID2 := "new-category-id2"
|
||||
newCategoryName2 := "new-category-name2"
|
||||
|
||||
changes, err = org.CreateCategory(newCategoryID2, newCategoryName2, []string{})
|
||||
s.Require().NoError(err)
|
||||
s.Require().Equal(int32(len(description.Categories)-1), description.Categories[newCategoryID2].Position)
|
||||
s.Require().NotNil(changes.CategoriesAdded[newCategoryID2])
|
||||
s.Require().Nil(changes.CategoriesModified[newCategoryID2])
|
||||
|
||||
newCategoryID3 := "new-category-id3"
|
||||
newCategoryName3 := "new-category-name3"
|
||||
_, err = org.CreateCategory(newCategoryID3, newCategoryName3, []string{"some-chat-id"})
|
||||
s.Require().Equal(ErrChatNotFound, err)
|
||||
|
||||
newChatID := "new-chat-id"
|
||||
identity := &protobuf.ChatIdentity{
|
||||
DisplayName: "new-chat-display-name",
|
||||
Description: "new-chat-description",
|
||||
}
|
||||
permissions := &protobuf.CommunityPermissions{
|
||||
Access: protobuf.CommunityPermissions_NO_MEMBERSHIP,
|
||||
}
|
||||
|
||||
_, _ = org.CreateChat(newChatID, &protobuf.CommunityChat{
|
||||
Identity: identity,
|
||||
Permissions: permissions,
|
||||
})
|
||||
|
||||
changes, err = org.CreateCategory(newCategoryID3, newCategoryName3, []string{newChatID})
|
||||
s.Require().NoError(err)
|
||||
s.Require().NotNil(changes.ChatsModified[newChatID])
|
||||
s.Require().Equal(newCategoryID3, changes.ChatsModified[newChatID].CategoryModified)
|
||||
|
||||
newCategoryID4 := "new-category-id4"
|
||||
newCategoryName4 := "new-category-name4"
|
||||
|
||||
_, err = org.CreateCategory(newCategoryID4, newCategoryName4, []string{newChatID})
|
||||
s.Require().Equal(ErrChatAlreadyAssigned, err)
|
||||
}
|
||||
|
||||
func (s *CommunitySuite) TestEditCategory() {
|
||||
newCategoryID := "new-category-id"
|
||||
newCategoryName := "new-category-name"
|
||||
editedCategoryName := "edited-category-name"
|
||||
|
||||
org := s.buildCommunity(&s.identity.PublicKey)
|
||||
org.config.PrivateKey = s.identity
|
||||
_, _ = org.CreateCategory(newCategoryID, newCategoryName, []string{testChatID1})
|
||||
org.config.PrivateKey = nil
|
||||
|
||||
_, err := org.EditCategory(newCategoryID, editedCategoryName, []string{testChatID1})
|
||||
s.Require().Equal(ErrNotAdmin, err)
|
||||
|
||||
org.config.PrivateKey = s.identity
|
||||
|
||||
_, err = org.EditCategory("some-random-category", editedCategoryName, []string{testChatID1})
|
||||
s.Require().Equal(ErrCategoryNotFound, err)
|
||||
|
||||
changes, err := org.EditCategory(newCategoryID, editedCategoryName, []string{testChatID1})
|
||||
|
||||
description := org.config.CommunityDescription
|
||||
|
||||
s.Require().NoError(err)
|
||||
s.Require().Equal(editedCategoryName, description.Categories[newCategoryID].Name)
|
||||
s.Require().NotNil(changes)
|
||||
s.Require().NotNil(changes.CategoriesModified[newCategoryID])
|
||||
s.Require().Equal(description.Categories[newCategoryID], changes.CategoriesModified[newCategoryID])
|
||||
s.Require().Nil(changes.CategoriesAdded[newCategoryID])
|
||||
|
||||
_, err = org.EditCategory(newCategoryID, editedCategoryName, []string{"some-random-chat-id"})
|
||||
s.Require().Equal(ErrChatNotFound, err)
|
||||
|
||||
_, err = org.EditCategory(testCategoryID1, testCategoryName1, []string{testChatID1})
|
||||
s.Require().Equal(ErrChatAlreadyAssigned, err)
|
||||
|
||||
// Edit by removing the chats
|
||||
|
||||
identity := &protobuf.ChatIdentity{
|
||||
DisplayName: "new-chat-display-name",
|
||||
Description: "new-chat-description",
|
||||
}
|
||||
permissions := &protobuf.CommunityPermissions{
|
||||
Access: protobuf.CommunityPermissions_NO_MEMBERSHIP,
|
||||
}
|
||||
|
||||
testChatID2 := "test-chat-id-2"
|
||||
testChatID3 := "test-chat-id-3"
|
||||
|
||||
_, _ = org.CreateChat(testChatID2, &protobuf.CommunityChat{
|
||||
Identity: identity,
|
||||
Permissions: permissions,
|
||||
})
|
||||
_, _ = org.CreateChat(testChatID3, &protobuf.CommunityChat{
|
||||
Identity: identity,
|
||||
Permissions: permissions,
|
||||
})
|
||||
|
||||
_, err = org.EditCategory(newCategoryID, editedCategoryName, []string{testChatID1, testChatID2, testChatID3})
|
||||
s.Require().NoError(err)
|
||||
|
||||
s.Require().Equal(newCategoryID, description.Chats[testChatID1].CategoryId)
|
||||
s.Require().Equal(newCategoryID, description.Chats[testChatID2].CategoryId)
|
||||
s.Require().Equal(newCategoryID, description.Chats[testChatID3].CategoryId)
|
||||
|
||||
s.Require().Equal(int32(0), description.Chats[testChatID1].Position)
|
||||
s.Require().Equal(int32(1), description.Chats[testChatID2].Position)
|
||||
s.Require().Equal(int32(2), description.Chats[testChatID3].Position)
|
||||
|
||||
_, _ = org.EditCategory(newCategoryID, editedCategoryName, []string{testChatID1, testChatID3})
|
||||
s.Require().Equal("", description.Chats[testChatID2].CategoryId)
|
||||
s.Require().Equal(int32(0), description.Chats[testChatID1].Position)
|
||||
s.Require().Equal(int32(1), description.Chats[testChatID3].Position)
|
||||
|
||||
_, _ = org.EditCategory(newCategoryID, editedCategoryName, []string{testChatID3})
|
||||
s.Require().Equal("", description.Chats[testChatID1].CategoryId)
|
||||
s.Require().Equal(int32(0), description.Chats[testChatID3].Position)
|
||||
}
|
||||
|
||||
func (s *CommunitySuite) TestDeleteCategory() {
|
||||
org := s.buildCommunity(&s.identity.PublicKey)
|
||||
org.config.PrivateKey = s.identity
|
||||
identity := &protobuf.ChatIdentity{
|
||||
DisplayName: "new-chat-display-name",
|
||||
Description: "new-chat-description",
|
||||
}
|
||||
permissions := &protobuf.CommunityPermissions{
|
||||
Access: protobuf.CommunityPermissions_NO_MEMBERSHIP,
|
||||
}
|
||||
|
||||
testChatID2 := "test-chat-id-2"
|
||||
testChatID3 := "test-chat-id-3"
|
||||
newCategoryID := "new-category-id"
|
||||
newCategoryName := "new-category-name"
|
||||
|
||||
_, _ = org.CreateChat(testChatID2, &protobuf.CommunityChat{
|
||||
Identity: identity,
|
||||
Permissions: permissions,
|
||||
})
|
||||
_, _ = org.CreateChat(testChatID3, &protobuf.CommunityChat{
|
||||
Identity: identity,
|
||||
Permissions: permissions,
|
||||
})
|
||||
|
||||
_, _ = org.CreateCategory(newCategoryID, newCategoryName, []string{})
|
||||
|
||||
description := org.config.CommunityDescription
|
||||
|
||||
_, _ = org.EditCategory(newCategoryID, newCategoryName, []string{testChatID2, testChatID1})
|
||||
|
||||
s.Require().Equal(newCategoryID, description.Chats[testChatID1].CategoryId)
|
||||
s.Require().Equal(newCategoryID, description.Chats[testChatID2].CategoryId)
|
||||
|
||||
s.Require().Equal(int32(0), description.Chats[testChatID3].Position)
|
||||
s.Require().Equal(int32(0), description.Chats[testChatID2].Position)
|
||||
s.Require().Equal(int32(1), description.Chats[testChatID1].Position)
|
||||
|
||||
org.config.PrivateKey = nil
|
||||
_, err := org.DeleteCategory(testCategoryID1)
|
||||
s.Require().Equal(ErrNotAdmin, err)
|
||||
|
||||
org.config.PrivateKey = s.identity
|
||||
_, err = org.DeleteCategory("some-category-id")
|
||||
s.Require().Equal(ErrCategoryNotFound, err)
|
||||
|
||||
changes, err := org.DeleteCategory(newCategoryID)
|
||||
s.Require().NoError(err)
|
||||
s.Require().NotNil(changes)
|
||||
|
||||
s.Require().Equal("", description.Chats[testChatID1].CategoryId)
|
||||
s.Require().Equal("", description.Chats[testChatID2].CategoryId)
|
||||
s.Require().Equal("", description.Chats[testChatID3].CategoryId)
|
||||
}
|
||||
|
||||
func (s *CommunitySuite) TestDeleteChatOrder() {
|
||||
org := s.buildCommunity(&s.identity.PublicKey)
|
||||
org.config.PrivateKey = s.identity
|
||||
identity := &protobuf.ChatIdentity{
|
||||
DisplayName: "new-chat-display-name",
|
||||
Description: "new-chat-description",
|
||||
}
|
||||
permissions := &protobuf.CommunityPermissions{
|
||||
Access: protobuf.CommunityPermissions_NO_MEMBERSHIP,
|
||||
}
|
||||
|
||||
testChatID2 := "test-chat-id-2"
|
||||
testChatID3 := "test-chat-id-3"
|
||||
newCategoryID := "new-category-id"
|
||||
newCategoryName := "new-category-name"
|
||||
|
||||
_, _ = org.CreateChat(testChatID2, &protobuf.CommunityChat{
|
||||
Identity: identity,
|
||||
Permissions: permissions,
|
||||
})
|
||||
_, _ = org.CreateChat(testChatID3, &protobuf.CommunityChat{
|
||||
Identity: identity,
|
||||
Permissions: permissions,
|
||||
})
|
||||
|
||||
_, _ = org.CreateCategory(newCategoryID, newCategoryName, []string{testChatID1, testChatID2, testChatID3})
|
||||
|
||||
description, _ := org.DeleteChat(testChatID2)
|
||||
s.Require().Equal(int32(0), description.Chats[testChatID1].Position)
|
||||
s.Require().Equal(int32(1), description.Chats[testChatID3].Position)
|
||||
|
||||
description, _ = org.DeleteChat(testChatID1)
|
||||
s.Require().Equal(int32(0), description.Chats[testChatID3].Position)
|
||||
|
||||
_, err := org.DeleteChat(testChatID3)
|
||||
s.Require().NoError(err)
|
||||
}
|
|
@ -18,6 +18,8 @@ func TestCommunitySuite(t *testing.T) {
|
|||
}
|
||||
|
||||
const testChatID1 = "chat-id-1"
|
||||
const testCategoryID1 = "category-id-1"
|
||||
const testCategoryName1 = "category-name-1"
|
||||
const testChatID2 = "chat-id-2"
|
||||
|
||||
type CommunitySuite struct {
|
||||
|
@ -131,9 +133,9 @@ func (s *CommunitySuite) TestCreateChat() {
|
|||
|
||||
s.Require().NoError(err)
|
||||
s.Require().NotNil(description)
|
||||
|
||||
s.Require().NotNil(description.Chats[newChatID])
|
||||
s.Require().NotEmpty(description.Clock)
|
||||
s.Require().Equal(len(description.Chats)-1, int(description.Chats[newChatID].Position))
|
||||
s.Require().Equal(permissions, description.Chats[newChatID].Permissions)
|
||||
s.Require().Equal(identity, description.Chats[newChatID].Identity)
|
||||
|
||||
|
@ -705,10 +707,12 @@ func (s *CommunitySuite) emptyCommunityDescriptionWithChat() *protobuf.Community
|
|||
Members: make(map[string]*protobuf.CommunityMember),
|
||||
Clock: 1,
|
||||
Chats: make(map[string]*protobuf.CommunityChat),
|
||||
Categories: make(map[string]*protobuf.CommunityCategory),
|
||||
Permissions: &protobuf.CommunityPermissions{},
|
||||
}
|
||||
|
||||
desc.Chats[testChatID1] = &protobuf.CommunityChat{Permissions: &protobuf.CommunityPermissions{}, Members: make(map[string]*protobuf.CommunityMember)}
|
||||
desc.Categories[testCategoryID1] = &protobuf.CommunityCategory{CategoryId: testCategoryID1, Name: testCategoryName1, Position: 0}
|
||||
desc.Chats[testChatID1] = &protobuf.CommunityChat{Position: 0, Permissions: &protobuf.CommunityPermissions{}, Members: make(map[string]*protobuf.CommunityMember)}
|
||||
desc.Members[common.PubkeyToHex(&s.member1.PublicKey)] = &protobuf.CommunityMember{}
|
||||
desc.Chats[testChatID1].Members[common.PubkeyToHex(&s.member1.PublicKey)] = &protobuf.CommunityMember{}
|
||||
|
||||
|
|
|
@ -3,8 +3,11 @@ package communities
|
|||
import "errors"
|
||||
|
||||
var ErrChatNotFound = errors.New("chat not found")
|
||||
var ErrCategoryNotFound = errors.New("category not found")
|
||||
var ErrChatAlreadyAssigned = errors.New("chat already assigned to a category")
|
||||
var ErrOrgNotFound = errors.New("community not found")
|
||||
var ErrChatAlreadyExists = errors.New("chat already exists")
|
||||
var ErrCategoryAlreadyExists = errors.New("category already exists")
|
||||
var ErrCantRequestAccess = errors.New("can't request access")
|
||||
var ErrInvalidCommunityDescription = errors.New("invalid community description")
|
||||
var ErrInvalidCommunityDescriptionNoOrgPermissions = errors.New("invalid community description no org permissions")
|
||||
|
@ -12,6 +15,9 @@ var ErrInvalidCommunityDescriptionNoChatPermissions = errors.New("invalid commun
|
|||
var ErrInvalidCommunityDescriptionUnknownChatAccess = errors.New("invalid community description unknown chat access")
|
||||
var ErrInvalidCommunityDescriptionUnknownOrgAccess = errors.New("invalid community description unknown org access")
|
||||
var ErrInvalidCommunityDescriptionMemberInChatButNotInOrg = errors.New("invalid community description member in chat but not in org")
|
||||
var ErrInvalidCommunityDescriptionCategoryNoID = errors.New("invalid community category id")
|
||||
var ErrInvalidCommunityDescriptionCategoryNoName = errors.New("invalid community category name")
|
||||
var ErrInvalidCommunityDescriptionUnknownChatCategory = errors.New("invalid community category in chat")
|
||||
var ErrNotAdmin = errors.New("no admin privileges for this community")
|
||||
var ErrInvalidGrant = errors.New("invalid grant")
|
||||
var ErrNotAuthorized = errors.New("not authorized")
|
||||
|
|
|
@ -310,6 +310,131 @@ func (m *Manager) CreateChat(communityID types.HexBytes, chat *protobuf.Communit
|
|||
return community, changes, nil
|
||||
}
|
||||
|
||||
func (m *Manager) CreateCategory(request *requests.CreateCommunityCategory) (*Community, *CommunityChanges, error) {
|
||||
community, err := m.GetByID(request.CommunityID)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
if community == nil {
|
||||
return nil, nil, ErrOrgNotFound
|
||||
}
|
||||
categoryID := uuid.New().String()
|
||||
changes, err := community.CreateCategory(categoryID, request.CategoryName, request.ChatIDs)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
err = m.persistence.SaveCommunity(community)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
// Advertise changes
|
||||
m.publish(&Subscription{Community: community})
|
||||
|
||||
return community, changes, nil
|
||||
}
|
||||
|
||||
func (m *Manager) EditCategory(request *requests.EditCommunityCategory) (*Community, *CommunityChanges, error) {
|
||||
community, err := m.GetByID(request.CommunityID)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
if community == nil {
|
||||
return nil, nil, ErrOrgNotFound
|
||||
}
|
||||
|
||||
changes, err := community.EditCategory(request.CategoryID, request.CategoryName, request.ChatIDs)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
err = m.persistence.SaveCommunity(community)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
// Advertise changes
|
||||
m.publish(&Subscription{Community: community})
|
||||
|
||||
return community, changes, nil
|
||||
}
|
||||
|
||||
func (m *Manager) ReorderCategories(request *requests.ReorderCommunityCategories) (*Community, *CommunityChanges, error) {
|
||||
community, err := m.GetByID(request.CommunityID)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
if community == nil {
|
||||
return nil, nil, ErrOrgNotFound
|
||||
}
|
||||
|
||||
changes, err := community.ReorderCategories(request.CategoryID, request.Position)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
err = m.persistence.SaveCommunity(community)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
// Advertise changes
|
||||
m.publish(&Subscription{Community: community})
|
||||
|
||||
return community, changes, nil
|
||||
}
|
||||
|
||||
func (m *Manager) ReorderChat(request *requests.ReorderCommunityChat) (*Community, *CommunityChanges, error) {
|
||||
community, err := m.GetByID(request.CommunityID)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
if community == nil {
|
||||
return nil, nil, ErrOrgNotFound
|
||||
}
|
||||
|
||||
changes, err := community.ReorderChat(request.CategoryID, request.ChatID, request.Position)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
err = m.persistence.SaveCommunity(community)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
// Advertise changes
|
||||
m.publish(&Subscription{Community: community})
|
||||
|
||||
return community, changes, nil
|
||||
}
|
||||
|
||||
func (m *Manager) DeleteCategory(request *requests.DeleteCommunityCategory) (*Community, *CommunityChanges, error) {
|
||||
community, err := m.GetByID(request.CommunityID)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
if community == nil {
|
||||
return nil, nil, ErrOrgNotFound
|
||||
}
|
||||
|
||||
changes, err := community.DeleteCategory(request.CategoryID)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
err = m.persistence.SaveCommunity(community)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
// Advertise changes
|
||||
m.publish(&Subscription{Community: community})
|
||||
|
||||
return community, changes, nil
|
||||
}
|
||||
|
||||
func (m *Manager) HandleCommunityDescriptionMessage(signer *ecdsa.PublicKey, description *protobuf.CommunityDescription, payload []byte) (*CommunityResponse, error) {
|
||||
id := crypto.CompressPubkey(signer)
|
||||
community, err := m.persistence.GetByID(m.identity, id)
|
||||
|
|
|
@ -15,6 +15,12 @@ func validateCommunityChat(desc *protobuf.CommunityDescription, chat *protobuf.C
|
|||
return ErrInvalidCommunityDescriptionUnknownChatAccess
|
||||
}
|
||||
|
||||
if len(chat.CategoryId) != 0 {
|
||||
if _, exists := desc.Categories[chat.CategoryId]; !exists {
|
||||
return ErrInvalidCommunityDescriptionUnknownChatCategory
|
||||
}
|
||||
}
|
||||
|
||||
for pk := range chat.Members {
|
||||
if desc.Members == nil {
|
||||
return ErrInvalidCommunityDescriptionMemberInChatButNotInOrg
|
||||
|
@ -28,6 +34,18 @@ func validateCommunityChat(desc *protobuf.CommunityDescription, chat *protobuf.C
|
|||
return nil
|
||||
}
|
||||
|
||||
func validateCommunityCategory(category *protobuf.CommunityCategory) error {
|
||||
if len(category.CategoryId) == 0 {
|
||||
return ErrInvalidCommunityDescriptionCategoryNoID
|
||||
}
|
||||
|
||||
if len(category.Name) == 0 {
|
||||
return ErrInvalidCommunityDescriptionCategoryNoName
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func ValidateCommunityDescription(desc *protobuf.CommunityDescription) error {
|
||||
if desc == nil {
|
||||
return ErrInvalidCommunityDescription
|
||||
|
@ -39,6 +57,12 @@ func ValidateCommunityDescription(desc *protobuf.CommunityDescription) error {
|
|||
return ErrInvalidCommunityDescriptionUnknownOrgAccess
|
||||
}
|
||||
|
||||
for _, category := range desc.Categories {
|
||||
if err := validateCommunityCategory(category); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
for _, chat := range desc.Chats {
|
||||
if err := validateCommunityChat(desc, chat); err != nil {
|
||||
return err
|
||||
|
|
|
@ -186,6 +186,26 @@ func (s *MessengerCommunitiesSuite) TestJoinCommunity() {
|
|||
s.Require().NotEmpty(createdChat.Timestamp)
|
||||
s.Require().True(strings.HasPrefix(createdChat.ID, community.IDString()))
|
||||
|
||||
// Make sure the changes are reflect in the community
|
||||
community = response.Communities()[0]
|
||||
|
||||
var chatIds []string
|
||||
for k := range community.Chats() {
|
||||
chatIds = append(chatIds, k)
|
||||
}
|
||||
|
||||
category := &requests.CreateCommunityCategory{
|
||||
CommunityID: community.ID(),
|
||||
CategoryName: "category-name",
|
||||
ChatIDs: chatIds,
|
||||
}
|
||||
|
||||
response, err = s.bob.CreateCommunityCategory(category)
|
||||
s.Require().NoError(err)
|
||||
s.Require().NotNil(response)
|
||||
s.Require().Len(response.Communities(), 1)
|
||||
s.Require().Len(response.Communities()[0].Categories(), 1)
|
||||
|
||||
// Make sure the changes are reflect in the community
|
||||
community = response.Communities()[0]
|
||||
chats := community.Chats()
|
||||
|
@ -231,6 +251,12 @@ func (s *MessengerCommunitiesSuite) TestJoinCommunity() {
|
|||
s.Require().Len(response.Communities(), 1)
|
||||
s.Require().True(response.Communities()[0].Joined())
|
||||
s.Require().Len(response.Chats(), 1)
|
||||
s.Require().Len(response.Communities()[0].Categories(), 1)
|
||||
|
||||
var categoryID string
|
||||
for k := range response.Communities()[0].Categories() {
|
||||
categoryID = k
|
||||
}
|
||||
|
||||
// The chat should be created
|
||||
createdChat = response.Chats()[0]
|
||||
|
@ -238,6 +264,7 @@ func (s *MessengerCommunitiesSuite) TestJoinCommunity() {
|
|||
s.Require().Equal(orgChat.Identity.DisplayName, createdChat.Name)
|
||||
s.Require().NotEmpty(createdChat.ID)
|
||||
s.Require().Equal(ChatTypeCommunityChat, createdChat.ChatType)
|
||||
s.Require().Equal(categoryID, createdChat.CategoryID)
|
||||
s.Require().True(createdChat.Active)
|
||||
s.Require().NotEmpty(createdChat.Timestamp)
|
||||
s.Require().True(strings.HasPrefix(createdChat.ID, community.IDString()))
|
||||
|
@ -464,6 +491,15 @@ func (s *MessengerCommunitiesSuite) TestImportCommunity() {
|
|||
|
||||
community := response.Communities()[0]
|
||||
|
||||
category := &requests.CreateCommunityCategory{
|
||||
CommunityID: community.ID(),
|
||||
CategoryName: "category-name",
|
||||
ChatIDs: []string{},
|
||||
}
|
||||
|
||||
response, err = s.bob.CreateCommunityCategory(category)
|
||||
community = response.Communities()[0]
|
||||
|
||||
privateKey, err := s.bob.ExportCommunity(community.ID())
|
||||
s.Require().NoError(err)
|
||||
|
||||
|
@ -496,6 +532,7 @@ func (s *MessengerCommunitiesSuite) TestImportCommunity() {
|
|||
|
||||
s.Require().NoError(err)
|
||||
s.Require().Len(response.Communities(), 1)
|
||||
s.Require().Len(response.Communities()[0].Categories(), 1)
|
||||
community = response.Communities()[0]
|
||||
s.Require().True(community.Joined())
|
||||
s.Require().True(community.IsAdmin())
|
||||
|
|
|
@ -235,6 +235,86 @@ func (m *Messenger) RequestToJoinCommunity(request *requests.RequestToJoinCommun
|
|||
return response, nil
|
||||
}
|
||||
|
||||
func (m *Messenger) CreateCommunityCategory(request *requests.CreateCommunityCategory) (*MessengerResponse, error) {
|
||||
if err := request.Validate(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var response MessengerResponse
|
||||
community, changes, err := m.communitiesManager.CreateCategory(request)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
response.AddCommunity(community)
|
||||
response.CommunityChanges = []*communities.CommunityChanges{changes}
|
||||
|
||||
return &response, nil
|
||||
}
|
||||
|
||||
func (m *Messenger) EditCommunityCategory(request *requests.EditCommunityCategory) (*MessengerResponse, error) {
|
||||
if err := request.Validate(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var response MessengerResponse
|
||||
community, changes, err := m.communitiesManager.EditCategory(request)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
response.AddCommunity(community)
|
||||
response.CommunityChanges = []*communities.CommunityChanges{changes}
|
||||
|
||||
return &response, nil
|
||||
}
|
||||
|
||||
func (m *Messenger) ReorderCommunityCategories(request *requests.ReorderCommunityCategories) (*MessengerResponse, error) {
|
||||
if err := request.Validate(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var response MessengerResponse
|
||||
community, changes, err := m.communitiesManager.ReorderCategories(request)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
response.AddCommunity(community)
|
||||
response.CommunityChanges = []*communities.CommunityChanges{changes}
|
||||
|
||||
return &response, nil
|
||||
}
|
||||
|
||||
func (m *Messenger) ReorderCommunityChat(request *requests.ReorderCommunityChat) (*MessengerResponse, error) {
|
||||
if err := request.Validate(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var response MessengerResponse
|
||||
community, changes, err := m.communitiesManager.ReorderChat(request)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
response.AddCommunity(community)
|
||||
response.CommunityChanges = []*communities.CommunityChanges{changes}
|
||||
|
||||
return &response, nil
|
||||
}
|
||||
|
||||
func (m *Messenger) DeleteCommunityCategory(request *requests.DeleteCommunityCategory) (*MessengerResponse, error) {
|
||||
if err := request.Validate(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var response MessengerResponse
|
||||
community, changes, err := m.communitiesManager.DeleteCategory(request)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
response.AddCommunity(community)
|
||||
response.CommunityChanges = []*communities.CommunityChanges{changes}
|
||||
|
||||
return &response, nil
|
||||
}
|
||||
|
||||
func (m *Messenger) AcceptRequestToJoinCommunity(request *requests.AcceptRequestToJoinCommunity) (*MessengerResponse, error) {
|
||||
if err := request.Validate(); err != nil {
|
||||
return nil, err
|
||||
|
|
|
@ -238,15 +238,16 @@ func (m *CommunityPermissions) GetAccess() CommunityPermissions_Access {
|
|||
}
|
||||
|
||||
type CommunityDescription struct {
|
||||
Clock uint64 `protobuf:"varint,1,opt,name=clock,proto3" json:"clock,omitempty"`
|
||||
Members map[string]*CommunityMember `protobuf:"bytes,2,rep,name=members,proto3" json:"members,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"`
|
||||
Permissions *CommunityPermissions `protobuf:"bytes,3,opt,name=permissions,proto3" json:"permissions,omitempty"`
|
||||
Identity *ChatIdentity `protobuf:"bytes,5,opt,name=identity,proto3" json:"identity,omitempty"`
|
||||
Chats map[string]*CommunityChat `protobuf:"bytes,6,rep,name=chats,proto3" json:"chats,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"`
|
||||
BanList []string `protobuf:"bytes,7,rep,name=ban_list,json=banList,proto3" json:"ban_list,omitempty"`
|
||||
XXX_NoUnkeyedLiteral struct{} `json:"-"`
|
||||
XXX_unrecognized []byte `json:"-"`
|
||||
XXX_sizecache int32 `json:"-"`
|
||||
Clock uint64 `protobuf:"varint,1,opt,name=clock,proto3" json:"clock,omitempty"`
|
||||
Members map[string]*CommunityMember `protobuf:"bytes,2,rep,name=members,proto3" json:"members,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"`
|
||||
Permissions *CommunityPermissions `protobuf:"bytes,3,opt,name=permissions,proto3" json:"permissions,omitempty"`
|
||||
Identity *ChatIdentity `protobuf:"bytes,5,opt,name=identity,proto3" json:"identity,omitempty"`
|
||||
Chats map[string]*CommunityChat `protobuf:"bytes,6,rep,name=chats,proto3" json:"chats,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"`
|
||||
BanList []string `protobuf:"bytes,7,rep,name=ban_list,json=banList,proto3" json:"ban_list,omitempty"`
|
||||
Categories map[string]*CommunityCategory `protobuf:"bytes,8,rep,name=categories,proto3" json:"categories,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"`
|
||||
XXX_NoUnkeyedLiteral struct{} `json:"-"`
|
||||
XXX_unrecognized []byte `json:"-"`
|
||||
XXX_sizecache int32 `json:"-"`
|
||||
}
|
||||
|
||||
func (m *CommunityDescription) Reset() { *m = CommunityDescription{} }
|
||||
|
@ -316,10 +317,19 @@ func (m *CommunityDescription) GetBanList() []string {
|
|||
return nil
|
||||
}
|
||||
|
||||
func (m *CommunityDescription) GetCategories() map[string]*CommunityCategory {
|
||||
if m != nil {
|
||||
return m.Categories
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
type CommunityChat struct {
|
||||
Members map[string]*CommunityMember `protobuf:"bytes,1,rep,name=members,proto3" json:"members,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"`
|
||||
Permissions *CommunityPermissions `protobuf:"bytes,2,opt,name=permissions,proto3" json:"permissions,omitempty"`
|
||||
Identity *ChatIdentity `protobuf:"bytes,3,opt,name=identity,proto3" json:"identity,omitempty"`
|
||||
CategoryId string `protobuf:"bytes,4,opt,name=category_id,json=categoryId,proto3" json:"category_id,omitempty"`
|
||||
Position int32 `protobuf:"varint,5,opt,name=position,proto3" json:"position,omitempty"`
|
||||
XXX_NoUnkeyedLiteral struct{} `json:"-"`
|
||||
XXX_unrecognized []byte `json:"-"`
|
||||
XXX_sizecache int32 `json:"-"`
|
||||
|
@ -371,6 +381,75 @@ func (m *CommunityChat) GetIdentity() *ChatIdentity {
|
|||
return nil
|
||||
}
|
||||
|
||||
func (m *CommunityChat) GetCategoryId() string {
|
||||
if m != nil {
|
||||
return m.CategoryId
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (m *CommunityChat) GetPosition() int32 {
|
||||
if m != nil {
|
||||
return m.Position
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
type CommunityCategory struct {
|
||||
CategoryId string `protobuf:"bytes,1,opt,name=category_id,json=categoryId,proto3" json:"category_id,omitempty"`
|
||||
Name string `protobuf:"bytes,2,opt,name=name,proto3" json:"name,omitempty"`
|
||||
Position int32 `protobuf:"varint,3,opt,name=position,proto3" json:"position,omitempty"`
|
||||
XXX_NoUnkeyedLiteral struct{} `json:"-"`
|
||||
XXX_unrecognized []byte `json:"-"`
|
||||
XXX_sizecache int32 `json:"-"`
|
||||
}
|
||||
|
||||
func (m *CommunityCategory) Reset() { *m = CommunityCategory{} }
|
||||
func (m *CommunityCategory) String() string { return proto.CompactTextString(m) }
|
||||
func (*CommunityCategory) ProtoMessage() {}
|
||||
func (*CommunityCategory) Descriptor() ([]byte, []int) {
|
||||
return fileDescriptor_f937943d74c1cd8b, []int{5}
|
||||
}
|
||||
|
||||
func (m *CommunityCategory) XXX_Unmarshal(b []byte) error {
|
||||
return xxx_messageInfo_CommunityCategory.Unmarshal(m, b)
|
||||
}
|
||||
func (m *CommunityCategory) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
|
||||
return xxx_messageInfo_CommunityCategory.Marshal(b, m, deterministic)
|
||||
}
|
||||
func (m *CommunityCategory) XXX_Merge(src proto.Message) {
|
||||
xxx_messageInfo_CommunityCategory.Merge(m, src)
|
||||
}
|
||||
func (m *CommunityCategory) XXX_Size() int {
|
||||
return xxx_messageInfo_CommunityCategory.Size(m)
|
||||
}
|
||||
func (m *CommunityCategory) XXX_DiscardUnknown() {
|
||||
xxx_messageInfo_CommunityCategory.DiscardUnknown(m)
|
||||
}
|
||||
|
||||
var xxx_messageInfo_CommunityCategory proto.InternalMessageInfo
|
||||
|
||||
func (m *CommunityCategory) GetCategoryId() string {
|
||||
if m != nil {
|
||||
return m.CategoryId
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (m *CommunityCategory) GetName() string {
|
||||
if m != nil {
|
||||
return m.Name
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (m *CommunityCategory) GetPosition() int32 {
|
||||
if m != nil {
|
||||
return m.Position
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
type CommunityInvitation struct {
|
||||
CommunityDescription []byte `protobuf:"bytes,1,opt,name=community_description,json=communityDescription,proto3" json:"community_description,omitempty"`
|
||||
Grant []byte `protobuf:"bytes,2,opt,name=grant,proto3" json:"grant,omitempty"`
|
||||
|
@ -385,7 +464,7 @@ func (m *CommunityInvitation) Reset() { *m = CommunityInvitation{} }
|
|||
func (m *CommunityInvitation) String() string { return proto.CompactTextString(m) }
|
||||
func (*CommunityInvitation) ProtoMessage() {}
|
||||
func (*CommunityInvitation) Descriptor() ([]byte, []int) {
|
||||
return fileDescriptor_f937943d74c1cd8b, []int{5}
|
||||
return fileDescriptor_f937943d74c1cd8b, []int{6}
|
||||
}
|
||||
|
||||
func (m *CommunityInvitation) XXX_Unmarshal(b []byte) error {
|
||||
|
@ -448,7 +527,7 @@ func (m *CommunityRequestToJoin) Reset() { *m = CommunityRequestToJoin{}
|
|||
func (m *CommunityRequestToJoin) String() string { return proto.CompactTextString(m) }
|
||||
func (*CommunityRequestToJoin) ProtoMessage() {}
|
||||
func (*CommunityRequestToJoin) Descriptor() ([]byte, []int) {
|
||||
return fileDescriptor_f937943d74c1cd8b, []int{6}
|
||||
return fileDescriptor_f937943d74c1cd8b, []int{7}
|
||||
}
|
||||
|
||||
func (m *CommunityRequestToJoin) XXX_Unmarshal(b []byte) error {
|
||||
|
@ -511,7 +590,7 @@ func (m *CommunityRequestToJoinResponse) Reset() { *m = CommunityRequest
|
|||
func (m *CommunityRequestToJoinResponse) String() string { return proto.CompactTextString(m) }
|
||||
func (*CommunityRequestToJoinResponse) ProtoMessage() {}
|
||||
func (*CommunityRequestToJoinResponse) Descriptor() ([]byte, []int) {
|
||||
return fileDescriptor_f937943d74c1cd8b, []int{7}
|
||||
return fileDescriptor_f937943d74c1cd8b, []int{8}
|
||||
}
|
||||
|
||||
func (m *CommunityRequestToJoinResponse) XXX_Unmarshal(b []byte) error {
|
||||
|
@ -567,10 +646,12 @@ func init() {
|
|||
proto.RegisterType((*CommunityMember)(nil), "protobuf.CommunityMember")
|
||||
proto.RegisterType((*CommunityPermissions)(nil), "protobuf.CommunityPermissions")
|
||||
proto.RegisterType((*CommunityDescription)(nil), "protobuf.CommunityDescription")
|
||||
proto.RegisterMapType((map[string]*CommunityCategory)(nil), "protobuf.CommunityDescription.CategoriesEntry")
|
||||
proto.RegisterMapType((map[string]*CommunityChat)(nil), "protobuf.CommunityDescription.ChatsEntry")
|
||||
proto.RegisterMapType((map[string]*CommunityMember)(nil), "protobuf.CommunityDescription.MembersEntry")
|
||||
proto.RegisterType((*CommunityChat)(nil), "protobuf.CommunityChat")
|
||||
proto.RegisterMapType((map[string]*CommunityMember)(nil), "protobuf.CommunityChat.MembersEntry")
|
||||
proto.RegisterType((*CommunityCategory)(nil), "protobuf.CommunityCategory")
|
||||
proto.RegisterType((*CommunityInvitation)(nil), "protobuf.CommunityInvitation")
|
||||
proto.RegisterType((*CommunityRequestToJoin)(nil), "protobuf.CommunityRequestToJoin")
|
||||
proto.RegisterType((*CommunityRequestToJoinResponse)(nil), "protobuf.CommunityRequestToJoinResponse")
|
||||
|
@ -581,53 +662,59 @@ func init() {
|
|||
}
|
||||
|
||||
var fileDescriptor_f937943d74c1cd8b = []byte{
|
||||
// 758 bytes of a gzipped FileDescriptorProto
|
||||
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xb4, 0x54, 0xef, 0x6e, 0xda, 0x48,
|
||||
0x10, 0x8f, 0x31, 0x7f, 0xcc, 0x40, 0x88, 0xb3, 0xf9, 0xe7, 0x70, 0xba, 0x1c, 0x67, 0xdd, 0x49,
|
||||
0x9c, 0x4e, 0xc7, 0x49, 0x44, 0x27, 0x9d, 0xaa, 0x36, 0x2d, 0x4d, 0xad, 0xd4, 0x0d, 0x98, 0x64,
|
||||
0x81, 0x56, 0xfd, 0x64, 0x19, 0xb3, 0x6d, 0xad, 0xc0, 0x9a, 0x7a, 0x0d, 0x12, 0x0f, 0x50, 0xa9,
|
||||
0x8f, 0xd0, 0x0f, 0xfd, 0xdc, 0xe7, 0xea, 0x1b, 0xf4, 0x15, 0x2a, 0xef, 0x02, 0x76, 0x52, 0x48,
|
||||
0x23, 0x55, 0xfd, 0x64, 0xcf, 0xce, 0xcc, 0x6f, 0x67, 0x7e, 0x33, 0xfb, 0x83, 0x6d, 0xd7, 0x1f,
|
||||
0x8d, 0x26, 0xd4, 0x0b, 0x3d, 0xc2, 0x6a, 0xe3, 0xc0, 0x0f, 0x7d, 0xa4, 0xf0, 0x4f, 0x7f, 0xf2,
|
||||
0xaa, 0xbc, 0xe3, 0xbe, 0x71, 0x42, 0xdb, 0x1b, 0x10, 0x1a, 0x7a, 0xe1, 0x4c, 0xb8, 0xf5, 0x29,
|
||||
0x64, 0xce, 0x02, 0x87, 0x86, 0xe8, 0x77, 0x28, 0x2e, 0x92, 0x67, 0xb6, 0x37, 0xd0, 0xa4, 0x8a,
|
||||
0x54, 0x2d, 0xe2, 0xc2, 0xf2, 0xcc, 0x1c, 0xa0, 0x5f, 0x20, 0x3f, 0x22, 0xa3, 0x3e, 0x09, 0x22,
|
||||
0x7f, 0x8a, 0xfb, 0x15, 0x71, 0x60, 0x0e, 0xd0, 0x01, 0xe4, 0xe6, 0xf8, 0x9a, 0x5c, 0x91, 0xaa,
|
||||
0x79, 0x9c, 0x8d, 0x4c, 0x73, 0x80, 0x76, 0x21, 0xe3, 0x0e, 0x7d, 0xf7, 0x4a, 0x4b, 0x57, 0xa4,
|
||||
0x6a, 0x1a, 0x0b, 0x43, 0x7f, 0x2f, 0xc1, 0xd6, 0xe9, 0x02, 0xbb, 0xc5, 0x41, 0xd0, 0x7f, 0x90,
|
||||
0x09, 0xfc, 0x21, 0x61, 0x9a, 0x54, 0x91, 0xab, 0xa5, 0xfa, 0x6f, 0xb5, 0x45, 0xe9, 0xb5, 0x1b,
|
||||
0x91, 0x35, 0x1c, 0x85, 0x61, 0x11, 0xad, 0x9f, 0x40, 0x86, 0xdb, 0x48, 0x85, 0x62, 0xcf, 0x3a,
|
||||
0xb7, 0xda, 0x2f, 0x2c, 0x1b, 0xb7, 0x9b, 0x86, 0xba, 0x81, 0x8a, 0xa0, 0x44, 0x7f, 0x76, 0xa3,
|
||||
0xd9, 0x54, 0x25, 0xb4, 0x07, 0xdb, 0xdc, 0x6a, 0x35, 0xac, 0xc6, 0x99, 0x61, 0xf7, 0x3a, 0x06,
|
||||
0xee, 0xa8, 0x29, 0xfd, 0xb3, 0x04, 0xbb, 0xcb, 0x0b, 0x2e, 0x48, 0x30, 0xf2, 0x18, 0xf3, 0x7c,
|
||||
0xca, 0xd0, 0x21, 0x28, 0x84, 0x32, 0xdb, 0xa7, 0xc3, 0x19, 0xa7, 0x43, 0xc1, 0x39, 0x42, 0x59,
|
||||
0x9b, 0x0e, 0x67, 0x48, 0x83, 0xdc, 0x38, 0xf0, 0xa6, 0x4e, 0x48, 0x38, 0x11, 0x0a, 0x5e, 0x98,
|
||||
0xe8, 0x01, 0x64, 0x1d, 0xd7, 0x25, 0x8c, 0x71, 0x1a, 0x4a, 0xf5, 0x3f, 0x57, 0x74, 0x91, 0xb8,
|
||||
0xa4, 0xd6, 0xe0, 0xc1, 0x78, 0x9e, 0xa4, 0x77, 0x21, 0x2b, 0x4e, 0x10, 0x82, 0xd2, 0xa2, 0x9b,
|
||||
0xc6, 0xe9, 0xa9, 0xd1, 0xe9, 0xa8, 0x1b, 0x68, 0x1b, 0x36, 0xad, 0xb6, 0xdd, 0x32, 0x5a, 0x8f,
|
||||
0x0d, 0xdc, 0x79, 0x6a, 0x5e, 0xa8, 0x12, 0xda, 0x81, 0x2d, 0xd3, 0x7a, 0x6e, 0x76, 0x1b, 0x5d,
|
||||
0xb3, 0x6d, 0xd9, 0x6d, 0xab, 0xf9, 0x52, 0x4d, 0xa1, 0x12, 0x40, 0xdb, 0xb2, 0xb1, 0x71, 0xd9,
|
||||
0x33, 0x3a, 0x5d, 0x55, 0xd6, 0xbf, 0xc8, 0x89, 0x16, 0x9f, 0x10, 0xe6, 0x06, 0xde, 0x38, 0xf4,
|
||||
0x7c, 0x1a, 0x0f, 0x47, 0x4a, 0x0c, 0x07, 0x19, 0x90, 0x13, 0x73, 0x65, 0x5a, 0xaa, 0x22, 0x57,
|
||||
0x0b, 0xf5, 0xbf, 0x57, 0x34, 0x91, 0x80, 0xa9, 0x89, 0xb1, 0x30, 0x83, 0x86, 0xc1, 0x0c, 0x2f,
|
||||
0x72, 0xd1, 0x23, 0x28, 0x8c, 0xe3, 0x4e, 0x39, 0x1f, 0x85, 0xfa, 0xd1, 0xed, 0x7c, 0xe0, 0x64,
|
||||
0x0a, 0xaa, 0x83, 0xb2, 0xd8, 0x57, 0x2d, 0xc3, 0xd3, 0xf7, 0x13, 0xe9, 0x7c, 0xbf, 0x84, 0x17,
|
||||
0x2f, 0xe3, 0xd0, 0x43, 0xc8, 0x44, 0x9b, 0xc7, 0xb4, 0x2c, 0x2f, 0xfd, 0xaf, 0xef, 0x94, 0x1e,
|
||||
0xa1, 0xcc, 0x0b, 0x17, 0x79, 0xd1, 0xd8, 0xfb, 0x0e, 0xb5, 0x87, 0x1e, 0x0b, 0xb5, 0x5c, 0x45,
|
||||
0xae, 0xe6, 0x71, 0xae, 0xef, 0xd0, 0xa6, 0xc7, 0xc2, 0x72, 0x0f, 0x8a, 0xc9, 0x56, 0x91, 0x0a,
|
||||
0xf2, 0x15, 0x11, 0xcb, 0x91, 0xc7, 0xd1, 0x2f, 0xfa, 0x17, 0x32, 0x53, 0x67, 0x38, 0x11, 0x6b,
|
||||
0x51, 0xa8, 0x1f, 0xae, 0xdd, 0x61, 0x2c, 0xe2, 0xee, 0xa5, 0xfe, 0x97, 0xca, 0x97, 0x00, 0x71,
|
||||
0x19, 0x2b, 0x40, 0xff, 0xb9, 0x0e, 0x7a, 0xb0, 0x02, 0x34, 0xca, 0x4f, 0x40, 0xea, 0x1f, 0x53,
|
||||
0xb0, 0x79, 0xcd, 0x89, 0x4e, 0xe2, 0xa1, 0x4a, 0x9c, 0x99, 0x3f, 0xd6, 0xc0, 0xdc, 0x6d, 0x9a,
|
||||
0xa9, 0x1f, 0x9b, 0xa6, 0x7c, 0xb7, 0x69, 0xfe, 0x24, 0xc6, 0xf5, 0x0f, 0x12, 0xec, 0x2c, 0xdd,
|
||||
0x26, 0x9d, 0x7a, 0xa1, 0xc3, 0xdf, 0xc3, 0x31, 0xec, 0xc5, 0x2a, 0x38, 0x88, 0xd7, 0x64, 0x2e,
|
||||
0x87, 0xbb, 0xee, 0x9a, 0x47, 0xf4, 0x3a, 0xd2, 0xd0, 0xb9, 0x26, 0x0a, 0x63, 0xbd, 0x20, 0xfe,
|
||||
0x0a, 0x30, 0x9e, 0xf4, 0x87, 0x9e, 0x6b, 0x47, 0x9d, 0xa4, 0x79, 0x4e, 0x5e, 0x9c, 0x9c, 0x93,
|
||||
0x99, 0xfe, 0x4e, 0x82, 0xfd, 0x65, 0x69, 0x98, 0xbc, 0x9d, 0x10, 0x16, 0x76, 0xfd, 0x67, 0xbe,
|
||||
0xb7, 0xee, 0xb5, 0xce, 0x65, 0x8a, 0x3a, 0x23, 0xc1, 0x41, 0x9e, 0xcb, 0x94, 0xe5, 0x8c, 0xc8,
|
||||
0xfa, 0x1a, 0x6e, 0xaa, 0x7d, 0xfa, 0x1b, 0xb5, 0xd7, 0x3f, 0x49, 0x70, 0xb4, 0xba, 0x0e, 0x4c,
|
||||
0xd8, 0xd8, 0xa7, 0x8c, 0xac, 0xa9, 0xe7, 0x3e, 0xe4, 0x97, 0x38, 0xb7, 0xac, 0x49, 0x82, 0x41,
|
||||
0x1c, 0x27, 0xa0, 0x32, 0x28, 0x91, 0x14, 0x8e, 0x43, 0x22, 0x6a, 0x56, 0xf0, 0xd2, 0x8e, 0x89,
|
||||
0x4e, 0x27, 0x88, 0xee, 0x67, 0x39, 0xf6, 0xf1, 0xd7, 0x00, 0x00, 0x00, 0xff, 0xff, 0x16, 0xf8,
|
||||
0x6e, 0x5b, 0xfd, 0x06, 0x00, 0x00,
|
||||
// 850 bytes of a gzipped FileDescriptorProto
|
||||
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xb4, 0x55, 0xef, 0x8e, 0xdb, 0x44,
|
||||
0x10, 0xef, 0xc6, 0x71, 0xe2, 0x4c, 0xd2, 0x3b, 0xdf, 0xde, 0xb5, 0x75, 0xaf, 0xa2, 0x0d, 0x16,
|
||||
0x48, 0x41, 0x88, 0x20, 0x52, 0x21, 0x21, 0x04, 0x85, 0x70, 0x58, 0xc5, 0x34, 0xe7, 0xb4, 0x9b,
|
||||
0x1c, 0x08, 0xbe, 0x58, 0x8e, 0xb3, 0x94, 0x55, 0x13, 0xdb, 0x78, 0x9d, 0x93, 0xf2, 0x00, 0x48,
|
||||
0x3c, 0x02, 0x12, 0xdf, 0x79, 0x27, 0xbe, 0xf1, 0x28, 0x68, 0x77, 0xe3, 0x3f, 0xb9, 0x4b, 0xda,
|
||||
0x93, 0x50, 0x3f, 0xc5, 0xb3, 0xbb, 0xf3, 0x9b, 0xdf, 0xfc, 0x66, 0x32, 0x03, 0x47, 0x61, 0xbc,
|
||||
0x5c, 0xae, 0x22, 0x96, 0x31, 0xca, 0xfb, 0x49, 0x1a, 0x67, 0x31, 0x36, 0xe4, 0xcf, 0x6c, 0xf5,
|
||||
0xcb, 0xe9, 0x71, 0xf8, 0x6b, 0x90, 0xf9, 0x6c, 0x4e, 0xa3, 0x8c, 0x65, 0x6b, 0x75, 0x6d, 0x5f,
|
||||
0x82, 0xfe, 0x34, 0x0d, 0xa2, 0x0c, 0xbf, 0x0b, 0x9d, 0xdc, 0x79, 0xed, 0xb3, 0xb9, 0x85, 0xba,
|
||||
0xa8, 0xd7, 0x21, 0xed, 0xe2, 0xcc, 0x9d, 0xe3, 0x07, 0xd0, 0x5a, 0xd2, 0xe5, 0x8c, 0xa6, 0xe2,
|
||||
0xbe, 0x26, 0xef, 0x0d, 0x75, 0xe0, 0xce, 0xf1, 0x3d, 0x68, 0x6e, 0xf0, 0x2d, 0xad, 0x8b, 0x7a,
|
||||
0x2d, 0xd2, 0x10, 0xa6, 0x3b, 0xc7, 0x27, 0xa0, 0x87, 0x8b, 0x38, 0x7c, 0x65, 0xd5, 0xbb, 0xa8,
|
||||
0x57, 0x27, 0xca, 0xb0, 0xff, 0x40, 0x70, 0x78, 0x96, 0x63, 0x9f, 0x4b, 0x10, 0xfc, 0x29, 0xe8,
|
||||
0x69, 0xbc, 0xa0, 0xdc, 0x42, 0x5d, 0xad, 0x77, 0x30, 0x78, 0xd4, 0xcf, 0xa9, 0xf7, 0xaf, 0xbc,
|
||||
0xec, 0x13, 0xf1, 0x8c, 0xa8, 0xd7, 0xf6, 0x13, 0xd0, 0xa5, 0x8d, 0x4d, 0xe8, 0x5c, 0x78, 0xcf,
|
||||
0xbc, 0xf1, 0x8f, 0x9e, 0x4f, 0xc6, 0x23, 0xc7, 0xbc, 0x85, 0x3b, 0x60, 0x88, 0x2f, 0x7f, 0x38,
|
||||
0x1a, 0x99, 0x08, 0xdf, 0x81, 0x23, 0x69, 0x9d, 0x0f, 0xbd, 0xe1, 0x53, 0xc7, 0xbf, 0x98, 0x38,
|
||||
0x64, 0x62, 0xd6, 0xec, 0x7f, 0x11, 0x9c, 0x14, 0x01, 0x9e, 0xd3, 0x74, 0xc9, 0x38, 0x67, 0x71,
|
||||
0xc4, 0xf1, 0x7d, 0x30, 0x68, 0xc4, 0xfd, 0x38, 0x5a, 0xac, 0xa5, 0x1c, 0x06, 0x69, 0xd2, 0x88,
|
||||
0x8f, 0xa3, 0xc5, 0x1a, 0x5b, 0xd0, 0x4c, 0x52, 0x76, 0x19, 0x64, 0x54, 0x0a, 0x61, 0x90, 0xdc,
|
||||
0xc4, 0x5f, 0x42, 0x23, 0x08, 0x43, 0xca, 0xb9, 0x94, 0xe1, 0x60, 0xf0, 0xfe, 0x8e, 0x2c, 0x2a,
|
||||
0x41, 0xfa, 0x43, 0xf9, 0x98, 0x6c, 0x9c, 0xec, 0x29, 0x34, 0xd4, 0x09, 0xc6, 0x70, 0x90, 0x67,
|
||||
0x33, 0x3c, 0x3b, 0x73, 0x26, 0x13, 0xf3, 0x16, 0x3e, 0x82, 0xdb, 0xde, 0xd8, 0x3f, 0x77, 0xce,
|
||||
0xbf, 0x71, 0xc8, 0xe4, 0x3b, 0xf7, 0xb9, 0x89, 0xf0, 0x31, 0x1c, 0xba, 0xde, 0x0f, 0xee, 0x74,
|
||||
0x38, 0x75, 0xc7, 0x9e, 0x3f, 0xf6, 0x46, 0x3f, 0x99, 0x35, 0x7c, 0x00, 0x30, 0xf6, 0x7c, 0xe2,
|
||||
0xbc, 0xb8, 0x70, 0x26, 0x53, 0x53, 0xb3, 0xff, 0xd2, 0x2b, 0x29, 0x7e, 0x4b, 0x79, 0x98, 0xb2,
|
||||
0x24, 0x63, 0x71, 0x54, 0x16, 0x07, 0x55, 0x8a, 0x83, 0x1d, 0x68, 0xaa, 0xba, 0x72, 0xab, 0xd6,
|
||||
0xd5, 0x7a, 0xed, 0xc1, 0x87, 0x3b, 0x92, 0xa8, 0xc0, 0xf4, 0x55, 0x59, 0xb8, 0x13, 0x65, 0xe9,
|
||||
0x9a, 0xe4, 0xbe, 0xf8, 0x6b, 0x68, 0x27, 0x65, 0xa6, 0x52, 0x8f, 0xf6, 0xe0, 0xe1, 0xeb, 0xf5,
|
||||
0x20, 0x55, 0x17, 0x3c, 0x00, 0x23, 0xef, 0x57, 0x4b, 0x97, 0xee, 0x77, 0x2b, 0xee, 0xb2, 0xbf,
|
||||
0xd4, 0x2d, 0x29, 0xde, 0xe1, 0xaf, 0x40, 0x17, 0x9d, 0xc7, 0xad, 0x86, 0xa4, 0xfe, 0xc1, 0x1b,
|
||||
0xa8, 0x0b, 0x94, 0x0d, 0x71, 0xe5, 0x27, 0xca, 0x3e, 0x0b, 0x22, 0x7f, 0xc1, 0x78, 0x66, 0x35,
|
||||
0xbb, 0x5a, 0xaf, 0x45, 0x9a, 0xb3, 0x20, 0x1a, 0x31, 0x9e, 0x61, 0x0f, 0x20, 0x0c, 0x32, 0xfa,
|
||||
0x32, 0x4e, 0x19, 0xe5, 0x96, 0x21, 0x03, 0xf4, 0xdf, 0x14, 0xa0, 0x70, 0x50, 0x51, 0x2a, 0x08,
|
||||
0xa7, 0x17, 0xd0, 0xa9, 0x4a, 0x87, 0x4d, 0xd0, 0x5e, 0x51, 0xd5, 0x6c, 0x2d, 0x22, 0x3e, 0xf1,
|
||||
0xc7, 0xa0, 0x5f, 0x06, 0x8b, 0x95, 0x6a, 0xb3, 0xf6, 0xe0, 0xfe, 0xde, 0xff, 0x04, 0x51, 0xef,
|
||||
0x3e, 0xaf, 0x7d, 0x86, 0x4e, 0x5f, 0x00, 0x94, 0x69, 0xed, 0x00, 0xfd, 0x68, 0x1b, 0xf4, 0xde,
|
||||
0x0e, 0x50, 0xe1, 0x5f, 0x85, 0xfc, 0x19, 0x0e, 0xaf, 0x24, 0xb2, 0x03, 0xf7, 0x93, 0x6d, 0xdc,
|
||||
0x07, 0xbb, 0x70, 0x15, 0xc8, 0xba, 0x82, 0x6d, 0xff, 0x53, 0x83, 0xdb, 0x5b, 0x81, 0xf1, 0x93,
|
||||
0xb2, 0x01, 0x91, 0x14, 0xf9, 0xbd, 0x3d, 0x14, 0x6f, 0xd6, 0x79, 0xb5, 0xff, 0xd7, 0x79, 0xda,
|
||||
0x0d, 0x3b, 0xef, 0x11, 0xb4, 0x37, 0xb5, 0x95, 0x13, 0xb4, 0x2e, 0x85, 0xc9, 0xcb, 0x2d, 0x06,
|
||||
0xe8, 0x29, 0x18, 0x49, 0xcc, 0x99, 0x68, 0x0b, 0xd9, 0xce, 0x3a, 0x29, 0xec, 0xb7, 0xd4, 0x0a,
|
||||
0xf6, 0x1c, 0x8e, 0xae, 0x69, 0x7f, 0x95, 0x28, 0xba, 0x46, 0x14, 0x43, 0x3d, 0x0a, 0x96, 0x2a,
|
||||
0x52, 0x8b, 0xc8, 0xef, 0x2d, 0xf2, 0xda, 0x36, 0x79, 0xfb, 0x4f, 0x04, 0xc7, 0x45, 0x18, 0x37,
|
||||
0xba, 0x64, 0x59, 0x20, 0xc7, 0xcb, 0x63, 0xb8, 0x53, 0x2e, 0x95, 0x79, 0xf9, 0xa7, 0xd8, 0x6c,
|
||||
0x97, 0x93, 0x70, 0xcf, 0x4c, 0x7a, 0x29, 0x56, 0xd2, 0x66, 0xc5, 0x28, 0x63, 0xff, 0x7e, 0x79,
|
||||
0x07, 0x20, 0x59, 0xcd, 0x16, 0x2c, 0xf4, 0x85, 0x5e, 0x75, 0xe9, 0xd3, 0x52, 0x27, 0xcf, 0xe8,
|
||||
0xda, 0xfe, 0x1d, 0xc1, 0xdd, 0x82, 0x1a, 0xa1, 0xbf, 0xad, 0x28, 0xcf, 0xa6, 0xf1, 0xf7, 0x31,
|
||||
0xdb, 0x37, 0xfc, 0x36, 0x53, 0xbf, 0x92, 0xbf, 0x98, 0xfa, 0x9e, 0x90, 0x60, 0x2f, 0x87, 0xab,
|
||||
0xcb, 0xb3, 0x7e, 0x6d, 0x79, 0xda, 0x7f, 0x23, 0x78, 0xb8, 0x9b, 0x07, 0xa1, 0x3c, 0x89, 0x23,
|
||||
0x4e, 0xf7, 0xf0, 0xf9, 0x02, 0x5a, 0x05, 0xce, 0x6b, 0x3a, 0xb9, 0xa2, 0x20, 0x29, 0x1d, 0x44,
|
||||
0xd5, 0xc4, 0x66, 0x49, 0x32, 0xaa, 0x38, 0x1b, 0xa4, 0xb0, 0x4b, 0xa1, 0xeb, 0x15, 0xa1, 0x67,
|
||||
0x0d, 0x89, 0xfd, 0xf8, 0xbf, 0x00, 0x00, 0x00, 0xff, 0xff, 0xfc, 0x77, 0xbe, 0x23, 0x4c, 0x08,
|
||||
0x00, 0x00,
|
||||
}
|
||||
|
|
|
@ -41,12 +41,21 @@ message CommunityDescription {
|
|||
ChatIdentity identity = 5;
|
||||
map<string,CommunityChat> chats = 6;
|
||||
repeated string ban_list = 7;
|
||||
map<string,CommunityCategory> categories = 8;
|
||||
}
|
||||
|
||||
message CommunityChat {
|
||||
map<string,CommunityMember> members = 1;
|
||||
CommunityPermissions permissions = 2;
|
||||
ChatIdentity identity = 3;
|
||||
string category_id = 4;
|
||||
int32 position = 5;
|
||||
}
|
||||
|
||||
message CommunityCategory {
|
||||
string category_id = 1;
|
||||
string name = 2;
|
||||
int32 position = 3;
|
||||
}
|
||||
|
||||
message CommunityInvitation {
|
||||
|
|
|
@ -0,0 +1,28 @@
|
|||
package requests
|
||||
|
||||
import (
|
||||
"errors"
|
||||
|
||||
"github.com/status-im/status-go/eth-node/types"
|
||||
)
|
||||
|
||||
var ErrCreateCommunityCategoryInvalidCommunityID = errors.New("create-community-category: invalid community id")
|
||||
var ErrCreateCommunityCategoryInvalidName = errors.New("create-community-category: invalid category name")
|
||||
|
||||
type CreateCommunityCategory struct {
|
||||
CommunityID types.HexBytes `json:"communityId"`
|
||||
CategoryName string `json:"categoryName"`
|
||||
ChatIDs []string `json:"chatIds"`
|
||||
}
|
||||
|
||||
func (j *CreateCommunityCategory) Validate() error {
|
||||
if len(j.CommunityID) == 0 {
|
||||
return ErrCreateCommunityCategoryInvalidCommunityID
|
||||
}
|
||||
|
||||
if len(j.CategoryName) == 0 {
|
||||
return ErrCreateCommunityCategoryInvalidName
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
|
@ -0,0 +1,28 @@
|
|||
package requests
|
||||
|
||||
import (
|
||||
"errors"
|
||||
|
||||
"github.com/status-im/status-go/eth-node/types"
|
||||
)
|
||||
|
||||
var ErrDeleteCommunityCategoryInvalidCommunityID = errors.New("set-community-chat-category: invalid community id")
|
||||
var ErrDeleteCommunityCategoryInvalidCategoryID = errors.New("set-community-chat-category: invalid category id")
|
||||
|
||||
type DeleteCommunityCategory struct {
|
||||
CommunityID types.HexBytes `json:"communityId"`
|
||||
CategoryID string `json:"categoryId"`
|
||||
}
|
||||
|
||||
func (j *DeleteCommunityCategory) Validate() error {
|
||||
if len(j.CommunityID) == 0 {
|
||||
return ErrDeleteCommunityCategoryInvalidCommunityID
|
||||
}
|
||||
|
||||
if len(j.CategoryID) == 0 {
|
||||
return ErrDeleteCommunityCategoryInvalidCategoryID
|
||||
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
|
@ -0,0 +1,34 @@
|
|||
package requests
|
||||
|
||||
import (
|
||||
"errors"
|
||||
|
||||
"github.com/status-im/status-go/eth-node/types"
|
||||
)
|
||||
|
||||
var ErrEditCommunityCategoryInvalidCommunityID = errors.New("edit-community-category: invalid community id")
|
||||
var ErrEditCommunityCategoryInvalidCategoryID = errors.New("edit-community-category: invalid category id")
|
||||
var ErrEditCommunityCategoryInvalidName = errors.New("edit-community-category: invalid category name")
|
||||
|
||||
type EditCommunityCategory struct {
|
||||
CommunityID types.HexBytes `json:"communityId"`
|
||||
CategoryID string `json:"categoryId"`
|
||||
CategoryName string `json:"categoryName"`
|
||||
ChatIDs []string `json:"chatIds"`
|
||||
}
|
||||
|
||||
func (j *EditCommunityCategory) Validate() error {
|
||||
if len(j.CommunityID) == 0 {
|
||||
return ErrEditCommunityCategoryInvalidCommunityID
|
||||
}
|
||||
|
||||
if len(j.CategoryID) == 0 {
|
||||
return ErrEditCommunityCategoryInvalidCategoryID
|
||||
}
|
||||
|
||||
if len(j.CategoryName) == 0 {
|
||||
return ErrEditCommunityCategoryInvalidName
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
|
@ -0,0 +1,33 @@
|
|||
package requests
|
||||
|
||||
import (
|
||||
"errors"
|
||||
|
||||
"github.com/status-im/status-go/eth-node/types"
|
||||
)
|
||||
|
||||
var ErrReorderCommunityCategoryInvalidCommunityID = errors.New("edit-community-category: invalid community id")
|
||||
var ErrReorderCommunityCategoryInvalidCategoryID = errors.New("edit-community-category: invalid category id")
|
||||
var ErrReorderCommunityCategoryInvalidPosition = errors.New("edit-community-category: invalid position")
|
||||
|
||||
type ReorderCommunityCategories struct {
|
||||
CommunityID types.HexBytes `json:"communityId"`
|
||||
CategoryID string `json:"categoryId"`
|
||||
Position int `json:"position"`
|
||||
}
|
||||
|
||||
func (j *ReorderCommunityCategories) Validate() error {
|
||||
if len(j.CommunityID) == 0 {
|
||||
return ErrReorderCommunityCategoryInvalidCommunityID
|
||||
}
|
||||
|
||||
if len(j.CategoryID) == 0 {
|
||||
return ErrEditCommunityCategoryInvalidCategoryID
|
||||
}
|
||||
|
||||
if j.Position < 0 {
|
||||
return ErrReorderCommunityCategoryInvalidPosition
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
|
@ -0,0 +1,39 @@
|
|||
package requests
|
||||
|
||||
import (
|
||||
"errors"
|
||||
|
||||
"github.com/status-im/status-go/eth-node/types"
|
||||
)
|
||||
|
||||
var ErrReorderCommunityChatInvalidCommunityID = errors.New("edit-community-category: invalid community id")
|
||||
var ErrReorderCommunityChatInvalidCategoryID = errors.New("edit-community-category: invalid category id")
|
||||
var ErrReorderCommunityChatInvalidChatID = errors.New("edit-community-category: invalid chat id")
|
||||
var ErrReorderCommunityChatInvalidPosition = errors.New("edit-community-category: invalid position")
|
||||
|
||||
type ReorderCommunityChat struct {
|
||||
CommunityID types.HexBytes `json:"communityId"`
|
||||
CategoryID string `json:"categoryId"`
|
||||
ChatID string `json:"chatId"`
|
||||
Position int `json:"position"`
|
||||
}
|
||||
|
||||
func (j *ReorderCommunityChat) Validate() error {
|
||||
if len(j.CommunityID) == 0 {
|
||||
return ErrReorderCommunityChatInvalidCommunityID
|
||||
}
|
||||
|
||||
if len(j.CategoryID) == 0 {
|
||||
return ErrReorderCommunityChatInvalidCategoryID
|
||||
}
|
||||
|
||||
if len(j.ChatID) == 0 {
|
||||
return ErrReorderCommunityChatInvalidChatID
|
||||
}
|
||||
|
||||
if j.Position < 0 {
|
||||
return ErrReorderCommunityCategoryInvalidPosition
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
|
@ -412,6 +412,31 @@ func (api *PublicAPI) RequestToJoinCommunity(request *requests.RequestToJoinComm
|
|||
return api.service.messenger.RequestToJoinCommunity(request)
|
||||
}
|
||||
|
||||
// CreateCommunityCategory creates a category within a particular community
|
||||
func (api *PublicAPI) CreateCommunityCategory(request *requests.CreateCommunityCategory) (*protocol.MessengerResponse, error) {
|
||||
return api.service.messenger.CreateCommunityCategory(request)
|
||||
}
|
||||
|
||||
// ReorderCommunityCategories is used to change the order of the categories of a community
|
||||
func (api *PublicAPI) ReorderCommunityCategories(request *requests.ReorderCommunityCategories) (*protocol.MessengerResponse, error) {
|
||||
return api.service.messenger.ReorderCommunityCategories(request)
|
||||
}
|
||||
|
||||
// ReorderCommunityChat allows changing the order of the chat or switching its category
|
||||
func (api *PublicAPI) ReorderCommunityChat(request *requests.ReorderCommunityChat) (*protocol.MessengerResponse, error) {
|
||||
return api.service.messenger.ReorderCommunityChat(request)
|
||||
}
|
||||
|
||||
// EditCommunityCategory modifies a category within a particular community
|
||||
func (api *PublicAPI) EditCommunityCategory(request *requests.EditCommunityCategory) (*protocol.MessengerResponse, error) {
|
||||
return api.service.messenger.EditCommunityCategory(request)
|
||||
}
|
||||
|
||||
// DeleteCommunityCategory deletes a category within a particular community and removes this category from any chat that has it
|
||||
func (api *PublicAPI) DeleteCommunityCategory(request *requests.DeleteCommunityCategory) (*protocol.MessengerResponse, error) {
|
||||
return api.service.messenger.DeleteCommunityCategory(request)
|
||||
}
|
||||
|
||||
type ApplicationMessagesResponse struct {
|
||||
Messages []*common.Message `json:"messages"`
|
||||
Cursor string `json:"cursor"`
|
||||
|
|
Loading…
Reference in New Issue