feat(communities): integrate community sharding

closes: #12408
This commit is contained in:
Patryk Osmaczko 2023-10-31 21:40:00 +01:00 committed by osmaczko
parent cbb59e0fe5
commit 59048b2069
22 changed files with 305 additions and 71 deletions

View File

@ -333,6 +333,16 @@ proc init*(self: Controller) =
if (args.communityId == self.sectionId): if (args.communityId == self.sectionId):
self.delegate.onAcceptRequestToJoinFailedNoPermission(args.communityId, args.pubKey, args.requestId) self.delegate.onAcceptRequestToJoinFailedNoPermission(args.communityId, args.pubKey, args.requestId)
self.events.on(SIGNAL_COMMUNITY_SHARD_SET) do(e: Args):
let args = CommunityShardSetArgs(e)
if args.communityId == self.sectionId:
self.delegate.setShardingInProgress(false)
self.events.on(SIGNAL_COMMUNITY_SHARD_SET_FAILED) do(e: Args):
let args = CommunityShardSetArgs(e)
if args.communityId == self.sectionId:
self.delegate.setShardingInProgress(false)
self.events.on(SIGNAL_CONTACT_NICKNAME_CHANGED) do(e: Args): self.events.on(SIGNAL_CONTACT_NICKNAME_CHANGED) do(e: Args):
var args = ContactArgs(e) var args = ContactArgs(e)
self.delegate.onContactDetailsUpdated(args.contactId) self.delegate.onContactDetailsUpdated(args.contactId)
@ -685,3 +695,7 @@ proc collectCommunityMetricsMessagesCount*(self: Controller, intervals: string)
proc waitingOnNewCommunityOwnerToConfirmRequestToRejoin*(self: Controller, communityId: string): bool = proc waitingOnNewCommunityOwnerToConfirmRequestToRejoin*(self: Controller, communityId: string): bool =
self.communityService.waitingOnNewCommunityOwnerToConfirmRequestToRejoin(communityId) self.communityService.waitingOnNewCommunityOwnerToConfirmRequestToRejoin(communityId)
proc setCommunityShard*(self: Controller, shardIndex: int) =
self.communityService.asyncSetCommunityShard(self.getMySectionId(), shardIndex)

View File

@ -407,4 +407,11 @@ method getChannelsPermissionsCheckOngoing*(self: AccessInterface): bool {.base.}
raise newException(ValueError, "No implementation available") raise newException(ValueError, "No implementation available")
method onWaitingOnNewCommunityOwnerToConfirmRequestToRejoin*(self: AccessInterface) {.base.} = method onWaitingOnNewCommunityOwnerToConfirmRequestToRejoin*(self: AccessInterface) {.base.} =
raise newException(ValueError, "No implementation available") raise newException(ValueError, "No implementation available")
method setCommunityShard*(self: AccessInterface, shardIndex: int) {.base.} =
raise newException(ValueError, "No implementation available")
method setShardingInProgress*(self: AccessInterface, value: bool) {.base.} =
raise newException(ValueError, "No implementation available")

View File

@ -1349,3 +1349,10 @@ method setChannelsPermissionsCheckOngoing*(self: Module, value: bool) =
method onWaitingOnNewCommunityOwnerToConfirmRequestToRejoin*(self: Module) = method onWaitingOnNewCommunityOwnerToConfirmRequestToRejoin*(self: Module) =
self.view.setWaitingOnNewCommunityOwnerToConfirmRequestToRejoin(true) self.view.setWaitingOnNewCommunityOwnerToConfirmRequestToRejoin(true)
method setCommunityShard*(self: Module, shardIndex: int) =
self.controller.setCommunityShard(shardIndex)
method setShardingInProgress*(self: Module, value: bool) =
self.view.setShardingInProgress(value)

View File

@ -30,6 +30,7 @@ QtObject:
communityMetrics: string # NOTE: later this should be replaced with QAbstractListModel-based model communityMetrics: string # NOTE: later this should be replaced with QAbstractListModel-based model
permissionsCheckOngoing: bool permissionsCheckOngoing: bool
isWaitingOnNewCommunityOwnerToConfirmRequestToRejoin: bool isWaitingOnNewCommunityOwnerToConfirmRequestToRejoin: bool
shardingInProgress: bool
proc delete*(self: View) = proc delete*(self: View) =
self.model.delete self.model.delete
@ -462,4 +463,24 @@ QtObject:
QtProperty[bool] isWaitingOnNewCommunityOwnerToConfirmRequestToRejoin: QtProperty[bool] isWaitingOnNewCommunityOwnerToConfirmRequestToRejoin:
read = getWaitingOnNewCommunityOwnerToConfirmRequestToRejoin read = getWaitingOnNewCommunityOwnerToConfirmRequestToRejoin
notify = isWaitingOnNewCommunityOwnerToConfirmRequestToRejoinChanged notify = isWaitingOnNewCommunityOwnerToConfirmRequestToRejoinChanged
proc getShardingInProgress*(self: View): bool {.slot.} =
return self.shardingInProgress
proc shardingInProgressChanged*(self: View) {.signal.}
QtProperty[bool] shardingInProgress:
read = getShardingInProgress
notify = shardingInProgressChanged
proc setShardingInProgress*(self: View, value: bool) =
if (value == self.shardingInProgress):
return
self.shardingInProgress = value
self.shardingInProgressChanged()
proc setCommunityShard*(self: View, shardIndex: int) {.slot.} =
self.setShardingInProgress(true)
self.delegate.setCommunityShard(shardIndex)

