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 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 {
|
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
|
golang.org/x/tools v0.0.0-20200211045251-2de505fc5306 // indirect
|
||||||
google.golang.org/genproto v0.0.0-20191115221424-83cc0476cb11 // indirect
|
google.golang.org/genproto v0.0.0-20191115221424-83cc0476cb11 // indirect
|
||||||
google.golang.org/grpc v1.25.1 // 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/assert.v1 v1.2.1 // indirect
|
||||||
gopkg.in/go-playground/validator.v9 v9.31.0
|
gopkg.in/go-playground/validator.v9 v9.31.0
|
||||||
gopkg.in/natefinch/lumberjack.v2 v2.0.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.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 h1:xsAVV57WRhGj6kEIi8ReJzQlHHqcBYCElAvkovg3B/4=
|
||||||
github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
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-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/go-querystring v1.0.0/go.mod h1:odCYkC5MyYFN7vkCjXpyrEuKhc/BUO6wN/zVPAxq5ck=
|
||||||
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
|
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.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg=
|
||||||
google.golang.org/grpc v1.25.1 h1:wdKvqQk7IttEw92GoRyKG2IDrUIpgpj6H6m81yfeMW0=
|
google.golang.org/grpc v1.25.1 h1:wdKvqQk7IttEw92GoRyKG2IDrUIpgpj6H6m81yfeMW0=
|
||||||
google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY=
|
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/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 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-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-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/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/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/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/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 h1:bmXmP2RSNtFES+bn4uYuHT7iJFJv7Vj+an+ZQdDaD1M=
|
||||||
gopkg.in/go-playground/validator.v9 v9.31.0/go.mod h1:+c9/zcJMFNgbLvly1L1V+PpxWdVbfP1avr/N00E2vyQ=
|
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/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 h1:1Lc07Kr7qY4U2YPouBjpCLxpiyxIVoxqXgkXLknAOE8=
|
||||||
gopkg.in/natefinch/lumberjack.v2 v2.0.0/go.mod h1:l0ndWWf7gzL7RNwBG7wST/UCcT4T24xpD6X8LsfU/+k=
|
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/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-20180302121509-abf0ba0be5d5/go.mod h1:uAJfkITjFhyEEuUfm7bsmCZRbW5WRq8s9EY8HZ6hCns=
|
||||||
gopkg.in/olebedev/go-duktape.v3 v3.0.0-20190709231704-1e4459ed25ff h1:uuol9OUzSvZntY1v963NAbVd7A+PHLMz1FlCe3Lorcs=
|
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/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-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/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/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 h1:NdAVW6RYxDif9DhDHaAortIu956m2c0v+09AZBPTbE0=
|
||||||
gopkg.in/urfave/cli.v1 v1.20.0/go.mod h1:vuBzUtMdQeixQj8LVd+/98pzhxNGQoyuPBlsXHOQNO0=
|
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.5/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||||
gopkg.in/yaml.v2 v2.2.6 h1:97YCGUei5WVbkKfogoJQsLwUJ17cWvpLrgNvlcbxikE=
|
gopkg.in/yaml.v2 v2.2.6 h1:97YCGUei5WVbkKfogoJQsLwUJ17cWvpLrgNvlcbxikE=
|
||||||
gopkg.in/yaml.v2 v2.2.6/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
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=
|
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-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-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-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.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=
|
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/b v1.0.0/go.mod h1:uZWcZfRj1BpYzfN9JTerzlNUnnPsV9O2ZA8JsRcubNg=
|
||||||
modernc.org/db v1.0.0/go.mod h1:kYD/cO29L/29RM0hXYl4i3+Q5VojL31kTUVpVJDw0s8=
|
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 is the id of the community it belongs to
|
||||||
CommunityID string `json:"communityId,omitempty"`
|
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 is a timestamp that indicates when the chat was joined
|
||||||
Joined int64 `json:"joined,omitempty"`
|
Joined int64 `json:"joined,omitempty"`
|
||||||
|
|
||||||
|
@ -305,6 +309,7 @@ func CreateCommunityChat(orgID, chatID string, orgChat *protobuf.CommunityChat,
|
||||||
|
|
||||||
return &Chat{
|
return &Chat{
|
||||||
CommunityID: orgID,
|
CommunityID: orgID,
|
||||||
|
CategoryID: orgChat.CategoryId,
|
||||||
Name: orgChat.Identity.DisplayName,
|
Name: orgChat.Identity.DisplayName,
|
||||||
Active: true,
|
Active: true,
|
||||||
Color: color,
|
Color: color,
|
||||||
|
|
|
@ -62,6 +62,14 @@ type CommunityChat struct {
|
||||||
Members map[string]*protobuf.CommunityMember `json:"members"`
|
Members map[string]*protobuf.CommunityMember `json:"members"`
|
||||||
Permissions *protobuf.CommunityPermissions `json:"permissions"`
|
Permissions *protobuf.CommunityPermissions `json:"permissions"`
|
||||||
CanPost bool `json:"canPost"`
|
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) {
|
func (o *Community) MarshalJSON() ([]byte, error) {
|
||||||
|
@ -77,6 +85,7 @@ func (o *Community) MarshalJSON() ([]byte, error) {
|
||||||
Name string `json:"name"`
|
Name string `json:"name"`
|
||||||
Description string `json:"description"`
|
Description string `json:"description"`
|
||||||
Chats map[string]CommunityChat `json:"chats"`
|
Chats map[string]CommunityChat `json:"chats"`
|
||||||
|
Categories map[string]CommunityCategory `json:"categories"`
|
||||||
Images map[string]images.IdentityImage `json:"images"`
|
Images map[string]images.IdentityImage `json:"images"`
|
||||||
Permissions *protobuf.CommunityPermissions `json:"permissions"`
|
Permissions *protobuf.CommunityPermissions `json:"permissions"`
|
||||||
Members map[string]*protobuf.CommunityMember `json:"members"`
|
Members map[string]*protobuf.CommunityMember `json:"members"`
|
||||||
|
@ -91,6 +100,7 @@ func (o *Community) MarshalJSON() ([]byte, error) {
|
||||||
Admin: o.IsAdmin(),
|
Admin: o.IsAdmin(),
|
||||||
Verified: o.config.Verified,
|
Verified: o.config.Verified,
|
||||||
Chats: make(map[string]CommunityChat),
|
Chats: make(map[string]CommunityChat),
|
||||||
|
Categories: make(map[string]CommunityCategory),
|
||||||
Joined: o.config.Joined,
|
Joined: o.config.Joined,
|
||||||
CanRequestAccess: o.CanRequestAccess(o.config.MemberIdentity),
|
CanRequestAccess: o.CanRequestAccess(o.config.MemberIdentity),
|
||||||
CanJoin: o.canJoin(),
|
CanJoin: o.canJoin(),
|
||||||
|
@ -99,6 +109,14 @@ func (o *Community) MarshalJSON() ([]byte, error) {
|
||||||
IsMember: o.isMember(),
|
IsMember: o.isMember(),
|
||||||
}
|
}
|
||||||
if o.config.CommunityDescription != nil {
|
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 {
|
for id, c := range o.config.CommunityDescription.Chats {
|
||||||
canPost, err := o.CanPost(o.config.MemberIdentity, id, nil)
|
canPost, err := o.CanPost(o.config.MemberIdentity, id, nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -110,6 +128,8 @@ func (o *Community) MarshalJSON() ([]byte, error) {
|
||||||
Permissions: c.Permissions,
|
Permissions: c.Permissions,
|
||||||
Members: c.Members,
|
Members: c.Members,
|
||||||
CanPost: canPost,
|
CanPost: canPost,
|
||||||
|
CategoryID: c.CategoryId,
|
||||||
|
Position: int(c.Position),
|
||||||
}
|
}
|
||||||
communityItem.Chats[id] = chat
|
communityItem.Chats[id] = chat
|
||||||
}
|
}
|
||||||
|
@ -171,6 +191,8 @@ func (o *Community) initialize() {
|
||||||
type CommunityChatChanges struct {
|
type CommunityChatChanges struct {
|
||||||
MembersAdded map[string]*protobuf.CommunityMember
|
MembersAdded map[string]*protobuf.CommunityMember
|
||||||
MembersRemoved map[string]*protobuf.CommunityMember
|
MembersRemoved map[string]*protobuf.CommunityMember
|
||||||
|
CategoryModified string
|
||||||
|
PositionModified int
|
||||||
}
|
}
|
||||||
|
|
||||||
type CommunityChanges struct {
|
type CommunityChanges struct {
|
||||||
|
@ -182,6 +204,10 @@ type CommunityChanges struct {
|
||||||
ChatsAdded map[string]*protobuf.CommunityChat `json:"chatsAdded"`
|
ChatsAdded map[string]*protobuf.CommunityChat `json:"chatsAdded"`
|
||||||
ChatsModified map[string]*CommunityChatChanges `json:"chatsModified"`
|
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
|
// ShouldMemberJoin indicates whether the user should join this community
|
||||||
// automatically
|
// automatically
|
||||||
ShouldMemberJoin bool `json:"memberAdded"`
|
ShouldMemberJoin bool `json:"memberAdded"`
|
||||||
|
@ -233,6 +259,14 @@ func (o *Community) CreateChat(chatID string, chat *protobuf.CommunityChat) (*Co
|
||||||
return nil, ErrChatAlreadyExists
|
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.config.CommunityDescription.Chats[chatID] = chat
|
||||||
|
|
||||||
o.increaseClock()
|
o.increaseClock()
|
||||||
|
@ -253,6 +287,15 @@ func (o *Community) DeleteChat(chatID string) (*protobuf.CommunityDescription, e
|
||||||
if o.config.CommunityDescription.Chats == nil {
|
if o.config.CommunityDescription.Chats == nil {
|
||||||
o.config.CommunityDescription.Chats = make(map[string]*protobuf.CommunityChat)
|
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)
|
delete(o.config.CommunityDescription.Chats, chatID)
|
||||||
|
|
||||||
o.increaseClock()
|
o.increaseClock()
|
||||||
|
@ -570,6 +613,7 @@ func (o *Community) UpdateCommunityDescription(signer *ecdsa.PublicKey, descript
|
||||||
if o.config.CommunityDescription.Chats == nil {
|
if o.config.CommunityDescription.Chats == nil {
|
||||||
o.config.CommunityDescription.Chats = make(map[string]*protobuf.CommunityChat)
|
o.config.CommunityDescription.Chats = make(map[string]*protobuf.CommunityChat)
|
||||||
}
|
}
|
||||||
|
|
||||||
if _, ok := o.config.CommunityDescription.Chats[chatID]; !ok {
|
if _, ok := o.config.CommunityDescription.Chats[chatID]; !ok {
|
||||||
if response.ChatsAdded == nil {
|
if response.ChatsAdded == nil {
|
||||||
response.ChatsAdded = make(map[string]*protobuf.CommunityChat)
|
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
|
o.config.CommunityDescription = description
|
||||||
|
@ -765,6 +868,17 @@ func (o *Community) Chats() map[string]*protobuf.CommunityChat {
|
||||||
return response
|
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) {
|
func (o *Community) VerifyGrantSignature(data []byte) (*protobuf.Grant, error) {
|
||||||
if len(data) <= signatureLength {
|
if len(data) <= signatureLength {
|
||||||
return nil, ErrInvalidGrant
|
return nil, ErrInvalidGrant
|
||||||
|
@ -1015,5 +1129,28 @@ func emptyCommunityChanges() *CommunityChanges {
|
||||||
ChatsRemoved: make(map[string]*protobuf.CommunityChat),
|
ChatsRemoved: make(map[string]*protobuf.CommunityChat),
|
||||||
ChatsAdded: make(map[string]*protobuf.CommunityChat),
|
ChatsAdded: make(map[string]*protobuf.CommunityChat),
|
||||||
ChatsModified: make(map[string]*CommunityChatChanges),
|
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 testChatID1 = "chat-id-1"
|
||||||
|
const testCategoryID1 = "category-id-1"
|
||||||
|
const testCategoryName1 = "category-name-1"
|
||||||
const testChatID2 = "chat-id-2"
|
const testChatID2 = "chat-id-2"
|
||||||
|
|
||||||
type CommunitySuite struct {
|
type CommunitySuite struct {
|
||||||
|
@ -131,9 +133,9 @@ func (s *CommunitySuite) TestCreateChat() {
|
||||||
|
|
||||||
s.Require().NoError(err)
|
s.Require().NoError(err)
|
||||||
s.Require().NotNil(description)
|
s.Require().NotNil(description)
|
||||||
|
|
||||||
s.Require().NotNil(description.Chats[newChatID])
|
s.Require().NotNil(description.Chats[newChatID])
|
||||||
s.Require().NotEmpty(description.Clock)
|
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(permissions, description.Chats[newChatID].Permissions)
|
||||||
s.Require().Equal(identity, description.Chats[newChatID].Identity)
|
s.Require().Equal(identity, description.Chats[newChatID].Identity)
|
||||||
|
|
||||||
|
@ -705,10 +707,12 @@ func (s *CommunitySuite) emptyCommunityDescriptionWithChat() *protobuf.Community
|
||||||
Members: make(map[string]*protobuf.CommunityMember),
|
Members: make(map[string]*protobuf.CommunityMember),
|
||||||
Clock: 1,
|
Clock: 1,
|
||||||
Chats: make(map[string]*protobuf.CommunityChat),
|
Chats: make(map[string]*protobuf.CommunityChat),
|
||||||
|
Categories: make(map[string]*protobuf.CommunityCategory),
|
||||||
Permissions: &protobuf.CommunityPermissions{},
|
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.Members[common.PubkeyToHex(&s.member1.PublicKey)] = &protobuf.CommunityMember{}
|
||||||
desc.Chats[testChatID1].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"
|
import "errors"
|
||||||
|
|
||||||
var ErrChatNotFound = errors.New("chat not found")
|
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 ErrOrgNotFound = errors.New("community not found")
|
||||||
var ErrChatAlreadyExists = errors.New("chat already exists")
|
var ErrChatAlreadyExists = errors.New("chat already exists")
|
||||||
|
var ErrCategoryAlreadyExists = errors.New("category already exists")
|
||||||
var ErrCantRequestAccess = errors.New("can't request access")
|
var ErrCantRequestAccess = errors.New("can't request access")
|
||||||
var ErrInvalidCommunityDescription = errors.New("invalid community description")
|
var ErrInvalidCommunityDescription = errors.New("invalid community description")
|
||||||
var ErrInvalidCommunityDescriptionNoOrgPermissions = errors.New("invalid community description no org permissions")
|
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 ErrInvalidCommunityDescriptionUnknownChatAccess = errors.New("invalid community description unknown chat access")
|
||||||
var ErrInvalidCommunityDescriptionUnknownOrgAccess = errors.New("invalid community description unknown org 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 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 ErrNotAdmin = errors.New("no admin privileges for this community")
|
||||||
var ErrInvalidGrant = errors.New("invalid grant")
|
var ErrInvalidGrant = errors.New("invalid grant")
|
||||||
var ErrNotAuthorized = errors.New("not authorized")
|
var ErrNotAuthorized = errors.New("not authorized")
|
||||||
|
|
|
@ -310,6 +310,131 @@ func (m *Manager) CreateChat(communityID types.HexBytes, chat *protobuf.Communit
|
||||||
return community, changes, nil
|
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) {
|
func (m *Manager) HandleCommunityDescriptionMessage(signer *ecdsa.PublicKey, description *protobuf.CommunityDescription, payload []byte) (*CommunityResponse, error) {
|
||||||
id := crypto.CompressPubkey(signer)
|
id := crypto.CompressPubkey(signer)
|
||||||
community, err := m.persistence.GetByID(m.identity, id)
|
community, err := m.persistence.GetByID(m.identity, id)
|
||||||
|
|
|
@ -15,6 +15,12 @@ func validateCommunityChat(desc *protobuf.CommunityDescription, chat *protobuf.C
|
||||||
return ErrInvalidCommunityDescriptionUnknownChatAccess
|
return ErrInvalidCommunityDescriptionUnknownChatAccess
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if len(chat.CategoryId) != 0 {
|
||||||
|
if _, exists := desc.Categories[chat.CategoryId]; !exists {
|
||||||
|
return ErrInvalidCommunityDescriptionUnknownChatCategory
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
for pk := range chat.Members {
|
for pk := range chat.Members {
|
||||||
if desc.Members == nil {
|
if desc.Members == nil {
|
||||||
return ErrInvalidCommunityDescriptionMemberInChatButNotInOrg
|
return ErrInvalidCommunityDescriptionMemberInChatButNotInOrg
|
||||||
|
@ -28,6 +34,18 @@ func validateCommunityChat(desc *protobuf.CommunityDescription, chat *protobuf.C
|
||||||
return nil
|
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 {
|
func ValidateCommunityDescription(desc *protobuf.CommunityDescription) error {
|
||||||
if desc == nil {
|
if desc == nil {
|
||||||
return ErrInvalidCommunityDescription
|
return ErrInvalidCommunityDescription
|
||||||
|
@ -39,6 +57,12 @@ func ValidateCommunityDescription(desc *protobuf.CommunityDescription) error {
|
||||||
return ErrInvalidCommunityDescriptionUnknownOrgAccess
|
return ErrInvalidCommunityDescriptionUnknownOrgAccess
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for _, category := range desc.Categories {
|
||||||
|
if err := validateCommunityCategory(category); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
for _, chat := range desc.Chats {
|
for _, chat := range desc.Chats {
|
||||||
if err := validateCommunityChat(desc, chat); err != nil {
|
if err := validateCommunityChat(desc, chat); err != nil {
|
||||||
return err
|
return err
|
||||||
|
|
|
@ -186,6 +186,26 @@ func (s *MessengerCommunitiesSuite) TestJoinCommunity() {
|
||||||
s.Require().NotEmpty(createdChat.Timestamp)
|
s.Require().NotEmpty(createdChat.Timestamp)
|
||||||
s.Require().True(strings.HasPrefix(createdChat.ID, community.IDString()))
|
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
|
// Make sure the changes are reflect in the community
|
||||||
community = response.Communities()[0]
|
community = response.Communities()[0]
|
||||||
chats := community.Chats()
|
chats := community.Chats()
|
||||||
|
@ -231,6 +251,12 @@ func (s *MessengerCommunitiesSuite) TestJoinCommunity() {
|
||||||
s.Require().Len(response.Communities(), 1)
|
s.Require().Len(response.Communities(), 1)
|
||||||
s.Require().True(response.Communities()[0].Joined())
|
s.Require().True(response.Communities()[0].Joined())
|
||||||
s.Require().Len(response.Chats(), 1)
|
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
|
// The chat should be created
|
||||||
createdChat = response.Chats()[0]
|
createdChat = response.Chats()[0]
|
||||||
|
@ -238,6 +264,7 @@ func (s *MessengerCommunitiesSuite) TestJoinCommunity() {
|
||||||
s.Require().Equal(orgChat.Identity.DisplayName, createdChat.Name)
|
s.Require().Equal(orgChat.Identity.DisplayName, createdChat.Name)
|
||||||
s.Require().NotEmpty(createdChat.ID)
|
s.Require().NotEmpty(createdChat.ID)
|
||||||
s.Require().Equal(ChatTypeCommunityChat, createdChat.ChatType)
|
s.Require().Equal(ChatTypeCommunityChat, createdChat.ChatType)
|
||||||
|
s.Require().Equal(categoryID, createdChat.CategoryID)
|
||||||
s.Require().True(createdChat.Active)
|
s.Require().True(createdChat.Active)
|
||||||
s.Require().NotEmpty(createdChat.Timestamp)
|
s.Require().NotEmpty(createdChat.Timestamp)
|
||||||
s.Require().True(strings.HasPrefix(createdChat.ID, community.IDString()))
|
s.Require().True(strings.HasPrefix(createdChat.ID, community.IDString()))
|
||||||
|
@ -464,6 +491,15 @@ func (s *MessengerCommunitiesSuite) TestImportCommunity() {
|
||||||
|
|
||||||
community := response.Communities()[0]
|
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())
|
privateKey, err := s.bob.ExportCommunity(community.ID())
|
||||||
s.Require().NoError(err)
|
s.Require().NoError(err)
|
||||||
|
|
||||||
|
@ -496,6 +532,7 @@ func (s *MessengerCommunitiesSuite) TestImportCommunity() {
|
||||||
|
|
||||||
s.Require().NoError(err)
|
s.Require().NoError(err)
|
||||||
s.Require().Len(response.Communities(), 1)
|
s.Require().Len(response.Communities(), 1)
|
||||||
|
s.Require().Len(response.Communities()[0].Categories(), 1)
|
||||||
community = response.Communities()[0]
|
community = response.Communities()[0]
|
||||||
s.Require().True(community.Joined())
|
s.Require().True(community.Joined())
|
||||||
s.Require().True(community.IsAdmin())
|
s.Require().True(community.IsAdmin())
|
||||||
|
|
|
@ -235,6 +235,86 @@ func (m *Messenger) RequestToJoinCommunity(request *requests.RequestToJoinCommun
|
||||||
return response, nil
|
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) {
|
func (m *Messenger) AcceptRequestToJoinCommunity(request *requests.AcceptRequestToJoinCommunity) (*MessengerResponse, error) {
|
||||||
if err := request.Validate(); err != nil {
|
if err := request.Validate(); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
|
|
|
@ -244,6 +244,7 @@ type CommunityDescription struct {
|
||||||
Identity *ChatIdentity `protobuf:"bytes,5,opt,name=identity,proto3" json:"identity,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"`
|
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"`
|
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_NoUnkeyedLiteral struct{} `json:"-"`
|
||||||
XXX_unrecognized []byte `json:"-"`
|
XXX_unrecognized []byte `json:"-"`
|
||||||
XXX_sizecache int32 `json:"-"`
|
XXX_sizecache int32 `json:"-"`
|
||||||
|
@ -316,10 +317,19 @@ func (m *CommunityDescription) GetBanList() []string {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (m *CommunityDescription) GetCategories() map[string]*CommunityCategory {
|
||||||
|
if m != nil {
|
||||||
|
return m.Categories
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
type CommunityChat struct {
|
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"`
|
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"`
|
Permissions *CommunityPermissions `protobuf:"bytes,2,opt,name=permissions,proto3" json:"permissions,omitempty"`
|
||||||
Identity *ChatIdentity `protobuf:"bytes,3,opt,name=identity,proto3" json:"identity,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_NoUnkeyedLiteral struct{} `json:"-"`
|
||||||
XXX_unrecognized []byte `json:"-"`
|
XXX_unrecognized []byte `json:"-"`
|
||||||
XXX_sizecache int32 `json:"-"`
|
XXX_sizecache int32 `json:"-"`
|
||||||
|
@ -371,6 +381,75 @@ func (m *CommunityChat) GetIdentity() *ChatIdentity {
|
||||||
return nil
|
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 {
|
type CommunityInvitation struct {
|
||||||
CommunityDescription []byte `protobuf:"bytes,1,opt,name=community_description,json=communityDescription,proto3" json:"community_description,omitempty"`
|
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"`
|
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 (m *CommunityInvitation) String() string { return proto.CompactTextString(m) }
|
||||||
func (*CommunityInvitation) ProtoMessage() {}
|
func (*CommunityInvitation) ProtoMessage() {}
|
||||||
func (*CommunityInvitation) Descriptor() ([]byte, []int) {
|
func (*CommunityInvitation) Descriptor() ([]byte, []int) {
|
||||||
return fileDescriptor_f937943d74c1cd8b, []int{5}
|
return fileDescriptor_f937943d74c1cd8b, []int{6}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *CommunityInvitation) XXX_Unmarshal(b []byte) error {
|
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 (m *CommunityRequestToJoin) String() string { return proto.CompactTextString(m) }
|
||||||
func (*CommunityRequestToJoin) ProtoMessage() {}
|
func (*CommunityRequestToJoin) ProtoMessage() {}
|
||||||
func (*CommunityRequestToJoin) Descriptor() ([]byte, []int) {
|
func (*CommunityRequestToJoin) Descriptor() ([]byte, []int) {
|
||||||
return fileDescriptor_f937943d74c1cd8b, []int{6}
|
return fileDescriptor_f937943d74c1cd8b, []int{7}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *CommunityRequestToJoin) XXX_Unmarshal(b []byte) error {
|
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 (m *CommunityRequestToJoinResponse) String() string { return proto.CompactTextString(m) }
|
||||||
func (*CommunityRequestToJoinResponse) ProtoMessage() {}
|
func (*CommunityRequestToJoinResponse) ProtoMessage() {}
|
||||||
func (*CommunityRequestToJoinResponse) Descriptor() ([]byte, []int) {
|
func (*CommunityRequestToJoinResponse) Descriptor() ([]byte, []int) {
|
||||||
return fileDescriptor_f937943d74c1cd8b, []int{7}
|
return fileDescriptor_f937943d74c1cd8b, []int{8}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *CommunityRequestToJoinResponse) XXX_Unmarshal(b []byte) error {
|
func (m *CommunityRequestToJoinResponse) XXX_Unmarshal(b []byte) error {
|
||||||
|
@ -567,10 +646,12 @@ func init() {
|
||||||
proto.RegisterType((*CommunityMember)(nil), "protobuf.CommunityMember")
|
proto.RegisterType((*CommunityMember)(nil), "protobuf.CommunityMember")
|
||||||
proto.RegisterType((*CommunityPermissions)(nil), "protobuf.CommunityPermissions")
|
proto.RegisterType((*CommunityPermissions)(nil), "protobuf.CommunityPermissions")
|
||||||
proto.RegisterType((*CommunityDescription)(nil), "protobuf.CommunityDescription")
|
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]*CommunityChat)(nil), "protobuf.CommunityDescription.ChatsEntry")
|
||||||
proto.RegisterMapType((map[string]*CommunityMember)(nil), "protobuf.CommunityDescription.MembersEntry")
|
proto.RegisterMapType((map[string]*CommunityMember)(nil), "protobuf.CommunityDescription.MembersEntry")
|
||||||
proto.RegisterType((*CommunityChat)(nil), "protobuf.CommunityChat")
|
proto.RegisterType((*CommunityChat)(nil), "protobuf.CommunityChat")
|
||||||
proto.RegisterMapType((map[string]*CommunityMember)(nil), "protobuf.CommunityChat.MembersEntry")
|
proto.RegisterMapType((map[string]*CommunityMember)(nil), "protobuf.CommunityChat.MembersEntry")
|
||||||
|
proto.RegisterType((*CommunityCategory)(nil), "protobuf.CommunityCategory")
|
||||||
proto.RegisterType((*CommunityInvitation)(nil), "protobuf.CommunityInvitation")
|
proto.RegisterType((*CommunityInvitation)(nil), "protobuf.CommunityInvitation")
|
||||||
proto.RegisterType((*CommunityRequestToJoin)(nil), "protobuf.CommunityRequestToJoin")
|
proto.RegisterType((*CommunityRequestToJoin)(nil), "protobuf.CommunityRequestToJoin")
|
||||||
proto.RegisterType((*CommunityRequestToJoinResponse)(nil), "protobuf.CommunityRequestToJoinResponse")
|
proto.RegisterType((*CommunityRequestToJoinResponse)(nil), "protobuf.CommunityRequestToJoinResponse")
|
||||||
|
@ -581,53 +662,59 @@ func init() {
|
||||||
}
|
}
|
||||||
|
|
||||||
var fileDescriptor_f937943d74c1cd8b = []byte{
|
var fileDescriptor_f937943d74c1cd8b = []byte{
|
||||||
// 758 bytes of a gzipped FileDescriptorProto
|
// 850 bytes of a gzipped FileDescriptorProto
|
||||||
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xb4, 0x54, 0xef, 0x6e, 0xda, 0x48,
|
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xb4, 0x55, 0xef, 0x8e, 0xdb, 0x44,
|
||||||
0x10, 0x8f, 0x31, 0x7f, 0xcc, 0x40, 0x88, 0xb3, 0xf9, 0xe7, 0x70, 0xba, 0x1c, 0x67, 0xdd, 0x49,
|
0x10, 0xef, 0xc6, 0x71, 0xe2, 0x4c, 0xd2, 0x3b, 0xdf, 0xde, 0xb5, 0x75, 0xaf, 0xa2, 0x0d, 0x16,
|
||||||
0x9c, 0x4e, 0xc7, 0x49, 0x44, 0x27, 0x9d, 0xaa, 0x36, 0x2d, 0x4d, 0xad, 0xd4, 0x0d, 0x98, 0x64,
|
0x48, 0x41, 0x88, 0x20, 0x52, 0x21, 0x21, 0x04, 0x85, 0x70, 0x58, 0xc5, 0x34, 0xe7, 0xb4, 0x9b,
|
||||||
0x81, 0x56, 0xfd, 0x64, 0x19, 0xb3, 0x6d, 0xad, 0xc0, 0x9a, 0x7a, 0x0d, 0x12, 0x0f, 0x50, 0xa9,
|
0x1c, 0x08, 0xbe, 0x58, 0x8e, 0xb3, 0x94, 0x55, 0x13, 0xdb, 0x78, 0x9d, 0x93, 0xf2, 0x00, 0x48,
|
||||||
0x8f, 0xd0, 0x0f, 0xfd, 0xdc, 0xe7, 0xea, 0x1b, 0xf4, 0x15, 0x2a, 0xef, 0x02, 0x76, 0x52, 0x48,
|
0x3c, 0x02, 0x12, 0xdf, 0x79, 0x27, 0xbe, 0xf1, 0x28, 0x68, 0x77, 0xe3, 0x3f, 0xb9, 0x4b, 0xda,
|
||||||
0x23, 0x55, 0xfd, 0x64, 0xcf, 0xce, 0xcc, 0x6f, 0x67, 0x7e, 0x33, 0xfb, 0x83, 0x6d, 0xd7, 0x1f,
|
0x93, 0x50, 0x3f, 0xc5, 0xb3, 0xbb, 0xf3, 0x9b, 0xdf, 0xfc, 0x66, 0x32, 0x03, 0x47, 0x61, 0xbc,
|
||||||
0x8d, 0x26, 0xd4, 0x0b, 0x3d, 0xc2, 0x6a, 0xe3, 0xc0, 0x0f, 0x7d, 0xa4, 0xf0, 0x4f, 0x7f, 0xf2,
|
0x5c, 0xae, 0x22, 0x96, 0x31, 0xca, 0xfb, 0x49, 0x1a, 0x67, 0x31, 0x36, 0xe4, 0xcf, 0x6c, 0xf5,
|
||||||
0xaa, 0xbc, 0xe3, 0xbe, 0x71, 0x42, 0xdb, 0x1b, 0x10, 0x1a, 0x7a, 0xe1, 0x4c, 0xb8, 0xf5, 0x29,
|
0xcb, 0xe9, 0x71, 0xf8, 0x6b, 0x90, 0xf9, 0x6c, 0x4e, 0xa3, 0x8c, 0x65, 0x6b, 0x75, 0x6d, 0x5f,
|
||||||
0x64, 0xce, 0x02, 0x87, 0x86, 0xe8, 0x77, 0x28, 0x2e, 0x92, 0x67, 0xb6, 0x37, 0xd0, 0xa4, 0x8a,
|
0x82, 0xfe, 0x34, 0x0d, 0xa2, 0x0c, 0xbf, 0x0b, 0x9d, 0xdc, 0x79, 0xed, 0xb3, 0xb9, 0x85, 0xba,
|
||||||
0x54, 0x2d, 0xe2, 0xc2, 0xf2, 0xcc, 0x1c, 0xa0, 0x5f, 0x20, 0x3f, 0x22, 0xa3, 0x3e, 0x09, 0x22,
|
0xa8, 0xd7, 0x21, 0xed, 0xe2, 0xcc, 0x9d, 0xe3, 0x07, 0xd0, 0x5a, 0xd2, 0xe5, 0x8c, 0xa6, 0xe2,
|
||||||
0x7f, 0x8a, 0xfb, 0x15, 0x71, 0x60, 0x0e, 0xd0, 0x01, 0xe4, 0xe6, 0xf8, 0x9a, 0x5c, 0x91, 0xaa,
|
0xbe, 0x26, 0xef, 0x0d, 0x75, 0xe0, 0xce, 0xf1, 0x3d, 0x68, 0x6e, 0xf0, 0x2d, 0xad, 0x8b, 0x7a,
|
||||||
0x79, 0x9c, 0x8d, 0x4c, 0x73, 0x80, 0x76, 0x21, 0xe3, 0x0e, 0x7d, 0xf7, 0x4a, 0x4b, 0x57, 0xa4,
|
0x2d, 0xd2, 0x10, 0xa6, 0x3b, 0xc7, 0x27, 0xa0, 0x87, 0x8b, 0x38, 0x7c, 0x65, 0xd5, 0xbb, 0xa8,
|
||||||
0x6a, 0x1a, 0x0b, 0x43, 0x7f, 0x2f, 0xc1, 0xd6, 0xe9, 0x02, 0xbb, 0xc5, 0x41, 0xd0, 0x7f, 0x90,
|
0x57, 0x27, 0xca, 0xb0, 0xff, 0x40, 0x70, 0x78, 0x96, 0x63, 0x9f, 0x4b, 0x10, 0xfc, 0x29, 0xe8,
|
||||||
0x09, 0xfc, 0x21, 0x61, 0x9a, 0x54, 0x91, 0xab, 0xa5, 0xfa, 0x6f, 0xb5, 0x45, 0xe9, 0xb5, 0x1b,
|
0x69, 0xbc, 0xa0, 0xdc, 0x42, 0x5d, 0xad, 0x77, 0x30, 0x78, 0xd4, 0xcf, 0xa9, 0xf7, 0xaf, 0xbc,
|
||||||
0x91, 0x35, 0x1c, 0x85, 0x61, 0x11, 0xad, 0x9f, 0x40, 0x86, 0xdb, 0x48, 0x85, 0x62, 0xcf, 0x3a,
|
0xec, 0x13, 0xf1, 0x8c, 0xa8, 0xd7, 0xf6, 0x13, 0xd0, 0xa5, 0x8d, 0x4d, 0xe8, 0x5c, 0x78, 0xcf,
|
||||||
0xb7, 0xda, 0x2f, 0x2c, 0x1b, 0xb7, 0x9b, 0x86, 0xba, 0x81, 0x8a, 0xa0, 0x44, 0x7f, 0x76, 0xa3,
|
0xbc, 0xf1, 0x8f, 0x9e, 0x4f, 0xc6, 0x23, 0xc7, 0xbc, 0x85, 0x3b, 0x60, 0x88, 0x2f, 0x7f, 0x38,
|
||||||
0xd9, 0x54, 0x25, 0xb4, 0x07, 0xdb, 0xdc, 0x6a, 0x35, 0xac, 0xc6, 0x99, 0x61, 0xf7, 0x3a, 0x06,
|
0x1a, 0x99, 0x08, 0xdf, 0x81, 0x23, 0x69, 0x9d, 0x0f, 0xbd, 0xe1, 0x53, 0xc7, 0xbf, 0x98, 0x38,
|
||||||
0xee, 0xa8, 0x29, 0xfd, 0xb3, 0x04, 0xbb, 0xcb, 0x0b, 0x2e, 0x48, 0x30, 0xf2, 0x18, 0xf3, 0x7c,
|
0x64, 0x62, 0xd6, 0xec, 0x7f, 0x11, 0x9c, 0x14, 0x01, 0x9e, 0xd3, 0x74, 0xc9, 0x38, 0x67, 0x71,
|
||||||
0xca, 0xd0, 0x21, 0x28, 0x84, 0x32, 0xdb, 0xa7, 0xc3, 0x19, 0xa7, 0x43, 0xc1, 0x39, 0x42, 0x59,
|
0xc4, 0xf1, 0x7d, 0x30, 0x68, 0xc4, 0xfd, 0x38, 0x5a, 0xac, 0xa5, 0x1c, 0x06, 0x69, 0xd2, 0x88,
|
||||||
0x9b, 0x0e, 0x67, 0x48, 0x83, 0xdc, 0x38, 0xf0, 0xa6, 0x4e, 0x48, 0x38, 0x11, 0x0a, 0x5e, 0x98,
|
0x8f, 0xa3, 0xc5, 0x1a, 0x5b, 0xd0, 0x4c, 0x52, 0x76, 0x19, 0x64, 0x54, 0x0a, 0x61, 0x90, 0xdc,
|
||||||
0xe8, 0x01, 0x64, 0x1d, 0xd7, 0x25, 0x8c, 0x71, 0x1a, 0x4a, 0xf5, 0x3f, 0x57, 0x74, 0x91, 0xb8,
|
0xc4, 0x5f, 0x42, 0x23, 0x08, 0x43, 0xca, 0xb9, 0x94, 0xe1, 0x60, 0xf0, 0xfe, 0x8e, 0x2c, 0x2a,
|
||||||
0xa4, 0xd6, 0xe0, 0xc1, 0x78, 0x9e, 0xa4, 0x77, 0x21, 0x2b, 0x4e, 0x10, 0x82, 0xd2, 0xa2, 0x9b,
|
0x41, 0xfa, 0x43, 0xf9, 0x98, 0x6c, 0x9c, 0xec, 0x29, 0x34, 0xd4, 0x09, 0xc6, 0x70, 0x90, 0x67,
|
||||||
0xc6, 0xe9, 0xa9, 0xd1, 0xe9, 0xa8, 0x1b, 0x68, 0x1b, 0x36, 0xad, 0xb6, 0xdd, 0x32, 0x5a, 0x8f,
|
0x33, 0x3c, 0x3b, 0x73, 0x26, 0x13, 0xf3, 0x16, 0x3e, 0x82, 0xdb, 0xde, 0xd8, 0x3f, 0x77, 0xce,
|
||||||
0x0d, 0xdc, 0x79, 0x6a, 0x5e, 0xa8, 0x12, 0xda, 0x81, 0x2d, 0xd3, 0x7a, 0x6e, 0x76, 0x1b, 0x5d,
|
0xbf, 0x71, 0xc8, 0xe4, 0x3b, 0xf7, 0xb9, 0x89, 0xf0, 0x31, 0x1c, 0xba, 0xde, 0x0f, 0xee, 0x74,
|
||||||
0xb3, 0x6d, 0xd9, 0x6d, 0xab, 0xf9, 0x52, 0x4d, 0xa1, 0x12, 0x40, 0xdb, 0xb2, 0xb1, 0x71, 0xd9,
|
0x38, 0x75, 0xc7, 0x9e, 0x3f, 0xf6, 0x46, 0x3f, 0x99, 0x35, 0x7c, 0x00, 0x30, 0xf6, 0x7c, 0xe2,
|
||||||
0x33, 0x3a, 0x5d, 0x55, 0xd6, 0xbf, 0xc8, 0x89, 0x16, 0x9f, 0x10, 0xe6, 0x06, 0xde, 0x38, 0xf4,
|
0xbc, 0xb8, 0x70, 0x26, 0x53, 0x53, 0xb3, 0xff, 0xd2, 0x2b, 0x29, 0x7e, 0x4b, 0x79, 0x98, 0xb2,
|
||||||
0x7c, 0x1a, 0x0f, 0x47, 0x4a, 0x0c, 0x07, 0x19, 0x90, 0x13, 0x73, 0x65, 0x5a, 0xaa, 0x22, 0x57,
|
0x24, 0x63, 0x71, 0x54, 0x16, 0x07, 0x55, 0x8a, 0x83, 0x1d, 0x68, 0xaa, 0xba, 0x72, 0xab, 0xd6,
|
||||||
0x0b, 0xf5, 0xbf, 0x57, 0x34, 0x91, 0x80, 0xa9, 0x89, 0xb1, 0x30, 0x83, 0x86, 0xc1, 0x0c, 0x2f,
|
0xd5, 0x7a, 0xed, 0xc1, 0x87, 0x3b, 0x92, 0xa8, 0xc0, 0xf4, 0x55, 0x59, 0xb8, 0x13, 0x65, 0xe9,
|
||||||
0x72, 0xd1, 0x23, 0x28, 0x8c, 0xe3, 0x4e, 0x39, 0x1f, 0x85, 0xfa, 0xd1, 0xed, 0x7c, 0xe0, 0x64,
|
0x9a, 0xe4, 0xbe, 0xf8, 0x6b, 0x68, 0x27, 0x65, 0xa6, 0x52, 0x8f, 0xf6, 0xe0, 0xe1, 0xeb, 0xf5,
|
||||||
0x0a, 0xaa, 0x83, 0xb2, 0xd8, 0x57, 0x2d, 0xc3, 0xd3, 0xf7, 0x13, 0xe9, 0x7c, 0xbf, 0x84, 0x17,
|
0x20, 0x55, 0x17, 0x3c, 0x00, 0x23, 0xef, 0x57, 0x4b, 0x97, 0xee, 0x77, 0x2b, 0xee, 0xb2, 0xbf,
|
||||||
0x2f, 0xe3, 0xd0, 0x43, 0xc8, 0x44, 0x9b, 0xc7, 0xb4, 0x2c, 0x2f, 0xfd, 0xaf, 0xef, 0x94, 0x1e,
|
0xd4, 0x2d, 0x29, 0xde, 0xe1, 0xaf, 0x40, 0x17, 0x9d, 0xc7, 0xad, 0x86, 0xa4, 0xfe, 0xc1, 0x1b,
|
||||||
0xa1, 0xcc, 0x0b, 0x17, 0x79, 0xd1, 0xd8, 0xfb, 0x0e, 0xb5, 0x87, 0x1e, 0x0b, 0xb5, 0x5c, 0x45,
|
0xa8, 0x0b, 0x94, 0x0d, 0x71, 0xe5, 0x27, 0xca, 0x3e, 0x0b, 0x22, 0x7f, 0xc1, 0x78, 0x66, 0x35,
|
||||||
0xae, 0xe6, 0x71, 0xae, 0xef, 0xd0, 0xa6, 0xc7, 0xc2, 0x72, 0x0f, 0x8a, 0xc9, 0x56, 0x91, 0x0a,
|
0xbb, 0x5a, 0xaf, 0x45, 0x9a, 0xb3, 0x20, 0x1a, 0x31, 0x9e, 0x61, 0x0f, 0x20, 0x0c, 0x32, 0xfa,
|
||||||
0xf2, 0x15, 0x11, 0xcb, 0x91, 0xc7, 0xd1, 0x2f, 0xfa, 0x17, 0x32, 0x53, 0x67, 0x38, 0x11, 0x6b,
|
0x32, 0x4e, 0x19, 0xe5, 0x96, 0x21, 0x03, 0xf4, 0xdf, 0x14, 0xa0, 0x70, 0x50, 0x51, 0x2a, 0x08,
|
||||||
0x51, 0xa8, 0x1f, 0xae, 0xdd, 0x61, 0x2c, 0xe2, 0xee, 0xa5, 0xfe, 0x97, 0xca, 0x97, 0x00, 0x71,
|
0xa7, 0x17, 0xd0, 0xa9, 0x4a, 0x87, 0x4d, 0xd0, 0x5e, 0x51, 0xd5, 0x6c, 0x2d, 0x22, 0x3e, 0xf1,
|
||||||
0x19, 0x2b, 0x40, 0xff, 0xb9, 0x0e, 0x7a, 0xb0, 0x02, 0x34, 0xca, 0x4f, 0x40, 0xea, 0x1f, 0x53,
|
0xc7, 0xa0, 0x5f, 0x06, 0x8b, 0x95, 0x6a, 0xb3, 0xf6, 0xe0, 0xfe, 0xde, 0xff, 0x04, 0x51, 0xef,
|
||||||
0xb0, 0x79, 0xcd, 0x89, 0x4e, 0xe2, 0xa1, 0x4a, 0x9c, 0x99, 0x3f, 0xd6, 0xc0, 0xdc, 0x6d, 0x9a,
|
0x3e, 0xaf, 0x7d, 0x86, 0x4e, 0x5f, 0x00, 0x94, 0x69, 0xed, 0x00, 0xfd, 0x68, 0x1b, 0xf4, 0xde,
|
||||||
0xa9, 0x1f, 0x9b, 0xa6, 0x7c, 0xb7, 0x69, 0xfe, 0x24, 0xc6, 0xf5, 0x0f, 0x12, 0xec, 0x2c, 0xdd,
|
0x0e, 0x50, 0xe1, 0x5f, 0x85, 0xfc, 0x19, 0x0e, 0xaf, 0x24, 0xb2, 0x03, 0xf7, 0x93, 0x6d, 0xdc,
|
||||||
0x26, 0x9d, 0x7a, 0xa1, 0xc3, 0xdf, 0xc3, 0x31, 0xec, 0xc5, 0x2a, 0x38, 0x88, 0xd7, 0x64, 0x2e,
|
0x07, 0xbb, 0x70, 0x15, 0xc8, 0xba, 0x82, 0x6d, 0xff, 0x53, 0x83, 0xdb, 0x5b, 0x81, 0xf1, 0x93,
|
||||||
0x87, 0xbb, 0xee, 0x9a, 0x47, 0xf4, 0x3a, 0xd2, 0xd0, 0xb9, 0x26, 0x0a, 0x63, 0xbd, 0x20, 0xfe,
|
0xb2, 0x01, 0x91, 0x14, 0xf9, 0xbd, 0x3d, 0x14, 0x6f, 0xd6, 0x79, 0xb5, 0xff, 0xd7, 0x79, 0xda,
|
||||||
0x0a, 0x30, 0x9e, 0xf4, 0x87, 0x9e, 0x6b, 0x47, 0x9d, 0xa4, 0x79, 0x4e, 0x5e, 0x9c, 0x9c, 0x93,
|
0x0d, 0x3b, 0xef, 0x11, 0xb4, 0x37, 0xb5, 0x95, 0x13, 0xb4, 0x2e, 0x85, 0xc9, 0xcb, 0x2d, 0x06,
|
||||||
0x99, 0xfe, 0x4e, 0x82, 0xfd, 0x65, 0x69, 0x98, 0xbc, 0x9d, 0x10, 0x16, 0x76, 0xfd, 0x67, 0xbe,
|
0xe8, 0x29, 0x18, 0x49, 0xcc, 0x99, 0x68, 0x0b, 0xd9, 0xce, 0x3a, 0x29, 0xec, 0xb7, 0xd4, 0x0a,
|
||||||
0xb7, 0xee, 0xb5, 0xce, 0x65, 0x8a, 0x3a, 0x23, 0xc1, 0x41, 0x9e, 0xcb, 0x94, 0xe5, 0x8c, 0xc8,
|
0xf6, 0x1c, 0x8e, 0xae, 0x69, 0x7f, 0x95, 0x28, 0xba, 0x46, 0x14, 0x43, 0x3d, 0x0a, 0x96, 0x2a,
|
||||||
0xfa, 0x1a, 0x6e, 0xaa, 0x7d, 0xfa, 0x1b, 0xb5, 0xd7, 0x3f, 0x49, 0x70, 0xb4, 0xba, 0x0e, 0x4c,
|
0x52, 0x8b, 0xc8, 0xef, 0x2d, 0xf2, 0xda, 0x36, 0x79, 0xfb, 0x4f, 0x04, 0xc7, 0x45, 0x18, 0x37,
|
||||||
0xd8, 0xd8, 0xa7, 0x8c, 0xac, 0xa9, 0xe7, 0x3e, 0xe4, 0x97, 0x38, 0xb7, 0xac, 0x49, 0x82, 0x41,
|
0xba, 0x64, 0x59, 0x20, 0xc7, 0xcb, 0x63, 0xb8, 0x53, 0x2e, 0x95, 0x79, 0xf9, 0xa7, 0xd8, 0x6c,
|
||||||
0x1c, 0x27, 0xa0, 0x32, 0x28, 0x91, 0x14, 0x8e, 0x43, 0x22, 0x6a, 0x56, 0xf0, 0xd2, 0x8e, 0x89,
|
0x97, 0x93, 0x70, 0xcf, 0x4c, 0x7a, 0x29, 0x56, 0xd2, 0x66, 0xc5, 0x28, 0x63, 0xff, 0x7e, 0x79,
|
||||||
0x4e, 0x27, 0x88, 0xee, 0x67, 0x39, 0xf6, 0xf1, 0xd7, 0x00, 0x00, 0x00, 0xff, 0xff, 0x16, 0xf8,
|
0x07, 0x20, 0x59, 0xcd, 0x16, 0x2c, 0xf4, 0x85, 0x5e, 0x75, 0xe9, 0xd3, 0x52, 0x27, 0xcf, 0xe8,
|
||||||
0x6e, 0x5b, 0xfd, 0x06, 0x00, 0x00,
|
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;
|
ChatIdentity identity = 5;
|
||||||
map<string,CommunityChat> chats = 6;
|
map<string,CommunityChat> chats = 6;
|
||||||
repeated string ban_list = 7;
|
repeated string ban_list = 7;
|
||||||
|
map<string,CommunityCategory> categories = 8;
|
||||||
}
|
}
|
||||||
|
|
||||||
message CommunityChat {
|
message CommunityChat {
|
||||||
map<string,CommunityMember> members = 1;
|
map<string,CommunityMember> members = 1;
|
||||||
CommunityPermissions permissions = 2;
|
CommunityPermissions permissions = 2;
|
||||||
ChatIdentity identity = 3;
|
ChatIdentity identity = 3;
|
||||||
|
string category_id = 4;
|
||||||
|
int32 position = 5;
|
||||||
|
}
|
||||||
|
|
||||||
|
message CommunityCategory {
|
||||||
|
string category_id = 1;
|
||||||
|
string name = 2;
|
||||||
|
int32 position = 3;
|
||||||
}
|
}
|
||||||
|
|
||||||
message CommunityInvitation {
|
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)
|
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 {
|
type ApplicationMessagesResponse struct {
|
||||||
Messages []*common.Message `json:"messages"`
|
Messages []*common.Message `json:"messages"`
|
||||||
Cursor string `json:"cursor"`
|
Cursor string `json:"cursor"`
|
||||||
|
|
Loading…
Reference in New Issue