View File

@ -433,6 +433,9 @@ proc createChannelGroupItem[T](self: Module[T], channelGroup: ChannelGroupDto):
) else: @[], ) else: @[],
channelGroup.encrypted, channelGroup.encrypted,
communityTokensItems, communityTokensItems,
channelGroup.pubsubTopic,
channelGroup.pubsubTopicKey,
channelGroup.shard.index,
) )
proc connectForNotificationsOnly[T](self: Module[T]) = proc connectForNotificationsOnly[T](self: Module[T]) =

View File

@ -57,6 +57,9 @@ type
declinedMemberRequestsModel: member_model.Model declinedMemberRequestsModel: member_model.Model
encrypted: bool encrypted: bool
communityTokensModel: community_tokens_model.TokenModel communityTokensModel: community_tokens_model.TokenModel
pubsubTopic: string
pubsubTopicKey: string
shardIndex: int
proc initItem*( proc initItem*(
id: string, id: string,
@ -94,6 +97,9 @@ proc initItem*(
declinedMemberRequests: seq[MemberItem] = @[], declinedMemberRequests: seq[MemberItem] = @[],
encrypted: bool = false, encrypted: bool = false,
communityTokens: seq[TokenItem] = @[], communityTokens: seq[TokenItem] = @[],
pubsubTopic = "",
pubsubTopicKey = "",
shardIndex = -1,
): SectionItem = ): SectionItem =
result.id = id result.id = id
result.sectionType = sectionType result.sectionType = sectionType
@ -136,6 +142,9 @@ proc initItem*(
result.encrypted = encrypted result.encrypted = encrypted
result.communityTokensModel = newTokenModel() result.communityTokensModel = newTokenModel()
result.communityTokensModel.setItems(communityTokens) result.communityTokensModel.setItems(communityTokens)
result.pubsubTopic = pubsubTopic
result.pubsubTopicKey = pubsubTopicKey
result.shardIndex = shardIndex
proc isEmpty*(self: SectionItem): bool = proc isEmpty*(self: SectionItem): bool =
return self.id.len == 0 return self.id.len == 0
@ -366,3 +375,21 @@ proc updateMembershipStatus*(self: SectionItem, memberKey: string, status: Membe
self.bannedMembersModel.updateMembershipStatus(memberKey, status) self.bannedMembersModel.updateMembershipStatus(memberKey, status)
else: else:
self.membersModel.updateMembershipStatus(memberKey, status) self.membersModel.updateMembershipStatus(memberKey, status)
proc pubsubTopic*(self: SectionItem): string {.inline.} =
self.pubsubTopic
proc `pubsubTopic=`*(self: var SectionItem, value: string) {.inline.} =
self.pubsubTopic = value
proc pubsubTopicKey*(self: SectionItem): string {.inline.} =
self.pubsubTopicKey
proc `pubsubTopicKey=`*(self: var SectionItem, value: string) {.inline.} =
self.pubsubTopicKey = value
proc shardIndex*(self: SectionItem): int {.inline.} =
self.shardIndex
proc `shardIndex=`*(self: var SectionItem, value: int) {.inline.} =
self.shardIndex = value

View File

@ -43,6 +43,9 @@ type
PendingMemberRequestsModel PendingMemberRequestsModel
DeclinedMemberRequestsModel DeclinedMemberRequestsModel
AmIBanned AmIBanned
PubsubTopic
PubsubTopicKey
ShardIndex
QtObject: QtObject:
type type
@ -116,6 +119,9 @@ QtObject:
ModelRole.PendingMemberRequestsModel.int:"pendingMemberRequests", ModelRole.PendingMemberRequestsModel.int:"pendingMemberRequests",
ModelRole.DeclinedMemberRequestsModel.int:"declinedMemberRequests", ModelRole.DeclinedMemberRequestsModel.int:"declinedMemberRequests",
ModelRole.AmIBanned.int:"amIBanned", ModelRole.AmIBanned.int:"amIBanned",
ModelRole.PubsubTopic.int:"pubsubTopic",
ModelRole.PubsubTopicKey.int:"pubsubTopicKey",
ModelRole.ShardIndex.int:"shardIndex",
}.toTable }.toTable
method data(self: SectionModel, index: QModelIndex, role: int): QVariant = method data(self: SectionModel, index: QModelIndex, role: int): QVariant =
@ -201,6 +207,12 @@ QtObject:
result = newQVariant(item.declinedMemberRequests) result = newQVariant(item.declinedMemberRequests)
of ModelRole.AmIBanned: of ModelRole.AmIBanned:
result = newQVariant(item.amIBanned) result = newQVariant(item.amIBanned)
of ModelRole.PubsubTopic:
result = newQVariant(item.pubsubTopic)
of ModelRole.PubsubTopicKey:
result = newQVariant(item.pubsubTopicKey)
of ModelRole.ShardIndex:
result = newQVariant(item.shardIndex)
proc itemExists*(self: SectionModel, id: string): bool = proc itemExists*(self: SectionModel, id: string): bool =
for it in self.items: for it in self.items:
@ -415,6 +427,9 @@ QtObject:
"ensOnly": item.ensOnly, "ensOnly": item.ensOnly,
"nbMembers": item.members.getCount(), "nbMembers": item.members.getCount(),
"encrypted": item.encrypted, "encrypted": item.encrypted,
"pubsubTopic": item.pubsubTopic,
"pubsubTopicKey": item.pubsubTopicKey,
"shardIndex": item.shardIndex,
} }
return $jsonObj return $jsonObj

View File

@ -74,4 +74,12 @@ type
ContractTransactionStatus* {.pure.} = enum ContractTransactionStatus* {.pure.} = enum
Failed, Failed,
InProgress, InProgress,
Completed Completed
type Shard* = object
cluster*: int
index*: int
proc initShard*(cluster: int = -1, index: int = -1): Shard =
result.cluster = cluster
result.index = index

View File

@ -113,6 +113,9 @@ type ChannelGroupDto* = object
unviewedMessagesCount*: int unviewedMessagesCount*: int
unviewedMentionsCount*: int unviewedMentionsCount*: int
channelPermissions*: CheckAllChannelsPermissionsResponseDto channelPermissions*: CheckAllChannelsPermissionsResponseDto
pubsubTopic*: string
pubsubTopicKey*: string
shard*: Shard
type ClearedHistoryDto* = object type ClearedHistoryDto* = object
chatId*: string chatId*: string
@ -374,6 +377,16 @@ proc toChannelGroupDto*(jsonObj: JsonNode): ChannelGroupDto =
for channelId, permissionResponse in checkChannelPermissionResponsesObj: for channelId, permissionResponse in checkChannelPermissionResponsesObj:
result.channelPermissions.channels[channelId] = permissionResponse.toCheckChannelPermissionsResponseDto() result.channelPermissions.channels[channelId] = permissionResponse.toCheckChannelPermissionsResponseDto()
discard jsonObj.getProp("pubsubTopic", result.pubsubTopic)
discard jsonObj.getProp("pubsubTopicKey", result.pubsubTopicKey)
var shardObj: JsonNode
if(jsonObj.getProp("shard", shardObj)):
var shard = initShard()
discard shardObj.getProp("cluster", shard.cluster)
discard shardObj.getProp("index", shard.index)
result.shard = shard
# To parse Community chats to ChatDto, we need to add the commuity ID and type # To parse Community chats to ChatDto, we need to add the commuity ID and type
proc toChatDto*(jsonObj: JsonNode, communityId: string): ChatDto = proc toChatDto*(jsonObj: JsonNode, communityId: string): ChatDto =
result = jsonObj.toChatDto() result = jsonObj.toChatDto()

View File

@ -292,3 +292,24 @@ const asyncReevaluateCommunityMembersPermissionsTask: Task = proc(argEncoded: st
"communityId": arg.communityId, "communityId": arg.communityId,
"error": e.msg, "error": e.msg,
}) })
type
AsyncSetCommunityShardArg = ref object of QObjectTaskArg
communityId: string
shardIndex: int
const asyncSetCommunityShardTask: Task = proc(argEncoded: string) {.gcsafe, nimcall.} =
let arg = decode[AsyncSetCommunityShardArg](argEncoded)
try:
let response = status_go.setCommunityShard(arg.communityId, arg.shardIndex)
arg.finish(%* {
"communityId": arg.communityId,
"response": response,
"error": "",
})
except Exception as e:
arg.finish(%* {
"communityId": arg.communityId,
"error": e.msg,
})

View File

@ -170,6 +170,9 @@ type CommunityDto* = object
communityTokensMetadata*: seq[CommunityTokensMetadataDto] communityTokensMetadata*: seq[CommunityTokensMetadataDto]
channelPermissions*: CheckAllChannelsPermissionsResponseDto channelPermissions*: CheckAllChannelsPermissionsResponseDto
activeMembersCount*: int64 activeMembersCount*: int64
pubsubTopic*: string
pubsubTopicKey*: string
shard*: Shard
proc isAvailable*(communityDto: CommunityDto): bool = proc isAvailable*(communityDto: CommunityDto): bool =
return communityDto.name != "" and communityDto.description != "" return communityDto.name != "" and communityDto.description != ""
@ -455,6 +458,16 @@ proc toCommunityDto*(jsonObj: JsonNode): CommunityDto =
for tokenObj in communityTokensMetadataObj: for tokenObj in communityTokensMetadataObj:
result.communityTokensMetadata.add(tokenObj.toCommunityTokensMetadataDto()) result.communityTokensMetadata.add(tokenObj.toCommunityTokensMetadataDto())
discard jsonObj.getProp("pubsubTopic", result.pubsubTopic)
discard jsonObj.getProp("pubsubTopicKey", result.pubsubTopicKey)
var shardObj: JsonNode
if(jsonObj.getProp("shard", shardObj)):
var shard = initShard()
discard shardObj.getProp("cluster", shard.cluster)
discard shardObj.getProp("index", shard.index)
result.shard = shard
proc toMembershipRequestState*(state: CommunityMemberPendingBanOrKick): MembershipRequestState = proc toMembershipRequestState*(state: CommunityMemberPendingBanOrKick): MembershipRequestState =
case state: case state:
of CommunityMemberPendingBanOrKick.Banned: of CommunityMemberPendingBanOrKick.Banned:
@ -550,6 +563,9 @@ proc toChannelGroupDto*(communityDto: CommunityDto): ChannelGroupDto =
historyArchiveSupportEnabled: communityDto.settings.historyArchiveSupportEnabled, historyArchiveSupportEnabled: communityDto.settings.historyArchiveSupportEnabled,
bannedMembersIds: communityDto.getBannedMembersIds(), bannedMembersIds: communityDto.getBannedMembersIds(),
encrypted: communityDto.encrypted, encrypted: communityDto.encrypted,
shard: communityDto.shard,
pubsubTopic: communityDto.pubsubTopic,
pubsubTopicKey: communityDto.pubsubTopicKey,
) )
proc parseCommunitiesSettings*(response: JsonNode): seq[CommunitySettingsDto] = proc parseCommunitiesSettings*(response: JsonNode): seq[CommunitySettingsDto] =

View File

@ -146,6 +146,9 @@ type
memberPubkey*: string memberPubkey*: string
status*: MembershipRequestState status*: MembershipRequestState
CommunityShardSetArgs* = ref object of Args
communityId*: string
# Signals which may be emitted by this service: # Signals which may be emitted by this service:
const SIGNAL_COMMUNITY_DATA_LOADED* = "communityDataLoaded" const SIGNAL_COMMUNITY_DATA_LOADED* = "communityDataLoaded"
const SIGNAL_COMMUNITY_JOINED* = "communityJoined" const SIGNAL_COMMUNITY_JOINED* = "communityJoined"
@ -220,6 +223,9 @@ const SIGNAL_CHECK_PERMISSIONS_TO_JOIN_FAILED* = "checkPermissionsToJoinFailed"
const SIGNAL_COMMUNITY_METRICS_UPDATED* = "communityMetricsUpdated" const SIGNAL_COMMUNITY_METRICS_UPDATED* = "communityMetricsUpdated"
const SIGNAL_COMMUNITY_SHARD_SET* = "communityShardSet"
const SIGNAL_COMMUNITY_SHARD_SET_FAILED* = "communityShardSetFailed"
QtObject: QtObject:
type type
Service* = ref object of QObject Service* = ref object of QObject
@ -2258,3 +2264,32 @@ QtObject:
except Exception as e: except Exception as e:
error "error while reevaluating community members permissions", msg = e.msg error "error while reevaluating community members permissions", msg = e.msg
proc asyncSetCommunityShard*(self: Service, communityId: string, shardIndex: int) =
try:
let arg = AsyncSetCommunityShardArg(
tptr: cast[ByteAddress](asyncSetCommunityShardTask),
vptr: cast[ByteAddress](self.vptr),
slot: "onAsyncSetCommunityShardDone",
communityId: communityId,
shardIndex: shardIndex,
)
self.threadpool.start(arg)
except Exception as e:
error "Error request to join community", msg = e.msg
proc onAsyncSetCommunityShardDone*(self: Service, communityIdAndRpcResponse: string) {.slot.} =
let rpcResponseObj = communityIdAndRpcResponse.parseJson
try:
if (rpcResponseObj{"error"}.kind != JNull and rpcResponseObj{"error"}.getStr != ""):
raise newException(CatchableError, rpcResponseObj{"error"}.getStr)
let rpcResponse = Json.decode($rpcResponseObj["response"], RpcResponse[JsonNode])
let community = rpcResponse.result["communities"][0].toCommunityDto()
self.handleCommunityUpdates(@[community], @[], @[])
self.events.emit(SIGNAL_COMMUNITY_SHARD_SET, CommunityShardSetArgs(communityId: rpcResponseObj["communityId"].getStr))
except Exception as e:
error "Error setting community shard", msg = e.msg
self.events.emit(SIGNAL_COMMUNITY_SHARD_SET_FAILED, CommunityShardSetArgs(communityId: rpcResponseObj["communityId"].getStr))

View File

@ -496,3 +496,21 @@ proc getCommunityMembersForWalletAddresses*(communityId: string, chainId: int):
proc promoteSelfToControlNode*(communityId: string): RpcResponse[JsonNode] {.raises: [Exception].} = proc promoteSelfToControlNode*(communityId: string): RpcResponse[JsonNode] {.raises: [Exception].} =
return callPrivateRPC("promoteSelfToControlNode".prefix, %* [communityId]) return callPrivateRPC("promoteSelfToControlNode".prefix, %* [communityId])
proc setCommunityShard*(communityId: string, index: int): RpcResponse[JsonNode] {.raises: [Exception].} =
let mainStatusShardClusterID = 16
if index != -1:
result = callPrivateRPC("setCommunityShard".prefix, %*[
{
"communityId": communityId,
"shard": {
"cluster": mainStatusShardClusterID,
"index": index
},
}])
else: # unset community shard
result = callPrivateRPC("setCommunityShard".prefix, %*[
{
"communityId": communityId,
}])

View File

@ -17,6 +17,7 @@ SplitView {
} }
EditSettingsPanel { EditSettingsPanel {
id: panel
SplitView.fillWidth: true SplitView.fillWidth: true
SplitView.fillHeight: true SplitView.fillHeight: true
name: communityEditor.name name: communityEditor.name
@ -24,10 +25,13 @@ SplitView {
logoImageData: communityEditor.image logoImageData: communityEditor.image
description: communityEditor.description description: communityEditor.description
bannerImageData: communityEditor.banner bannerImageData: communityEditor.banner
communityId: "0xdeadbeef" shardingEnabled: communityEditor.shardingEnabled
communityShardingEnabled: communityEditor.shardingEnabled shardIndex: communityEditor.shardIndex
communityShardIndex: communityEditor.shardIndex onShardIndexEdited: {
onCommunityShardIndexChanged: communityEditor.shardIndex = communityShardIndex panel.shardingInProgress = true
communityEditor.shardIndex = shardIndex
panel.shardingInProgress = false
}
} }
ScrollView { ScrollView {

View File

@ -35,9 +35,22 @@ SplitView {
closePolicy: Popup.NoAutoClose closePolicy: Popup.NoAutoClose
communityName: "Foobar" communityName: "Foobar"
publicKey: "0xdeadbeef" shardIndex: -1
shardingInProgress: ctrlShardingInProgress.checked pubsubTopic: '{"pubsubTopic":"/waku/2/rs/16/%1", "publicKey":"0xdeadbeef"}'.arg(dialog.shardIndex)
onEnableSharding: logs.logEvent("enableSharding", ["shardIndex"], arguments)
onShardIndexChanged: {
shardingInProgress = true
logs.logEvent("enableSharding", ["shardIndex"], arguments)
shardSetterDelayer.start()
}
}
Timer {
id: shardSetterDelayer
interval: 1000
onTriggered: {
dialog.shardingInProgress = false
}
} }
} }
@ -46,13 +59,6 @@ SplitView {
SplitView.preferredHeight: 200 SplitView.preferredHeight: 200
logsView.logText: logs.logText logsView.logText: logs.logText
ColumnLayout {
Switch {
id: ctrlShardingInProgress
text: "Sharding in progress"
}
}
} }
} }

View File

@ -37,7 +37,7 @@ SplitView {
communityName: "Foobar" communityName: "Foobar"
shardIndex: 33 shardIndex: 33
pubSubTopic: '{"pubsubTopic":"/waku/2/rs/16/%1", "publicKey":"%2"}'.arg(shardIndex).arg("0xdeadbeef") pubsubTopic: '{"pubsubTopic":"/waku/2/rs/16/%1", "publicKey":"%2"}'.arg(shardIndex).arg("0xdeadbeef")
onDisableShardingRequested: logs.logEvent("ManageShardingPopup::disableShardingRequested") onDisableShardingRequested: logs.logEvent("ManageShardingPopup::disableShardingRequested")
onEditShardIndexRequested: logs.logEvent("ManageShardingPopup::editShardIndexRequested") onEditShardIndexRequested: logs.logEvent("ManageShardingPopup::editShardIndexRequested")

View File

@ -22,9 +22,9 @@ SplitView {
isOwner: communityEditor.amISectionAdmin isOwner: communityEditor.amISectionAdmin
communitySettingsDisabled: !editable communitySettingsDisabled: !editable
communityShardingEnabled: communityEditor.shardingEnabled shardingEnabled: communityEditor.shardingEnabled
communityShardIndex: communityEditor.shardIndex shardIndex: communityEditor.shardIndex
isPendingOwnershipRequest: pendingOwnershipSwitch.checked isPendingOwnershipRequest: pendingOwnershipSwitch.checked
finaliseOwnershipTransferPopup: undefined finaliseOwnershipTransferPopup: undefined
} }

View File

@ -23,9 +23,12 @@ StatusScrollView {
property alias tags: baseLayout.tags property alias tags: baseLayout.tags
property alias selectedTags: baseLayout.selectedTags property alias selectedTags: baseLayout.selectedTags
property alias options: baseLayout.options property alias options: baseLayout.options
property string communityId
property bool communityShardingEnabled property bool shardingEnabled
property int communityShardIndex: -1 property int shardIndex
property bool shardingInProgress
property string pubsubTopic
property string pubsubTopicKey
property alias logoImageData: baseLayout.logoImageData property alias logoImageData: baseLayout.logoImageData
property alias logoImagePath: baseLayout.logoImagePath property alias logoImagePath: baseLayout.logoImagePath
@ -42,6 +45,8 @@ StatusScrollView {
(introMessageTextInput.input.dirty && !introMessageTextInput.valid) || (introMessageTextInput.input.dirty && !introMessageTextInput.valid) ||
(outroMessageTextInput.input.dirty && !outroMessageTextInput.valid)) (outroMessageTextInput.input.dirty && !outroMessageTextInput.valid))
signal shardIndexEdited(int shardIndex)
padding: 0 padding: 0
ColumnLayout { ColumnLayout {
@ -75,14 +80,14 @@ StatusScrollView {
Layout.fillWidth: true Layout.fillWidth: true
Layout.topMargin: -baseLayout.spacing Layout.topMargin: -baseLayout.spacing
Layout.bottomMargin: 2 Layout.bottomMargin: 2
visible: root.communityShardingEnabled visible: root.shardingEnabled
} }
RowLayout { RowLayout {
spacing: Style.current.halfPadding spacing: Style.current.halfPadding
visible: root.communityShardingEnabled visible: root.shardingEnabled
readonly property bool shardingActive: root.communityShardIndex !== -1 readonly property bool shardingActive: root.shardIndex !== -1
StatusBaseText { StatusBaseText {
Layout.fillWidth: true Layout.fillWidth: true
@ -92,11 +97,12 @@ StatusScrollView {
StatusBaseText { StatusBaseText {
color: Theme.palette.baseColor1 color: Theme.palette.baseColor1
visible: parent.shardingActive visible: parent.shardingActive
text: qsTr("Active: on shard #%1").arg(root.communityShardIndex) text: qsTr("Active: on shard #%1").arg(root.shardIndex)
} }
StatusButton { StatusButton {
size: StatusBaseButton.Size.Small size: StatusBaseButton.Size.Small
text: parent.shardingActive ? qsTr("Manage") : qsTr("Make %1 a sharded community").arg(root.name) text: parent.shardingActive ? qsTr("Manage") : qsTr("Make %1 a sharded community").arg(root.name)
loading: root.shardingInProgress
onClicked: parent.shardingActive ? Global.openPopup(manageShardingPopupCmp) : Global.openPopup(enableShardingPopupCmp) onClicked: parent.shardingActive ? Global.openPopup(manageShardingPopupCmp) : Global.openPopup(enableShardingPopupCmp)
} }
} }
@ -111,13 +117,17 @@ StatusScrollView {
Component { Component {
id: enableShardingPopupCmp id: enableShardingPopupCmp
EnableShardingPopup { EnableShardingPopup {
id: enableShardingPopup
destroyOnClose: true destroyOnClose: true
communityName: root.name communityName: root.name
publicKey: root.communityId shardIndex: root.shardIndex
shardingInProgress: false // TODO community sharding backend: set to "true" when generating the pubSub topic, or migrating pubsubTopic: '{"pubsubTopic":"%1", "publicKey":"%2"}'.arg(root.pubsubTopic).arg(root.pubsubTopicKey)
onEnableSharding: { shardingInProgress: root.shardingInProgress
console.warn("TODO: enable community sharding for shardIndex:", shardIndex) // TODO community sharding backend
root.communityShardIndex = shardIndex onShardIndexChanged: root.shardIndexEdited(shardIndex)
onShardingInProgressChanged: if (!shardingInProgress) {
// bring back the binding
enableShardingPopup.shardIndex = Qt.binding(() => root.shardIndex)
} }
} }
} }
@ -125,16 +135,14 @@ StatusScrollView {
Component { Component {
id: manageShardingPopupCmp id: manageShardingPopupCmp
ManageShardingPopup { ManageShardingPopup {
id: manageShardingPopup
destroyOnClose: true destroyOnClose: true
communityName: root.name communityName: root.name
shardIndex: root.communityShardIndex shardIndex: root.shardIndex
pubSubTopic: '{"pubsubTopic":"/waku/2/rs/16/%1", "publicKey":"%2"}'.arg(shardIndex).arg(root.communityId) // TODO community sharding backend pubsubTopic: '{"pubsubTopic":"%1", "publicKey":"%2"}'.arg(root.pubsubTopic).arg(root.pubsubTopicKey)
onDisableShardingRequested: {
root.communityShardIndex = -1 // TODO community sharding backend onDisableShardingRequested: root.shardIndexEdited(-1)
} onEditShardIndexRequested: Global.openPopup(enableShardingPopupCmp)
onEditShardIndexRequested: {
Global.openPopup(enableShardingPopupCmp, {initialShardIndex: root.communityShardIndex})
}
} }
} }
} }

View File

@ -50,9 +50,12 @@ StackLayout {
property string overviewChartData: "" property string overviewChartData: ""
property bool communityShardingEnabled property bool shardingEnabled
property int communityShardIndex: -1 property int shardIndex: -1
property bool shardingInProgress
property string pubsubTopic
property string pubsubTopicKey
// Community transfer ownership related props: // Community transfer ownership related props:
required property var finaliseOwnershipTransferPopup required property var finaliseOwnershipTransferPopup
required property bool isPendingOwnershipRequest required property bool isPendingOwnershipRequest
@ -74,6 +77,8 @@ StackLayout {
signal importControlNodeClicked signal importControlNodeClicked
signal mintOwnerTokenClicked signal mintOwnerTokenClicked
signal shardIndexEdited(int shardIndex)
clip: true clip: true
Component { Component {
@ -289,9 +294,11 @@ StackLayout {
pinMessagesEnabled: root.pinMessagesEnabled pinMessagesEnabled: root.pinMessagesEnabled
} }
communityId: root.communityId shardingEnabled: root.shardingEnabled
communityShardingEnabled: root.communityShardingEnabled shardIndex: root.shardIndex
communityShardIndex: root.communityShardIndex shardingInProgress: root.shardingInProgress
pubsubTopic: root.pubsubTopic
pubsubTopicKey: root.pubsubTopicKey
bottomReservedSpace: bottomReservedSpace:
Qt.size(settingsDirtyToastMessage.implicitWidth, Qt.size(settingsDirtyToastMessage.implicitWidth,
@ -305,6 +312,8 @@ StackLayout {
property: "bottomMargin" property: "bottomMargin"
value: 24 value: 24
} }
onShardIndexEdited: root.shardIndexEdited(shardIndex)
} }
} }

View File

@ -16,22 +16,21 @@ StatusStackModal {
id: root id: root
required property string communityName required property string communityName
required property string publicKey required property int shardIndex
property int initialShardIndex: -1 required property string pubsubTopic
property bool shardingInProgress property bool shardingInProgress
signal enableSharding(int shardIndex)
stackTitle: qsTr("Enable community sharding for %1").arg(communityName) stackTitle: qsTr("Enable community sharding for %1").arg(communityName)
width: 640 width: 640
readonly property var cancelButton: StatusFlatButton { readonly property var cancelButton: StatusFlatButton {
visible: typeof(currentItem.canGoNext) == "undefined" || currentItem.cancellable
text: qsTr("Cancel") text: qsTr("Cancel")
onClicked: root.close() onClicked: root.close()
} }
nextButton: StatusButton { nextButton: StatusButton {
text: qsTr("Next") text: qsTr("Enable community sharding")
enabled: typeof(currentItem.canGoNext) == "undefined" || currentItem.canGoNext enabled: typeof(currentItem.canGoNext) == "undefined" || currentItem.canGoNext
loading: root.shardingInProgress loading: root.shardingInProgress
onClicked: { onClicked: {
@ -39,38 +38,34 @@ StatusStackModal {
if (typeof(nextAction) == "function") { if (typeof(nextAction) == "function") {
return nextAction() return nextAction()
} }
root.currentIndex++
} }
} }
finishButton: StatusButton { finishButton: StatusButton {
text: qsTr("Enable community sharding") text: qsTr("Close")
enabled: typeof(currentItem.canGoNext) == "undefined" || currentItem.canGoNext enabled: typeof(currentItem.canGoNext) == "undefined" || currentItem.canGoNext
onClicked: { onClicked: {
root.enableSharding(d.shardIndex) root.currentIndex = 0
root.close() root.close()
} }
} }
rightButtons: [cancelButton, nextButton, finishButton] rightButtons: [cancelButton, nextButton, finishButton]
QtObject {
id: d
readonly property string pubSubTopic: '{"pubsubTopic":"/waku/2/rs/16/%1", "publicKey":"%2"}'.arg(shardIndex).arg(root.publicKey) // FIXME backend
property int shardIndex: root.initialShardIndex
}
onAboutToShow: shardIndexEdit.focus = true onAboutToShow: shardIndexEdit.focus = true
onShardingInProgressChanged: if (!root.shardingInProgress && root.currentIndex == 0) {
root.currentIndex++
}
stackItems: [ stackItems: [
ColumnLayout { ColumnLayout {
id: firstPage id: firstPage
spacing: Style.current.halfPadding spacing: Style.current.halfPadding
readonly property bool canGoNext: shardIndexEdit.valid readonly property bool cancellable: true
readonly property bool canGoNext: shardIndexEdit.valid && root.shardIndex != parseInt(shardIndexEdit.text)
readonly property var nextAction: function () { readonly property var nextAction: function () {
d.shardIndex = parseInt(shardIndexEdit.text) root.shardIndex = parseInt(shardIndexEdit.text)
root.currentIndex++
} }
StatusInput { StatusInput {
@ -78,7 +73,7 @@ StatusStackModal {
Layout.fillWidth: true Layout.fillWidth: true
label: qsTr("Enter shard number") label: qsTr("Enter shard number")
placeholderText: qsTr("Enter a number between 0 and 1023") placeholderText: qsTr("Enter a number between 0 and 1023")
text: d.shardIndex !== -1 ? d.shardIndex : "" text: root.shardIndex !== -1 ? root.shardIndex : ""
validators: [ validators: [
StatusIntValidator { StatusIntValidator {
bottom: 0 bottom: 0
@ -97,6 +92,7 @@ StatusStackModal {
} }
}, },
ColumnLayout { ColumnLayout {
readonly property bool cancellable: false
readonly property bool canGoNext: agreement.checked readonly property bool canGoNext: agreement.checked
StatusBaseText { StatusBaseText {
@ -107,7 +103,7 @@ StatusStackModal {
Layout.fillWidth: true Layout.fillWidth: true
Layout.preferredHeight: 138 Layout.preferredHeight: 138
readOnly: true readOnly: true
text: d.pubSubTopic text: root.pubsubTopic
rightPadding: 48 rightPadding: 48
wrapMode: TextEdit.Wrap wrapMode: TextEdit.Wrap

View File

@ -19,7 +19,7 @@ StatusDialog {
required property string communityName required property string communityName
required property int shardIndex required property int shardIndex
required property string pubSubTopic required property string pubsubTopic
signal disableShardingRequested() signal disableShardingRequested()
signal editShardIndexRequested() signal editShardIndexRequested()
@ -66,7 +66,7 @@ StatusDialog {
Layout.fillWidth: true Layout.fillWidth: true
Layout.preferredHeight: 138 Layout.preferredHeight: 138
readOnly: true readOnly: true
text: root.pubSubTopic text: root.pubsubTopic
rightPadding: 48 rightPadding: 48
wrapMode: TextEdit.Wrap wrapMode: TextEdit.Wrap

View File

@ -184,8 +184,11 @@ StatusSectionLayout {
isControlNode: root.isControlNode isControlNode: root.isControlNode
communitySettingsDisabled: root.communitySettingsDisabled communitySettingsDisabled: root.communitySettingsDisabled
overviewChartData: rootStore.overviewChartData overviewChartData: rootStore.overviewChartData
communityShardingEnabled: localAppSettings.wakuV2ShardedCommunitiesEnabled ?? false shardingEnabled: localAppSettings.wakuV2ShardedCommunitiesEnabled ?? false
communityShardIndex: root.community.shardIndex ?? -1 // TODO community sharding backend shardIndex: root.community.shardIndex
shardingInProgress: root.chatCommunitySectionModule.shardingInProgress
pubsubTopic: root.community.pubsubTopic
pubsubTopicKey: root.community.pubsubTopicKey
sendModalPopup: root.sendModalPopup sendModalPopup: root.sendModalPopup
tokensModel: root.community.communityTokens tokensModel: root.community.communityTokens
@ -245,6 +248,9 @@ StatusSectionLayout {
mintPanel.openNewTokenForm(false/*Collectible owner token*/) mintPanel.openNewTokenForm(false/*Collectible owner token*/)
} }
onShardIndexEdited: if (root.community.shardIndex != shardIndex) {
root.chatCommunitySectionModule.setCommunityShard(shardIndex)
}
} }
MembersSettingsPanel { MembersSettingsPanel {
@ -507,7 +513,7 @@ StatusSectionLayout {
onAirdropClicked: communityTokensStore.airdrop( onAirdropClicked: communityTokensStore.airdrop(
root.community.id, airdropTokens, addresses, root.community.id, airdropTokens, addresses,
feeAccountAddress) feeAccountAddress)
onNavigateToMintTokenSettings: { onNavigateToMintTokenSettings: {
root.goTo(Constants.CommunitySettingsSections.MintTokens) root.goTo(Constants.CommunitySettingsSections.MintTokens)
mintPanel.openNewTokenForm(isAssetType) mintPanel.openNewTokenForm(isAssetType)