diff --git a/src/app/modules/main/chat_section/chat_content/io_interface.nim b/src/app/modules/main/chat_section/chat_content/io_interface.nim
index a5bb85a65c..bf3044a8fe 100644
--- a/src/app/modules/main/chat_section/chat_content/io_interface.nim
+++ b/src/app/modules/main/chat_section/chat_content/io_interface.nim
@@ -127,3 +127,9 @@ method onMadeActive*(self: AccessInterface) {.base.} =
method onMadeInactive*(self: AccessInterface) {.base.} =
raise newException(ValueError, "No implementation available")
+
+method onUpdateViewOnlyPermissionsSatisfied*(self: AccessInterface, value: bool) {.base.} =
+ raise newException(ValueError, "No implementation available")
+
+method onUpdateViewAndPostPermissionsSatisfied*(self: AccessInterface, value: bool) {.base.} =
+ raise newException(ValueError, "No implementation available")
diff --git a/src/app/modules/main/chat_section/chat_content/module.nim b/src/app/modules/main/chat_section/chat_content/module.nim
index 42c13a8e84..cab665eb75 100644
--- a/src/app/modules/main/chat_section/chat_content/module.nim
+++ b/src/app/modules/main/chat_section/chat_content/module.nim
@@ -400,3 +400,9 @@ method amIChatAdmin*(self: Module): bool =
else:
let communityDto = self.controller.getCommunityDetails()
return communityDto.memberRole == MemberRole.Owner or communityDto.memberRole == MemberRole.Admin
+
+method onUpdateViewOnlyPermissionsSatisfied*(self: Module, value: bool) =
+ self.view.setViewOnlyPermissionsSatisfied(value)
+
+method onUpdateViewAndPostPermissionsSatisfied*(self: Module, value: bool) =
+ self.view.setViewAndPostPermissionsSatisfied(value)
diff --git a/src/app/modules/main/chat_section/chat_content/view.nim b/src/app/modules/main/chat_section/chat_content/view.nim
index 755141c072..3c5b303fed 100644
--- a/src/app/modules/main/chat_section/chat_content/view.nim
+++ b/src/app/modules/main/chat_section/chat_content/view.nim
@@ -13,6 +13,8 @@ QtObject:
pinnedMessagesModelVariant: QVariant
chatDetails: ChatDetails
chatDetailsVariant: QVariant
+ viewOnlyPermissionsSatisfied: bool
+ viewAndPostPermissionsSatisfied: bool
proc chatDetailsChanged*(self:View) {.signal.}
@@ -31,6 +33,8 @@ QtObject:
result.pinnedMessagesModelVariant = newQVariant(result.pinnedMessagesModel)
result.chatDetails = newChatDetails()
result.chatDetailsVariant = newQVariant(result.chatDetails)
+ result.viewOnlyPermissionsSatisfied = false
+ result.viewAndPostPermissionsSatisfied = false
proc load*(self: View, id: string, `type`: int, belongsToCommunity, isUsersListAvailable: bool,
name, icon: string, color, description, emoji: string, hasUnreadMessages: bool,
@@ -150,3 +154,28 @@ QtObject:
proc updateChatBlocked*(self: View, blocked: bool) =
self.chatDetails.setBlocked(blocked)
+
+ proc viewOnlyPermissionsSatisfiedChanged(self: View) {.signal.}
+
+ proc setViewOnlyPermissionsSatisfied*(self: View, value: bool) =
+ self.viewOnlyPermissionsSatisfied = value
+ self.viewOnlyPermissionsSatisfiedChanged()
+
+ proc getViewOnlyPermissionsSatisfied*(self: View): bool {.slot.} =
+ return self.viewOnlyPermissionsSatisfied
+ QtProperty[bool] viewOnlyPermissionsSatisfied:
+ read = getViewOnlyPermissionsSatisfied
+ notify = viewOnlyPermissionsSatisfiedChanged
+
+ proc viewAndPostPermissionsSatisfiedChanged(self: View) {.signal.}
+
+ proc setViewAndPostPermissionsSatisfied*(self: View, value: bool) =
+ self.viewAndPostPermissionsSatisfied = value
+ self.viewAndPostPermissionsSatisfiedChanged()
+
+ proc getViewAndPostPermissionsSatisfied*(self: View): bool {.slot.} =
+ return self.viewAndPostPermissionsSatisfied
+ QtProperty[bool] viewAndPostPermissionsSatisfied:
+ read = getViewAndPostPermissionsSatisfied
+ notify = viewAndPostPermissionsSatisfiedChanged
+
diff --git a/src/app/modules/main/chat_section/controller.nim b/src/app/modules/main/chat_section/controller.nim
index 77f7dce26d..3e0c496be1 100644
--- a/src/app/modules/main/chat_section/controller.nim
+++ b/src/app/modules/main/chat_section/controller.nim
@@ -107,6 +107,21 @@ proc authenticateToRequestToJoinCommunity*(self: Controller, communityId: string
self.tmpRequestToJoinEnsName = ensName
self.authenticate()
+proc getMySectionId*(self: Controller): string =
+ return self.sectionId
+
+proc asyncCheckPermissionsToJoin*(self: Controller) =
+ self.communityService.asyncCheckPermissionsToJoin(self.getMySectionId())
+
+proc asyncCheckAllChannelsPermissions*(self: Controller) =
+ self.communityService.asyncCheckAllChannelsPermissions(self.getMySectionId())
+
+proc asyncCheckChannelPermissions*(self: Controller, communityId: string, chatId: string) =
+ self.communityService.asyncCheckChannelPermissions(communityId, chatId)
+
+proc asyncCheckPermissions*(self: Controller) =
+ self.asyncCheckPermissionsToJoin()
+ self.asyncCheckAllChannelsPermissions()
proc init*(self: Controller) =
self.events.on(SIGNAL_SENDING_SUCCESS) do(e:Args):
@@ -257,7 +272,7 @@ proc init*(self: Controller) =
let args = CommunityTokenPermissionArgs(e)
if (args.communityId == self.sectionId):
self.delegate.onCommunityTokenPermissionCreated(args.communityId, args.tokenPermission)
- self.communityService.asyncCheckPermissionsToJoin(self.sectionId)
+ self.asyncCheckPermissions()
self.events.on(SIGNAL_COMMUNITY_TOKEN_PERMISSION_CREATION_FAILED) do(e: Args):
let args = CommunityTokenPermissionArgs(e)
@@ -268,7 +283,7 @@ proc init*(self: Controller) =
let args = CommunityTokenPermissionArgs(e)
if (args.communityId == self.sectionId):
self.delegate.onCommunityTokenPermissionUpdated(args.communityId, args.tokenPermission)
- self.communityService.asyncCheckPermissionsToJoin(self.sectionId)
+ self.asyncCheckPermissions()
self.events.on(SIGNAL_COMMUNITY_TOKEN_PERMISSION_UPDATE_FAILED) do(e: Args):
@@ -280,7 +295,7 @@ proc init*(self: Controller) =
let args = CommunityTokenPermissionRemovedArgs(e)
if (args.communityId == self.sectionId):
self.delegate.onCommunityTokenPermissionDeleted(args.communityId, args.permissionId)
- self.communityService.asyncCheckPermissionsToJoin(self.sectionId)
+ self.asyncCheckPermissions()
self.events.on(SIGNAL_COMMUNITY_TOKEN_PERMISSION_DELETION_FAILED) do(e: Args):
let args = CommunityTokenPermissionArgs(e)
@@ -292,6 +307,16 @@ proc init*(self: Controller) =
if (args.communityId == self.sectionId):
self.delegate.onCommunityCheckPermissionsToJoinResponse(args.checkPermissionsToJoinResponse)
+ self.events.on(SIGNAL_CHECK_CHANNEL_PERMISSIONS_RESPONSE) do(e: Args):
+ let args = CheckChannelPermissionsResponseArgs(e)
+ if args.communityId == self.sectionId:
+ self.delegate.onCommunityCheckChannelPermissionsResponse(args.chatId, args.checkChannelPermissionsResponse)
+
+ self.events.on(SIGNAL_CHECK_ALL_CHANNELS_PERMISSIONS_RESPONSE) do(e: Args):
+ let args = CheckAllChannelsPermissionsResponseArgs(e)
+ if args.communityId == self.sectionId:
+ self.delegate.onCommunityCheckAllChannelsPermissionsResponse(args.checkAllChannelsPermissionsResponse)
+
self.events.on(SIGNAL_COMMUNITY_TOKEN_METADATA_ADDED) do(e: Args):
let args = CommunityTokenMetadataArgs(e)
if (args.communityId == self.sectionId):
@@ -299,9 +324,11 @@ proc init*(self: Controller) =
self.events.on(SIGNAL_OWNED_COLLECTIBLES_UPDATE_FINISHED) do(e: Args):
self.delegate.onOwnedCollectiblesUpdated()
+ self.asyncCheckPermissions()
self.events.on(SIGNAL_WALLET_ACCOUNT_TOKENS_REBUILT) do(e: Args):
self.delegate.onWalletAccountTokensRebuilt()
+ self.asyncCheckPermissions()
self.events.on(SIGNAL_COMMUNITY_KICKED) do (e: Args):
let args = CommunityArgs(e)
@@ -366,9 +393,6 @@ proc init*(self: Controller) =
self.events.on(SIGNAL_MAILSERVER_HISTORY_REQUEST_COMPLETED) do(e:Args):
self.delegate.setLoadingHistoryMessagesInProgress(false)
-proc getMySectionId*(self: Controller): string =
- return self.sectionId
-
proc isCommunity*(self: Controller): bool =
return self.isCommunitySection
@@ -633,6 +657,12 @@ proc getColorHash*(self: Controller, pubkey: string): ColorHashDto =
proc getColorId*(self: Controller, pubkey: string): int =
procs_from_visual_identity_service.colorIdOf(pubkey)
+proc checkChatHasPermissions*(self: Controller, communityId: string, chatId: string): bool =
+ return self.communityService.checkChatHasPermissions(communityId, chatId)
+
+proc checkChatIsLocked*(self: Controller, communityId: string, chatId: string): bool =
+ return self.communityService.checkChatIsLocked(communityId, chatId)
+
proc createOrEditCommunityTokenPermission*(self: Controller, communityId: string, tokenPermission: CommunityTokenPermissionDto) =
self.communityService.createOrEditCommunityTokenPermission(communityId, tokenPermission)
@@ -670,5 +700,3 @@ proc getContractAddressesForToken*(self: Controller, symbol: string): Table[int,
proc getCommunityTokenList*(self: Controller): seq[CommunityTokenDto] =
return self.communityTokensService.getCommunityTokens(self.getMySectionId())
-proc asyncCheckPermissionsToJoin*(self: Controller) =
- self.communityService.asyncCheckPermissionsToJoin(self.getMySectionId())
diff --git a/src/app/modules/main/chat_section/io_interface.nim b/src/app/modules/main/chat_section/io_interface.nim
index a8375ad502..13bf16ab69 100644
--- a/src/app/modules/main/chat_section/io_interface.nim
+++ b/src/app/modules/main/chat_section/io_interface.nim
@@ -343,7 +343,7 @@ method switchToChannel*(self: AccessInterface, channelName: string) {.base.} =
method joinSpectatedCommunity*(self: AccessInterface) {.base.} =
raise newException(ValueError, "No implementation available")
-method createOrEditCommunityTokenPermission*(self: AccessInterface, communityId: string, permissionId: string, permissionType: int, tokenCriteriaJson: string, isPrivate: bool) {.base.} =
+method createOrEditCommunityTokenPermission*(self: AccessInterface, communityId: string, permissionId: string, permissionType: int, tokenCriteriaJson: string, channelIDs: seq[string], isPrivate: bool) {.base.} =
raise newException(ValueError, "No implementation available")
method deleteCommunityTokenPermission*(self: AccessInterface, communityId: string, permissionId: string) {.base.} =
@@ -398,4 +398,11 @@ method onOwnedcollectiblesUpdated*(self: AccessInterface) {.base.} =
raise newException(ValueError, "No implementation available")
method onCommunityCheckPermissionsToJoinResponse*(self: AccessInterface, checkPermissionsToJoinResponse: CheckPermissionsToJoinResponseDto) {.base.} =
+
+ raise newException(ValueError, "No implementation available")
+
+method onCommunityCheckChannelPermissionsResponse*(self: AccessInterface, chatId: string, checkChannelPermissionsResponse: CheckChannelPermissionsResponseDto) {.base.} =
+ raise newException(ValueError, "No implementation available")
+
+method onCommunityCheckAllChannelsPermissionsResponse*(self: AccessInterface, checkAllChannelsPermissionsResponse: CheckAllChannelsPermissionsResponseDto) {.base.} =
raise newException(ValueError, "No implementation available")
diff --git a/src/app/modules/main/chat_section/item.nim b/src/app/modules/main/chat_section/item.nim
index efa962d20e..97ce2e0f72 100644
--- a/src/app/modules/main/chat_section/item.nim
+++ b/src/app/modules/main/chat_section/item.nim
@@ -33,6 +33,8 @@ type
trustStatus: TrustStatus
onlineStatus: OnlineStatus
loaderActive: bool
+ locked: bool
+ requiresPermissions: bool
proc initItem*(
id,
@@ -58,7 +60,9 @@ proc initItem*(
categoryOpened: bool = true,
trustStatus: TrustStatus = TrustStatus.Unknown,
onlineStatus = OnlineStatus.Inactive,
- loaderActive = false
+ loaderActive = false,
+ locked = false,
+ requiresPermissions = false
): Item =
result = Item()
result.id = id
@@ -86,6 +90,8 @@ proc initItem*(
result.trustStatus = trustStatus
result.onlineStatus = onlineStatus
result.loaderActive = loaderActive
+ result.locked = locked
+ result.requiresPermissions = requiresPermissions
proc `$`*(self: Item): string =
result = fmt"""chat_section/Item(
@@ -112,6 +118,8 @@ proc `$`*(self: Item): string =
trustStatus: {$self.trustStatus},
onlineStatus: {$self.onlineStatus},
loaderActive: {$self.loaderActive},
+ locked: {$self.locked},
+ requiresPermissions: {$self.requiresPermissions},
]"""
proc toJsonNode*(self: Item): JsonNode =
@@ -138,7 +146,9 @@ proc toJsonNode*(self: Item): JsonNode =
"categoryOpened": self.categoryOpened,
"trustStatus": self.trustStatus,
"onlineStatus": self.onlineStatus,
- "loaderActive": self.loaderActive
+ "loaderActive": self.loaderActive,
+ "locked": self.locked,
+ "requiresPermissions": self.requiresPermissions
}
proc delete*(self: Item) =
@@ -278,3 +288,15 @@ proc `loaderActive=`*(self: var Item, value: bool) =
proc isCategory*(self: Item): bool =
self.`type` == CATEGORY_TYPE
+
+proc isLocked*(self: Item): bool =
+ self.locked
+
+proc `locked=`*(self: Item, value: bool) =
+ self.locked = value
+
+proc requiresPermissions*(self: Item): bool =
+ self.requiresPermissions
+
+proc `requiresPermissions=`*(self: Item, value: bool) =
+ self.requiresPermissions = value
diff --git a/src/app/modules/main/chat_section/model.nim b/src/app/modules/main/chat_section/model.nim
index 0088c26a81..580a5dc892 100644
--- a/src/app/modules/main/chat_section/model.nim
+++ b/src/app/modules/main/chat_section/model.nim
@@ -31,6 +31,8 @@ type
OnlineStatus
IsCategory
LoaderActive
+ Locked
+ RequiresPermissions
QtObject:
type
@@ -99,6 +101,8 @@ QtObject:
ModelRole.OnlineStatus.int:"onlineStatus",
ModelRole.IsCategory.int:"isCategory",
ModelRole.LoaderActive.int:"loaderActive",
+ ModelRole.Locked.int:"locked",
+ ModelRole.RequiresPermissions.int:"requiresPermissions",
}.toTable
method data(self: Model, index: QModelIndex, role: int): QVariant =
@@ -162,6 +166,10 @@ QtObject:
result = newQVariant(item.isCategory)
of ModelRole.LoaderActive:
result = newQVariant(item.loaderActive)
+ of ModelRole.Locked:
+ result = newQVariant(item.isLocked)
+ of ModelRole.RequiresPermissions:
+ result = newQVariant(item.requiresPermissions)
proc getItemIdxById(items: seq[Item], id: string): int =
var idx = 0
@@ -274,6 +282,22 @@ QtObject:
else:
self.dataChanged(index, index, @[ModelRole.Active.int])
+ proc setItemLocked*(self: Model, id: string, locked: bool) =
+ let index = self.getItemIdxById(id)
+ if index == -1:
+ return
+ self.items[index].locked = locked
+ let modelIndex = self.createIndex(index, 0, nil)
+ self.dataChanged(modelIndex, modelIndex, @[ModelRole.Locked.int])
+
+ proc setItemPermissionsRequired*(self: Model, id: string, value: bool) =
+ let index = self.getItemIdxById(id)
+ if index == -1:
+ return
+ self.items[index].requiresPermissions = value
+ let modelIndex = self.createIndex(index, 0, nil)
+ self.dataChanged(modelIndex, modelIndex, @[ModelRole.RequiresPermissions.int])
+
proc changeMutedOnItemById*(self: Model, id: string, muted: bool) =
let index = self.getItemIdxById(id)
if index == -1:
@@ -545,4 +569,4 @@ QtObject:
self.items[index].loaderActive = false
self.items[index].active = false
let modelIndex = self.createIndex(index, 0, nil)
- self.dataChanged(modelIndex, modelIndex, @[ModelRole.Active.int, ModelRole.LoaderActive.int])
\ No newline at end of file
+ self.dataChanged(modelIndex, modelIndex, @[ModelRole.Active.int, ModelRole.LoaderActive.int])
diff --git a/src/app/modules/main/chat_section/module.nim b/src/app/modules/main/chat_section/module.nim
index 748aa9f974..270c13ab5d 100644
--- a/src/app/modules/main/chat_section/module.nim
+++ b/src/app/modules/main/chat_section/module.nim
@@ -13,6 +13,8 @@ import ../../shared_models/token_criteria_item
import ../../shared_models/token_criteria_model
import ../../shared_models/token_list_item
import ../../shared_models/token_list_model
+import ../../shared_models/token_permission_chat_list_item
+import ../../shared_models/token_permission_chat_list_model
import chat_content/module as chat_content_module
import chat_content/users/module as users_module
@@ -69,6 +71,8 @@ proc buildChatSectionUI(self: Module,
gifService: gif_service.Service,
mailserversService: mailservers_service.Service)
+proc reevaluateRequiresTokenPermissionToJoin(self: Module)
+
proc addOrUpdateChat(self: Module,
chat: ChatDto,
channelGroup: ChannelGroupDto,
@@ -291,9 +295,17 @@ proc rebuildCommunityTokenPermissionsModel(self: Module) =
tokenPermissionsItem.getType() == TokenPermissionType.BecomeAdmin.int)
self.view.tokenPermissionsModel().setItems(tokenPermissionsItems)
- self.view.setRequiresTokenPermissionToJoin(len(memberPermissions) > 0 or len(adminPermissions) > 0)
+ self.reevaluateRequiresTokenPermissionToJoin()
-proc initCommunityTokenPermissionsModel(self: Module) =
+proc reevaluateRequiresTokenPermissionToJoin(self: Module) =
+ let community = self.controller.getMyCommunity()
+ var hasBecomeMemberOrBecomeAdminPermissions = false
+ for id, tokenPermission in community.tokenPermissions:
+ if tokenPermission.`type` == TokenPermissionType.BecomeMember or tokenPermission.`type` == TokenPermissionType.BecomeAdmin:
+ hasBecomeMemberOrBecomeAdminPermissions = true
+ self.view.setRequiresTokenPermissionToJoin(hasBecomeMemberOrBecomeAdminPermissions)
+
+proc initCommunityTokenPermissionsModel(self: Module, channelGroup: ChannelGroupDto) =
self.rebuildCommunityTokenPermissionsModel()
proc buildTokenList(self: Module) =
@@ -390,14 +402,19 @@ method onChatsLoaded*(
self.usersModule.load()
let community = self.controller.getMyCommunity()
self.view.setAmIMember(community.joined)
- self.initCommunityTokenPermissionsModel()
+ self.initCommunityTokenPermissionsModel(channelGroup)
self.controller.asyncCheckPermissionsToJoin()
let activeChatId = self.controller.getActiveChatId()
let isCurrentSectionActive = self.controller.getIsCurrentSectionActive()
- for chatId, cModule in self.chatContentModules:
- if isCurrentSectionActive and chatId == activeChatId:
- cModule.onMadeActive()
+ if isCurrentSectionActive:
+ for chatId, cModule in self.chatContentModules:
+ if chatId == activeChatId:
+ cModule.onMadeActive()
+
+ if(self.controller.isCommunity()):
+ let community = self.controller.getMyCommunity()
+ self.controller.asyncCheckChannelPermissions(community.id, activeChatId)
self.view.chatsLoaded()
@@ -475,6 +492,10 @@ method activeItemSet*(self: Module, itemId: string) =
# notify parent module about active chat/channel
self.delegate.onActiveChatChange(mySectionId, activeChatId)
self.delegate.onDeactivateChatLoader(deactivateSectionId, deactivateChatId)
+
+ if self.controller.isCommunity():
+ self.controller.asyncCheckChannelPermissions(mySectionId, activeChatId)
+
method getModuleAsVariant*(self: Module): QVariant =
return self.viewVariant
@@ -496,6 +517,16 @@ proc updateParentBadgeNotifications(self: Module) =
unviewedMentionsCount
)
+proc updateChatLocked(self: Module, chatId: string) =
+ let communityId = self.controller.getMySectionId()
+ let locked = self.controller.checkChatIsLocked(communityId, chatId)
+ self.view.chatsModel().setItemLocked(chatId, locked)
+
+proc updateChatRequiresPermissions(self: Module, chatId: string) =
+ let communityId = self.controller.getMySectionId
+ let requiresPermissions = self.controller.checkChatHasPermissions(communityId, chatId)
+ self.view.chatsModel().setItemPermissionsRequired(chatId, requiresPermissions)
+
proc updateBadgeNotifications(self: Module, chat: ChatDto, hasUnreadMessages: bool, unviewedMentionsCount: int) =
let chatId = chat.id
@@ -530,6 +561,11 @@ method onActiveSectionChange*(self: Module, sectionId: string) =
self.setFirstChannelAsActive()
else:
self.setActiveItem(activeChatId)
+
+ if self.isCommunity():
+ self.controller.asyncCheckPermissionsToJoin()
+ self.controller.asyncCheckAllChannelsPermissions()
+
self.delegate.onActiveChatChange(self.controller.getMySectionId(), self.controller.getActiveChatId())
method chatsModel*(self: Module): chats_model.Model =
@@ -625,7 +661,10 @@ method addNewChat*(
categoryOpened,
onlineStatus = onlineStatus,
loaderActive = setChatAsActive,
+ locked = self.controller.checkChatIsLocked(self.controller.getMySectionId(), chatDto.id),
+ requiresPermissions = self.controller.checkChatHasPermissions(self.controller.getMySectionId(), chatDto.id)
)
+
self.addSubmodule(
chatDto.id,
belongsToCommunity,
@@ -640,6 +679,7 @@ method addNewChat*(
gifService,
mailserversService,
)
+
self.chatContentModules[chatDto.id].load(result)
if insertIntoModel:
self.view.chatsModel().appendItem(result)
@@ -786,19 +826,17 @@ method onCommunityTokenPermissionDeleted*(self: Module, communityId: string, per
method onCommunityTokenPermissionCreated*(self: Module, communityId: string, tokenPermission: CommunityTokenPermissionDto) =
let tokenPermissionItem = buildTokenPermissionItem(tokenPermission)
- if tokenPermissionItem.tokenCriteriaMet:
- self.view.setAllTokenRequirementsMet(true)
- self.view.tokenPermissionsModel.addItem(tokenPermissionItem)
- self.view.setRequiresTokenPermissionToJoin(true)
+ self.view.tokenPermissionsModel.addItem(tokenPermissionItem)
+ self.reevaluateRequiresTokenPermissionToJoin()
singletonInstance.globalEvents.showCommunityTokenPermissionCreatedNotification(communityId, "Community permission created", "A token permission has been added")
-method onCommunityCheckPermissionsToJoinResponse*(self: Module, checkPermissionsToJoinResponse: CheckPermissionsToJoinResponseDto) =
- let community = self.controller.getMyCommunity()
-
- for id, criteriaResult in checkPermissionsToJoinResponse.permissions:
+proc updateTokenPermissionModel*(self: Module, permissions: Table[string, CheckPermissionsResultDto], community: CommunityDto) =
+ for id, criteriaResult in permissions:
if community.tokenPermissions.hasKey(id):
let tokenPermissionItem = self.view.tokenPermissionsModel.getItemById(id)
+ if tokenPermissionItem.id == "":
+ continue
var updatedTokenCriteriaItems: seq[TokenCriteriaItem] = @[]
var permissionSatisfied = true
@@ -823,7 +861,7 @@ method onCommunityCheckPermissionsToJoinResponse*(self: Module, checkPermissions
tokenPermissionItem.id,
tokenPermissionItem.`type`,
updatedTokenCriteriaItems,
- @[], # TODO: handle chat list items
+ tokenPermissionItem.getChatList().getItems(),
tokenPermissionItem.isPrivate,
permissionSatisfied
)
@@ -852,9 +890,23 @@ method onCommunityCheckPermissionsToJoinResponse*(self: Module, checkPermissions
self.view.setRequiresTokenPermissionToJoin(requiresPermissionToJoin)
+proc updateChannelPermissionViewData*(self: Module, chatId: string, viewOnlyPermissions: ViewOnlyOrViewAndPostPermissionsResponseDto, viewAndPostPermissions: ViewOnlyOrViewAndPostPermissionsResponseDto, community: CommunityDto) =
+ self.updateTokenPermissionModel(viewOnlyPermissions.permissions, community)
+ self.updateTokenPermissionModel(viewAndPostPermissions.permissions, community)
+ self.updateChatRequiresPermissions(chatId)
+ self.updateChatLocked(chatId)
+ self.chatContentModules[chatId].onUpdateViewOnlyPermissionsSatisfied(viewOnlyPermissions.satisfied)
+ self.chatContentModules[chatId].onUpdateViewAndPostPermissionsSatisfied(viewAndPostPermissions.satisfied)
+
+method onCommunityCheckPermissionsToJoinResponse*(self: Module, checkPermissionsToJoinResponse: CheckPermissionsToJoinResponseDto) =
+ let community = self.controller.getMyCommunity()
+ self.view.setAllTokenRequirementsMet(checkPermissionsToJoinResponse.satisfied)
+ self.updateTokenPermissionModel(checkPermissionsToJoinResponse.permissions, community)
+
method onCommunityTokenPermissionUpdated*(self: Module, communityId: string, tokenPermission: CommunityTokenPermissionDto) =
let tokenPermissionItem = buildTokenPermissionItem(tokenPermission)
self.view.tokenPermissionsModel.updateItem(tokenPermission.id, tokenPermissionItem)
+ self.reevaluateRequiresTokenPermissionToJoin()
singletonInstance.globalEvents.showCommunityTokenPermissionUpdatedNotification(communityId, "Community permission updated", "A token permission has been updated")
@@ -867,6 +919,15 @@ method onCommunityTokenPermissionUpdateFailed*(self: Module, communityId: string
method onCommunityTokenPermissionDeletionFailed*(self: Module, communityId: string) =
singletonInstance.globalEvents.showCommunityTokenPermissionDeletionFailedNotification(communityId, "Failed to delete community permission", "Something went wrong")
+method onCommunityCheckChannelPermissionsResponse*(self: Module, chatId: string, checkChannelPermissionsResponse: CheckChannelPermissionsResponseDto) =
+ let community = self.controller.getMyCommunity()
+ self.updateChannelPermissionViewData(chatId, checkChannelPermissionsResponse.viewOnlyPermissions, checkChannelPermissionsResponse.viewAndPostPermissions, community)
+
+method onCommunityCheckAllChannelsPermissionsResponse*(self: Module, checkAllChannelsPermissionsResponse: CheckAllChannelsPermissionsResponseDto) =
+ let community = self.controller.getMyCommunity()
+ for chatId, permissionResult in checkAllChannelsPermissionsResponse.channels:
+ self.updateChannelPermissionViewData(chatId, permissionResult.viewOnlyPermissions, permissionResult.viewAndPostPermissions, community)
+
method onCommunityTokenMetadataAdded*(self: Module, communityId: string, tokenMetadata: CommunityTokensMetadataDto) =
let tokenListItem = initTokenListItem(
key = tokenMetadata.symbol,
@@ -1207,6 +1268,8 @@ proc addOrUpdateChat(self: Module,
if chatExists:
self.changeMutedOnChat(chat.id, chat.muted)
+ self.updateChatRequiresPermissions(chat.id)
+ self.updateChatLocked(chat.id)
if (chat.chatType == ChatType.PrivateGroupChat):
self.onGroupChatDetailsUpdated(chat.id, chat.name, chat.color, chat.icon)
elif (chat.chatType != ChatType.OneToOne):
@@ -1278,13 +1341,19 @@ method joinSpectatedCommunity*(self: Module) =
if self.usersModule != nil:
self.usersModule.updateMembersList()
-method createOrEditCommunityTokenPermission*(self: Module, communityId: string, permissionId: string, permissionType: int, tokenCriteriaJson: string, isPrivate: bool) =
+method createOrEditCommunityTokenPermission*(self: Module, communityId: string, permissionId: string, permissionType: int, tokenCriteriaJson: string, channelIDs: seq[string], isPrivate: bool) =
+
var tokenPermission = CommunityTokenPermissionDto()
tokenPermission.id = permissionId
tokenPermission.isPrivate = isPrivate
tokenPermission.`type` = TokenPermissionType(permissionType)
+ tokenPermission.chatIDs = channelIDs
+
+ if tokenPermission.`type` != TokenPermissionType.View and tokenPermission.`type` != TokenPermissionType.ViewAndPost:
+ tokenPermission.chatIDs = @[]
let tokenCriteriaJsonObj = tokenCriteriaJson.parseJson
+
for tokenCriteria in tokenCriteriaJsonObj:
let viewAmount = tokenCriteria{"amount"}.getFloat
diff --git a/src/app/modules/main/chat_section/view.nim b/src/app/modules/main/chat_section/view.nim
index 65d2961f2d..33df9ebca3 100644
--- a/src/app/modules/main/chat_section/view.nim
+++ b/src/app/modules/main/chat_section/view.nim
@@ -1,4 +1,4 @@
-import NimQml, json, sequtils
+import NimQml, json, sequtils, strutils
import model as chats_model
import item, active_item
import ../../shared_models/user_model as user_model
@@ -401,8 +401,10 @@ QtObject:
QtProperty[QVariant] permissionsModel:
read = getTokenPermissionsModel
- proc createOrEditCommunityTokenPermission*(self: View, communityId: string, permissionId: string, permissionType: int, tokenCriteriaJson: string, isPrivate: bool) {.slot.} =
- self.delegate.createOrEditCommunityTokenPermission(communityId, permissionId, permissionType, tokenCriteriaJson, isPrivate)
+ proc createOrEditCommunityTokenPermission*(self: View, communityId: string, permissionId: string, permissionType: int, tokenCriteriaJson: string, channelIDs: string, isPrivate: bool) {.slot.} =
+
+ let chatIDs = channelIDs.split(',')
+ self.delegate.createOrEditCommunityTokenPermission(communityId, permissionId, permissionType, tokenCriteriaJson, chatIDs, isPrivate)
proc deleteCommunityTokenPermission*(self: View, communityId: string, permissionId: string) {.slot.} =
self.delegate.deleteCommunityTokenPermission(communityId, permissionId)
@@ -450,4 +452,4 @@ QtObject:
QtProperty[bool] allTokenRequirementsMet:
read = getAllTokenRequirementsMet
- notify = allTokenRequirementsMetChanged
\ No newline at end of file
+ notify = allTokenRequirementsMetChanged
diff --git a/src/app/modules/shared_models/token_permission_chat_list_item.nim b/src/app/modules/shared_models/token_permission_chat_list_item.nim
index 0eb4f362b5..6edba2f29f 100644
--- a/src/app/modules/shared_models/token_permission_chat_list_item.nim
+++ b/src/app/modules/shared_models/token_permission_chat_list_item.nim
@@ -3,23 +3,17 @@ import strformat
type
TokenPermissionChatListItem* = object
key: string
- name: string
proc `$`*(self: TokenPermissionChatListItem): string =
result = fmt"""TokenPermissionChatListItem(
- key: {self.key},
- name: {self.name},
+ key: {self.key}
]"""
proc initTokenPermissionChatListItem*(
- key: string,
- name: string,
+ key: string
): TokenPermissionChatListItem =
result.key = key
- result.name = name
proc getKey*(self: TokenPermissionChatListItem): string =
return self.key
-proc getName*(self: TokenPermissionChatListItem): string =
- return self.name
diff --git a/src/app/modules/shared_models/token_permission_chat_list_model.nim b/src/app/modules/shared_models/token_permission_chat_list_model.nim
index def062502b..3f7edb7ca6 100644
--- a/src/app/modules/shared_models/token_permission_chat_list_model.nim
+++ b/src/app/modules/shared_models/token_permission_chat_list_model.nim
@@ -4,7 +4,6 @@ import token_permission_chat_list_item
type
ModelRole {.pure.} = enum
Key = UserRole + 1
- Name
QtObject:
type TokenPermissionChatListModel* = ref object of QAbstractListModel
@@ -24,7 +23,6 @@ QtObject:
method roleNames(self: TokenPermissionChatListModel): Table[int, string] =
{
ModelRole.Key.int:"key",
- ModelRole.Name.int:"name",
}.toTable
proc countChanged(self: TokenPermissionChatListModel) {.signal.}
@@ -47,8 +45,6 @@ QtObject:
case enumRole:
of ModelRole.Key:
result = newQVariant(item.getKey())
- of ModelRole.Name:
- result = newQVariant(item.getName())
proc addItem*(self: TokenPermissionChatListModel, item: TokenPermissionChatListItem) =
let parentModelIndex = newQModelIndex()
@@ -57,3 +53,12 @@ QtObject:
self.items.add(item)
self.endInsertRows()
self.countChanged()
+
+ proc setItems*(self: TokenPermissionChatListModel, items: seq[TokenPermissionChatListItem]) =
+ self.beginResetModel()
+ self.items = items
+ self.endResetModel()
+ self.countChanged()
+
+ proc getItems*(self: TokenPermissionChatListModel): seq[TokenPermissionChatListItem] =
+ return self.items
diff --git a/src/app/modules/shared_models/token_permission_item.nim b/src/app/modules/shared_models/token_permission_item.nim
index 5ff03e9212..97d9223932 100644
--- a/src/app/modules/shared_models/token_permission_item.nim
+++ b/src/app/modules/shared_models/token_permission_item.nim
@@ -63,7 +63,6 @@ proc getIsPrivate*(self: TokenPermissionItem): bool =
proc getTokenCriteriaMet*(self: TokenPermissionItem): bool =
return self.tokenCriteriaMet
-
proc buildTokenPermissionItem*(tokenPermission: CommunityTokenPermissionDto): TokenPermissionItem =
var tokenCriteriaItems: seq[TokenCriteriaItem] = @[]
@@ -80,11 +79,15 @@ proc buildTokenPermissionItem*(tokenPermission: CommunityTokenPermissionDto): To
tokenCriteriaItems.add(tokenCriteriaItem)
+ var tokenPermissionChatListItems: seq[TokenPermissionChatListItem] = @[]
+ for chatID in tokenPermission.chatIDs:
+ tokenPermissionChatListItems.add(initTokenPermissionChatListItem(chatID))
+
let tokenPermissionItem = initTokenPermissionItem(
tokenPermission.id,
tokenPermission.`type`.int,
tokenCriteriaItems,
- @[], # TODO: handle chat list items
+ tokenPermissionChatListItems,
tokenPermission.isPrivate,
false # allTokenCriteriaMet will be update by a call to checkPermissinosToJoin
)
diff --git a/src/app/modules/shared_models/token_permissions_model.nim b/src/app/modules/shared_models/token_permissions_model.nim
index 333cea1c35..d557e5c9a1 100644
--- a/src/app/modules/shared_models/token_permissions_model.nim
+++ b/src/app/modules/shared_models/token_permissions_model.nim
@@ -1,5 +1,7 @@
import NimQml, Tables
import token_permission_item
+import token_permission_chat_list_item
+import token_permission_chat_list_model
import token_criteria_model
type
@@ -10,6 +12,7 @@ type
TokenCriteria
ChatList
IsPrivate
+ TokenCriteriaMet
QtObject:
type TokenPermissionsModel* = ref object of QAbstractListModel
@@ -34,15 +37,34 @@ QtObject:
ModelRole.TokenCriteria.int:"holdingsListModel",
ModelRole.ChatList.int:"channelsListModel",
ModelRole.IsPrivate.int:"isPrivate",
+ ModelRole.TokenCriteriaMet.int:"tokenCriteriaMet",
}.toTable
proc countChanged(self: TokenPermissionsModel) {.signal.}
proc getCount*(self: TokenPermissionsModel): int {.slot.} =
return self.items.len
+
QtProperty[int] count:
read = getCount
notify = countChanged
+ proc findIndexById(self: TokenPermissionsModel, id: string): int =
+ for i in 0 ..< self.items.len:
+ if(self.items[i].getId() == id):
+ return i
+ return -1
+
+ proc belongsToChat*(self: TokenPermissionsModel, permissionId: string, chatId: string): bool {.slot.} =
+ let idx = self.findIndexById(permissionId)
+ if(idx == -1):
+ return false
+
+ for clItem in self.items[idx].chatList.getItems():
+ if clItem.getKey() == chatId:
+ return true
+
+ return false
+
method rowCount(self: TokenPermissionsModel, index: QModelIndex = nil): int =
return self.items.len
@@ -66,6 +88,8 @@ QtObject:
result = newQVariant(item.getChatList())
of ModelRole.IsPrivate:
result = newQVariant(item.getIsPrivate())
+ of ModelRole.TokenCriteriaMet:
+ result = newQVariant(item.getTokenCriteriaMet())
proc addItem*(self: TokenPermissionsModel, item: TokenPermissionItem) =
let parentModelIndex = newQModelIndex()
@@ -84,12 +108,6 @@ QtObject:
proc getItems*(self: TokenPermissionsModel): seq[TokenPermissionItem] =
return self.items
- proc findIndexById(self: TokenPermissionsModel, id: string): int =
- for i in 0 ..< self.items.len:
- if(self.items[i].getId() == id):
- return i
- return -1
-
proc removeItemWithId*(self: TokenPermissionsModel, permissionId: string) =
let idx = self.findIndexById(permissionId)
if(idx == -1):
@@ -117,6 +135,7 @@ QtObject:
self.items[idx].`type` = item.`type`
self.items[idx].tokenCriteria.setItems(item.tokenCriteria.getItems())
+ self.items[idx].chatList.setItems(item.chatList.getItems())
self.items[idx].isPrivate = item.isPrivate
self.items[idx].tokenCriteriaMet = item.tokenCriteriaMet
@@ -127,4 +146,5 @@ QtObject:
ModelRole.Type.int,
ModelRole.TokenCriteria.int,
ModelRole.IsPrivate.int,
+ ModelRole.TokenCriteriaMet.int
])
diff --git a/src/app_service/service/community/async_tasks.nim b/src/app_service/service/community/async_tasks.nim
index 3b737dbbe0..2b3fcb604c 100644
--- a/src/app_service/service/community/async_tasks.nim
+++ b/src/app_service/service/community/async_tasks.nim
@@ -121,3 +121,44 @@ const asyncCheckPermissionsToJoinTask: Task = proc(argEncoded: string) {.gcsafe,
"communityId": arg.communityId,
"error": e.msg,
})
+
+type
+ AsyncCheckChannelPermissionsTaskArg = ref object of QObjectTaskArg
+ communityId: string
+ chatId: string
+
+const asyncCheckChannelPermissionsTask: Task = proc(argEncoded: string) {.gcsafe, nimcall.} =
+ let arg = decode[AsyncCheckChannelPermissionsTaskArg](argEncoded)
+ try:
+ let response = status_go.checkCommunityChannelPermissions(arg.communityId, arg.chatId)
+ arg.finish(%* {
+ "response": response,
+ "communityId": arg.communityId,
+ "chatId": arg.chatId,
+ "error": "",
+ })
+ except Exception as e:
+ arg.finish(%* {
+ "communityId": arg.communityId,
+ "chatId": arg.chatId,
+ "error": e.msg,
+ })
+
+type
+ AsyncCheckAllChannelsPermissionsTaskArg = ref object of QObjectTaskArg
+ communityId: string
+
+const asyncCheckAllChannelsPermissionsTask: Task = proc(argEncoded: string) {.gcsafe, nimcall.} =
+ let arg = decode[AsyncCheckAllChannelsPermissionsTaskArg](argEncoded)
+ try:
+ let response = status_go.checkAllCommunityChannelsPermissions(arg.communityId)
+ arg.finish(%* {
+ "response": response,
+ "communityId": arg.communityId,
+ "error": "",
+ })
+ except Exception as e:
+ arg.finish(%* {
+ "communityId": arg.communityId,
+ "error": e.msg,
+ })
diff --git a/src/app_service/service/community/dto/community.nim b/src/app_service/service/community/dto/community.nim
index 13e4d059ea..d67ccc763c 100644
--- a/src/app_service/service/community/dto/community.nim
+++ b/src/app_service/service/community/dto/community.nim
@@ -39,7 +39,6 @@ type TokenPermissionType* {.pure.}= enum
View = 3,
ViewAndPost = 4,
-
type TokenType* {.pure.}= enum
Unknown = 0,
ERC20 = 1,
@@ -71,6 +70,29 @@ type CommunityTokensMetadataDto* = object
name*: string
tokenType*: TokenType
+type AccountChainIDsCombinationDto* = object
+ address*: string
+ chainIds*: seq[int]
+
+type CheckPermissionsResultDto* = object
+ criteria*: seq[bool]
+
+type CheckPermissionsToJoinResponseDto* = object
+ satisfied*: bool
+ permissions*: Table[string, CheckPermissionsResultDto]
+ validCombinations*: seq[AccountChainIDsCombinationDto]
+
+type ViewOnlyOrViewAndPostPermissionsResponseDto* = object
+ satisfied*: bool
+ permissions*: Table[string, CheckPermissionsResultDto]
+
+type CheckChannelPermissionsResponseDto* = object
+ viewOnlyPermissions*: ViewOnlyOrViewAndPostPermissionsResponseDto
+ viewAndPostPermissions*: ViewOnlyOrViewAndPostPermissionsResponseDto
+
+type CheckAllChannelsPermissionsResponseDto* = object
+ channels*: Table[string, CheckChannelPermissionsResponseDto]
+
type CommunityDto* = object
id*: string
memberRole*: MemberRole
@@ -106,6 +128,7 @@ type CommunityDto* = object
canceledRequestsToJoin*: seq[CommunityMembershipRequestDto]
tokenPermissions*: Table[string, CommunityTokenPermissionDto]
communityTokensMetadata*: seq[CommunityTokensMetadataDto]
+ channelPermissions*: CheckAllChannelsPermissionsResponseDto
activeMembersCount*: int64
proc isAvailable*(communityDto: CommunityDto): bool =
@@ -140,18 +163,6 @@ type DiscordImportTaskProgress* = object
stopped*: bool
state*: string
-type AccountChainIDsCombinationDto* = object
- address*: string
- chainIds*: seq[int]
-
-type CheckPermissionToJoinResultDto* = object
- criteria*: seq[bool]
-
-type CheckPermissionsToJoinResponseDto* = object
- satisfied*: bool
- permissions*: Table[string, CheckPermissionToJoinResultDto]
- validCombinations*: seq[AccountChainIDsCombinationDto]
-
proc toCommunityAdminSettingsDto*(jsonObj: JsonNode): CommunityAdminSettingsDto =
result = CommunityAdminSettingsDto()
discard jsonObj.getProp("pinMessageAllMembersEnabled", result.pinMessageAllMembersEnabled)
@@ -241,7 +252,7 @@ proc toTokenCriteriaDto*(jsonObj: JsonNode): TokenCriteriaDto =
proc toCommunityTokenPermissionDto*(jsonObj: JsonNode): CommunityTokenPermissionDto =
result = CommunityTokenPermissionDto()
discard jsonObj.getProp("id", result.id)
- discard jsonObj.getProp("isPrivate", result.isPrivate)
+ discard jsonObj.getProp("is_private", result.isPrivate)
var tokenPermissionTypeInt: int
discard jsonObj.getProp("type", tokenPermissionTypeInt)
if (tokenPermissionTypeInt >= ord(low(TokenPermissionType)) or tokenPermissionTypeInt <= ord(high(TokenPermissionType))):
@@ -253,7 +264,7 @@ proc toCommunityTokenPermissionDto*(jsonObj: JsonNode): CommunityTokenPermission
result.tokenCriteria.add(tokenCriteria.toTokenCriteriaDto)
var chatIdsObj: JsonNode
- if(jsonObj.getProp("chatIds", chatIdsObj) and chatIdsObj.kind == JArray):
+ if(jsonObj.getProp("chat_ids", chatIdsObj) and chatIdsObj.kind == JArray):
for chatId in chatIdsObj:
result.chatIds.add(chatId.getStr)
@@ -262,8 +273,8 @@ proc toCommunityTokenPermissionDto*(jsonObj: JsonNode): CommunityTokenPermission
if jsonObj.hasKey("key"):
discard jsonObj.getProp("key", result.id)
-proc toCheckPermissionToJoinResultDto*(jsonObj: JsonNode): CheckPermissionToJoinResultDto =
- result = CheckPermissionToJoinResultDto()
+proc toCheckPermissionsResultDto*(jsonObj: JsonNode): CheckPermissionsResultDto =
+ result = CheckPermissionsResultDto()
var criteriaObj: JsonNode
if(jsonObj.getProp("criteria", criteriaObj) and criteriaObj.kind == JArray):
for c in criteriaObj:
@@ -288,9 +299,39 @@ proc toCheckPermissionsToJoinResponseDto*(jsonObj: JsonNode): CheckPermissionsTo
var permissionsObj: JsonNode
if(jsonObj.getProp("permissions", permissionsObj) and permissionsObj.kind == JObject):
- result.permissions = initTable[string, CheckPermissionToJoinResultDto]()
+ result.permissions = initTable[string, CheckPermissionsResultDto]()
for permissionId, permission in permissionsObj:
- result.permissions[permissionId] = permission.toCheckPermissionToJoinResultDto
+ result.permissions[permissionId] = permission.toCheckPermissionsResultDto
+
+proc toViewOnlyOrViewAndPostPermissionsResponseDto*(jsonObj: JsonNode): ViewOnlyOrViewAndPostPermissionsResponseDto =
+ result = ViewOnlyOrViewAndPostPermissionsResponseDto()
+ discard jsonObj.getProp("satisfied", result.satisfied)
+
+ var permissionsObj: JsonNode
+ if(jsonObj.getProp("permissions", permissionsObj) and permissionsObj.kind == JObject):
+ result.permissions = initTable[string, CheckPermissionsResultDto]()
+ for permissionId, permission in permissionsObj:
+ result.permissions[permissionId] = permission.toCheckPermissionsResultDto
+
+proc toCheckChannelPermissionsResponseDto*(jsonObj: JsonNode): CheckChannelPermissionsResponseDto =
+ result = CheckChannelPermissionsResponseDto()
+
+ var viewOnlyPermissionsObj: JsonNode
+ if(jsonObj.getProp("viewOnlyPermissions", viewOnlyPermissionsObj) and viewOnlyPermissionsObj.kind == JObject):
+ result.viewOnlyPermissions = viewOnlyPermissionsObj.toViewOnlyOrViewAndPostPermissionsResponseDto()
+
+ var viewAndPostPermissionsObj: JsonNode
+ if(jsonObj.getProp("viewAndPostPermissions", viewAndPostPermissionsObj) and viewAndPostPermissionsObj.kind == JObject):
+ result.viewAndPostPermissions = viewAndPostPermissionsObj.toViewOnlyOrViewAndPostPermissionsResponseDto()
+
+proc toCheckAllChannelsPermissionsResponseDto*(jsonObj: JsonNode): CheckAllChannelsPermissionsResponseDto =
+ result = CheckAllChannelsPermissionsResponseDto()
+ result.channels = initTable[string, CheckChannelPermissionsResponseDto]()
+
+ var channelsObj: JsonNode
+ if(jsonObj.getProp("channels", channelsObj) and channelsObj.kind == JObject):
+ for channelId, permissionResponse in channelsObj:
+ result.channels[channelId] = permissionResponse.toCheckChannelPermissionsResponseDto()
proc toCommunityDto*(jsonObj: JsonNode): CommunityDto =
result = CommunityDto()
diff --git a/src/app_service/service/community/service.nim b/src/app_service/service/community/service.nim
index 59369dc814..2aa502f8b3 100644
--- a/src/app_service/service/community/service.nim
+++ b/src/app_service/service/community/service.nim
@@ -117,6 +117,15 @@ type
communityId*: string
checkPermissionsToJoinResponse*: CheckPermissionsToJoinResponseDto
+ CheckChannelPermissionsResponseArgs* = ref object of Args
+ communityId*: string
+ chatId*: string
+ checkChannelPermissionsResponse*: CheckChannelPermissionsResponseDto
+
+ CheckAllChannelsPermissionsResponseArgs* = ref object of Args
+ communityId*: string
+ checkAllChannelsPermissionsResponse*: CheckAllChannelsPermissionsResponseDto
+
# Signals which may be emitted by this service:
const SIGNAL_COMMUNITY_DATA_LOADED* = "communityDataLoaded"
const SIGNAL_COMMUNITY_JOINED* = "communityJoined"
@@ -179,6 +188,8 @@ const TOKEN_PERMISSIONS_ADDED = "tokenPermissionsAdded"
const TOKEN_PERMISSIONS_MODIFIED = "tokenPermissionsModified"
const SIGNAL_CHECK_PERMISSIONS_TO_JOIN_RESPONSE* = "checkPermissionsToJoinResponse"
+const SIGNAL_CHECK_CHANNEL_PERMISSIONS_RESPONSE* = "checkChannelPermissionsResponse"
+const SIGNAL_CHECK_ALL_CHANNELS_PERMISSIONS_RESPONSE* = "checkAllChannelsPermissionsResponse"
QtObject:
type
@@ -581,6 +592,7 @@ QtObject:
if tokenPermission.tokenCriteria.len != prevTokenPermission.tokenCriteria.len or
tokenPermission.isPrivate != prevTokenPermission.isPrivate or
+ tokenPermission.chatIds.len != prevTokenPermission.chatIds.len or
tokenPermission.`type` != prevTokenPermission.`type`:
permissionUpdated = true
@@ -588,14 +600,16 @@ QtObject:
for tc in tokenPermission.tokenCriteria:
let index = findIndexBySymbol(tc.symbol, prevTokenPermission.tokenCriteria)
if index == -1:
- continue
-
- let prevTc = prevTokenPermission.tokenCriteria[index]
- if tc.amount != prevTc.amount or tc.ensPattern != prevTc.ensPattern:
permissionUpdated = true
- break
+ else:
+
+ let prevTc = prevTokenPermission.tokenCriteria[index]
+ if tc.amount != prevTc.amount or tc.ensPattern != prevTc.ensPattern or tc.symbol != prevTc.symbol or tc.name != prevTc.name or tc.decimals != prevTc.decimals:
+ permissionUpdated = true
+ break
if permissionUpdated:
+ self.communities[community.id].tokenPermissions[id] = tokenPermission
self.events.emit(SIGNAL_COMMUNITY_TOKEN_PERMISSION_UPDATED,
CommunityTokenPermissionArgs(communityId: community.id, tokenPermission: tokenPermission))
@@ -1371,16 +1385,13 @@ QtObject:
self.events.emit(SIGNAL_COMMUNITY_DATA_IMPORTED, CommunityArgs(community: community))
proc asyncCheckPermissionsToJoin*(self: Service, communityId: string) =
- try:
- let arg = AsyncCheckPermissionsToJoinTaskArg(
- tptr: cast[ByteAddress](asyncCheckPermissionsToJoinTask),
- vptr: cast[ByteAddress](self.vptr),
- slot: "onAsyncCheckPermissionsToJoinDone",
- communityId: communityId
- )
- self.threadpool.start(arg)
- except Exception as e:
- error "Error checking permissions to join community", msg = e.msg
+ let arg = AsyncCheckPermissionsToJoinTaskArg(
+ tptr: cast[ByteAddress](asyncCheckPermissionsToJoinTask),
+ vptr: cast[ByteAddress](self.vptr),
+ slot: "onAsyncCheckPermissionsToJoinDone",
+ communityId: communityId
+ )
+ self.threadpool.start(arg)
proc onAsyncCheckPermissionsToJoinDone*(self: Service, rpcResponse: string) {.slot.} =
try:
@@ -1397,6 +1408,59 @@ QtObject:
let errMsg = e.msg
error "error checking permissions to join: ", errMsg
+ proc asyncCheckChannelPermissions*(self: Service, communityId: string, chatId: string) =
+ let arg = AsyncCheckChannelPermissionsTaskArg(
+ tptr: cast[ByteAddress](asyncCheckChannelPermissionsTask),
+ vptr: cast[ByteAddress](self.vptr),
+ slot: "onAsyncCheckChannelPermissionsDone",
+ communityId: communityId,
+ chatId: chatId
+ )
+ self.threadpool.start(arg)
+
+ proc onAsyncCheckChannelPermissionsDone*(self: Service, rpcResponse: string) {.slot.} =
+ try:
+ let rpcResponseObj = rpcResponse.parseJson
+ if rpcResponseObj{"error"}.kind != JNull and rpcResponseObj{"error"}.getStr != "":
+ let error = Json.decode($rpcResponseObj["error"], RpcError)
+ error "Error checking community channel permissions", msg = error.message
+ return
+
+ let communityId = rpcResponseObj{"communityId"}.getStr()
+ let chatId = rpcResponseObj{"chatId"}.getStr()
+ let checkChannelPermissionsResponse = rpcResponseObj["response"]["result"].toCheckChannelPermissionsResponseDto()
+ self.communities[communityId].channelPermissions.channels[chatId] = checkChannelPermissionsResponse
+ self.events.emit(SIGNAL_CHECK_CHANNEL_PERMISSIONS_RESPONSE, CheckChannelPermissionsResponseArgs(communityId: communityId, chatId: chatId, checkChannelPermissionsResponse: checkChannelPermissionsResponse))
+ except Exception as e:
+ let errMsg = e.msg
+ error "error checking all channel permissions: ", errMsg
+
+ proc asyncCheckAllChannelsPermissions*(self: Service, communityId: string) =
+ let arg = AsyncCheckAllChannelsPermissionsTaskArg(
+ tptr: cast[ByteAddress](asyncCheckAllChannelsPermissionsTask),
+ vptr: cast[ByteAddress](self.vptr),
+ slot: "onAsyncCheckAllChannelsPermissionsDone",
+ communityId: communityId
+ )
+ self.threadpool.start(arg)
+
+ proc onAsyncCheckAllChannelsPermissionsDone*(self: Service, rpcResponse: string) {.slot.} =
+ try:
+ let rpcResponseObj = rpcResponse.parseJson
+ if rpcResponseObj{"error"}.kind != JNull and rpcResponseObj{"error"}.getStr != "":
+ let error = Json.decode($rpcResponseObj["error"], RpcError)
+ error "Error checking all community channel permissions", msg = error.message
+ return
+
+ let communityId = rpcResponseObj{"communityId"}.getStr()
+ let checkAllChannelsPermissionsResponse = rpcResponseObj["response"]["result"].toCheckAllChannelsPermissionsResponseDto()
+ self.communities[communityId].channelPermissions = checkAllChannelsPermissionsResponse
+ self.events.emit(SIGNAL_CHECK_ALL_CHANNELS_PERMISSIONS_RESPONSE, CheckAllChannelsPermissionsResponseArgs(communityId: communityId, checkAllChannelsPermissionsResponse: checkAllChannelsPermissionsResponse))
+
+ except Exception as e:
+ let errMsg = e.msg
+ error "error checking all channels permissions: ", errMsg
+
proc asyncRequestToJoinCommunity*(self: Service, communityId: string, ensName: string, password: string) =
try:
let arg = AsyncRequestToJoinCommunityTaskArg(
@@ -1783,9 +1847,9 @@ QtObject:
var response: RpcResponse[JsonNode]
if editing:
- response = status_go.editCommunityTokenPermission(communityId, tokenPermission.id, int(tokenPermission.`type`), Json.encode(tokenPermission.tokenCriteria), tokenPermission.isPrivate)
+ response = status_go.editCommunityTokenPermission(communityId, tokenPermission.id, int(tokenPermission.`type`), Json.encode(tokenPermission.tokenCriteria), tokenPermission.chatIDs, tokenPermission.isPrivate)
else:
- response = status_go.createCommunityTokenPermission(communityId, int(tokenPermission.`type`), Json.encode(tokenPermission.tokenCriteria), tokenPermission.isPrivate)
+ response = status_go.createCommunityTokenPermission(communityId, int(tokenPermission.`type`), Json.encode(tokenPermission.tokenCriteria), tokenPermission.chatIDs, tokenPermission.isPrivate)
if response.result != nil and response.result.kind != JNull:
var changesField = TOKEN_PERMISSIONS_ADDED
@@ -1835,3 +1899,20 @@ QtObject:
let community = self.communities[communityId]
return community.pendingRequestsToJoin[indexPending].publicKey
+
+ proc checkChatHasPermissions*(self: Service, communityId: string, chatId: string): bool =
+ let community = self.getCommunityById(communityId)
+ for id, tokenPermission in community.tokenPermissions:
+ if TokenPermissionType(tokenPermission.`type`) == TokenPermissionType.View or TokenPermissionType(tokenPermission.`type`) == TokenPermissionType.ViewAndPost:
+ for id in tokenPermission.chatIds:
+ if id == chatId:
+ return true
+ return false
+
+ proc checkChatIsLocked*(self: Service, communityId: string, chatId: string): bool =
+ if not self.communities.hasKey(communityId):
+ return false
+
+ let community = self.getCommunityById(communityId)
+ return community.channelPermissions.channels.hasKey(chatId) and not community.channelPermissions.channels[chatId].viewAndPostPermissions.satisfied
+
diff --git a/src/backend/communities.nim b/src/backend/communities.nim
index 33be3fdc6a..b1d6bcff41 100644
--- a/src/backend/communities.nim
+++ b/src/backend/communities.nim
@@ -44,6 +44,17 @@ proc checkPermissionsToJoinCommunity*(communityId: string): RpcResponse[JsonNode
"communityId": communityId
}])
+proc checkCommunityChannelPermissions*(communityId: string, chatId: string): RpcResponse[JsonNode] {.raises: [Exception].} =
+ result = callPrivateRPC("checkCommunityChannelPermissions".prefix, %*[{
+ "communityId": communityId,
+ "chatId": chatId
+ }])
+
+proc checkAllCommunityChannelsPermissions*(communityId: string): RpcResponse[JsonNode] {.raises: [Exception].} =
+ result = callPrivateRPC("checkAllCommunityChannelsPermissions".prefix, %*[{
+ "communityId": communityId
+ }])
+
proc myPendingRequestsToJoin*(): RpcResponse[JsonNode] {.raises: [Exception].} =
result = callPrivateRPC("myPendingRequestsToJoin".prefix)
@@ -177,20 +188,22 @@ proc requestImportDiscordCommunity*(
"filesToImport": filesToImport
}])
-proc createCommunityTokenPermission*(communityId: string, permissionType: int, tokenCriteria: string, isPrivate: bool): RpcResponse[JsonNode] {.raises: [Exception].} =
+proc createCommunityTokenPermission*(communityId: string, permissionType: int, tokenCriteria: string, chatIDs: seq[string], isPrivate: bool): RpcResponse[JsonNode] {.raises: [Exception].} =
result = callPrivateRPC("createCommunityTokenPermission".prefix, %*[{
"communityId": communityId,
"type": permissionType,
"tokenCriteria": parseJson(tokenCriteria),
+ "chat_ids": chatIDs,
"isPrivate": isPrivate
}])
-proc editCommunityTokenPermission*(communityId: string, permissionId: string, permissionType: int, tokenCriteria: string, isPrivate: bool): RpcResponse[JsonNode] {.raises: [Exception].} =
+proc editCommunityTokenPermission*(communityId: string, permissionId: string, permissionType: int, tokenCriteria: string, chatIDs: seq[string], isPrivate: bool): RpcResponse[JsonNode] {.raises: [Exception].} =
result = callPrivateRPC("editCommunityTokenPermission".prefix, %*[{
"communityId": communityId,
"permissionId": permissionId,
"type": permissionType,
"tokenCriteria": parseJson(tokenCriteria),
+ "chat_ids": chatIDs,
"isPrivate": isPrivate
}])
diff --git a/ui/StatusQ/src/StatusQ/Components/StatusChatList.qml b/ui/StatusQ/src/StatusQ/Components/StatusChatList.qml
index 16fbd14cf6..b46172ecc3 100644
--- a/ui/StatusQ/src/StatusQ/Components/StatusChatList.qml
+++ b/ui/StatusQ/src/StatusQ/Components/StatusChatList.qml
@@ -180,6 +180,8 @@ Item {
onlineStatus: !!model.onlineStatus ? model.onlineStatus : StatusChatListItem.OnlineStatus.Inactive
sensor.enabled: draggableItem.dragActive
dragged: draggableItem.dragActive
+ requiresPermissions: model.requiresPermissions
+ locked: model.locked
onClicked: {
highlightWhenCreated = false
diff --git a/ui/StatusQ/src/StatusQ/Components/StatusChatListItem.qml b/ui/StatusQ/src/StatusQ/Components/StatusChatListItem.qml
index d3303ab0ce..949105efe9 100644
--- a/ui/StatusQ/src/StatusQ/Components/StatusChatListItem.qml
+++ b/ui/StatusQ/src/StatusQ/Components/StatusChatListItem.qml
@@ -20,6 +20,8 @@ Rectangle {
property int notificationsCount: 0
property bool muted: false
property int onlineStatus: StatusChatListItem.OnlineStatus.Inactive
+ property bool requiresPermissions: false
+ property bool locked: false
property StatusAssetSettings asset: StatusAssetSettings {
width: 24
@@ -36,9 +38,6 @@ Rectangle {
property bool dragged: false
property alias sensor: sensor
- property bool requiresPermissions
- property bool locked
-
signal clicked(var mouse)
signal unmute()
diff --git a/ui/app/AppLayouts/Chat/ChatLayout.qml b/ui/app/AppLayouts/Chat/ChatLayout.qml
index b896e48f7d..584bf56fa7 100644
--- a/ui/app/AppLayouts/Chat/ChatLayout.qml
+++ b/ui/app/AppLayouts/Chat/ChatLayout.qml
@@ -32,6 +32,7 @@ StackLayout {
}
Loader {
+ id: mainViewLoader
readonly property var chatItem: root.rootStore.chatCommunitySectionModule
sourceComponent: chatItem.isCommunity() && chatItem.requiresTokenPermissionToJoin && !chatItem.amIMember ? joinCommunityViewComponent : chatViewComponent
}
@@ -41,6 +42,7 @@ StackLayout {
JoinCommunityView {
id: joinCommunityView
readonly property var communityData: sectionItemModel
+ readonly property string communityId: communityData.id
name: communityData.name
introMessage: communityData.introMessage
communityDesc: communityData.description
@@ -53,7 +55,10 @@ StackLayout {
communityData.memberRole === Constants.memberRole.admin
communityItemsModel: root.rootStore.communityItemsModel
requirementsMet: root.permissionsStore.allTokenRequirementsMet
- communityHoldingsModel: root.permissionsStore.permissionsModel
+ requiresRequest: !communityData.amIMember
+ communityHoldingsModel: root.permissionsStore.becomeMemberPermissionsModel
+ viewOnlyHoldingsModel: root.permissionsStore.viewOnlyPermissionsModel
+ viewAndPostHoldingsModel: root.permissionsStore.viewAndPostPermissionsModel
assetsModel: root.rootStore.assetsModel
collectiblesModel: root.rootStore.collectiblesModel
isInvitationPending: root.rootStore.isCommunityRequestPending(communityData.id)
@@ -63,19 +68,20 @@ StackLayout {
loginType: root.rootStore.loginType
onNotificationButtonClicked: Global.openActivityCenterPopup()
onAdHocChatButtonClicked: rootStore.openCloseCreateChatView()
- onRevealAddressClicked: openJoinCommunityDialog()
+ onRevealAddressClicked: {
+ Global.openPopup(communityIntroDialogPopup, {
+ communityId: communityData.id,
+ isInvitationPending: joinCommunityView.isInvitationPending,
+ name: communityData.name,
+ introMessage: communityData.introMessage,
+ imageSrc: communityData.image,
+ accessType: communityData.access
+ })
+ }
onInvitationPendingClicked: {
root.rootStore.cancelPendingRequest(communityData.id)
joinCommunityView.isInvitationPending = root.rootStore.isCommunityRequestPending(communityData.id)
}
- onJoined: {
- root.rootStore.requestToJoinCommunityWithAuthentication(communityData.id, root.rootStore.userProfileInst.name)
- }
-
- onCancelMembershipRequest: {
- root.rootStore.cancelPendingRequest(communityData.id)
- joinCommunityView.isInvitationPending = root.rootStore.isCommunityRequestPending(communityData.id)
- }
Connections {
target: root.rootStore.communitiesModuleInst
@@ -85,6 +91,25 @@ StackLayout {
}
}
}
+
+ CommunityIntroDialog {
+ id: communityIntroDialog
+
+ isInvitationPending: joinCommunityView.isInvitationPending
+ name: communityData.name
+ introMessage: communityData.introMessage
+ imageSrc: communityData.image
+ accessType: communityData.access
+
+ onJoined: {
+ root.rootStore.requestToJoinCommunityWithAuthentication(communityData.id, root.rootStore.userProfileInst.name)
+ }
+
+ onCancelMembershipRequest: {
+ root.rootStore.cancelPendingRequest(communityData.id)
+ joinCommunityView.isInvitationPending = root.rootStore.isCommunityRequestPending(communityData.id)
+ }
+ }
}
}
@@ -92,12 +117,26 @@ StackLayout {
id: chatViewComponent
ChatView {
id: chatView
+
+ readonly property var chatItem: root.rootStore.chatCommunitySectionModule
+ readonly property string communityId: root.sectionItemModel.id
+
emojiPopup: root.emojiPopup
stickersPopup: root.stickersPopup
contactsStore: root.contactsStore
rootStore: root.rootStore
createChatPropertiesStore: root.createChatPropertiesStore
sectionItemModel: root.sectionItemModel
+ amIMember: chatItem.amIMember
+ amISectionAdmin: root.sectionItemModel.memberRole === Constants.memberRole.owner ||
+ root.sectionItemModel.memberRole === Constants.memberRole.admin
+ hasViewOnlyPermissions: root.permissionsStore.viewOnlyPermissionsModel.count > 0
+ hasViewAndPostPermissions: root.permissionsStore.viewAndPostPermissionsModel.count > 0
+ viewOnlyPermissionsModel: root.permissionsStore.viewOnlyPermissionsModel
+ viewAndPostPermissionsModel: root.permissionsStore.viewAndPostPermissionsModel
+ assetsModel: root.rootStore.assetsModel
+ collectiblesModel: root.rootStore.collectiblesModel
+ isInvitationPending: root.rootStore.isCommunityRequestPending(root.sectionItemModel.id)
onCommunityInfoButtonClicked: root.currentIndex = 1
onCommunityManageButtonClicked: root.currentIndex = 1
@@ -108,6 +147,20 @@ StackLayout {
onOpenAppSearch: {
root.openAppSearch()
}
+ onRevealAddressClicked: {
+ Global.openPopup(communityIntroDialogPopup, {
+ communityId: root.sectionItemModel.id,
+ isInvitationPending: root.rootStore.isCommunityRequestPending(root.sectionItemModel.id),
+ name: root.sectionItemModel.name,
+ introMessage: root.sectionItemModel.introMessage,
+ imageSrc: root.sectionItemModel.image,
+ accessType: root.sectionItemModel.access
+ })
+ }
+ onInvitationPendingClicked: {
+ root.rootStore.cancelPendingRequest(root.sectionItemModel.id)
+ chatView.isInvitationPending = root.rootStore.isCommunityRequestPending(root.sectionItemModel.id)
+ }
}
}
@@ -134,4 +187,37 @@ StackLayout {
}
}
}
+
+ Component {
+ id: communityIntroDialogPopup
+ CommunityIntroDialog {
+ id: communityIntroDialog
+
+ property string communityId
+
+ onJoined: {
+ root.rootStore.requestToJoinCommunityWithAuthentication(communityIntroDialog.communityId, root.rootStore.userProfileInst.name)
+ }
+
+ onCancelMembershipRequest: {
+ root.rootStore.cancelPendingRequest(communityIntroDialog.communityId)
+ mainViewLoader.item.isInvitationPending = root.rootStore.isCommunityRequestPending(communityIntroDialog.communityId)
+ }
+
+ onClosed: {
+ destroy()
+ }
+ }
+ }
+
+ Connections {
+ target: root.rootStore
+ enabled: mainViewLoader.item
+ function onCommunityAccessRequested(communityId: string) {
+ if (communityId === mainViewLoader.item.communityId) {
+ mainViewLoader.item.isInvitationPending = root.rootStore.isCommunityRequestPending(communityId)
+ }
+ }
+ }
+
}
diff --git a/ui/app/AppLayouts/Chat/controls/community/PermissionTypes.qml b/ui/app/AppLayouts/Chat/controls/community/PermissionTypes.qml
index 02a017f5a1..d7a051c91f 100644
--- a/ui/app/AppLayouts/Chat/controls/community/PermissionTypes.qml
+++ b/ui/app/AppLayouts/Chat/controls/community/PermissionTypes.qml
@@ -6,7 +6,7 @@ import StatusQ.Core.Theme 0.1
QtObject {
enum Type {
- None, Admin, Member, Moderator, ViewAndPost, Read
+ None, Admin, Member, Read, ViewAndPost
}
function getName(type) {
diff --git a/ui/app/AppLayouts/Chat/controls/community/PermissionsDropdown.qml b/ui/app/AppLayouts/Chat/controls/community/PermissionsDropdown.qml
index a58e01e7ae..9b5abf8ade 100644
--- a/ui/app/AppLayouts/Chat/controls/community/PermissionsDropdown.qml
+++ b/ui/app/AppLayouts/Chat/controls/community/PermissionsDropdown.qml
@@ -112,9 +112,6 @@ StatusDropdown {
Layout.fillWidth: true
}
- // TODO: Channel-level permissions are temporarily hidden until they are
- // supported by the backend. Uncomment when backend functionality is ready.
- /*
CustomSeparator {
Layout.fillWidth: true
Layout.preferredHeight: d.sectionHeight
@@ -122,12 +119,6 @@ StatusDropdown {
text: qsTr("Channels")
}
- CustomPermissionListItem {
- permissionType: PermissionTypes.Type.Moderator
-
- Layout.fillWidth: true
- }
-
CustomPermissionListItem {
permissionType: PermissionTypes.Type.ViewAndPost
@@ -139,7 +130,6 @@ StatusDropdown {
Layout.fillWidth: true
}
- */
Separator {
visible: !!group.checkedButton
diff --git a/ui/app/AppLayouts/Chat/panels/communities/CommunityPermissionsSettingsPanel.qml b/ui/app/AppLayouts/Chat/panels/communities/CommunityPermissionsSettingsPanel.qml
index 7e16258456..b33a502b02 100644
--- a/ui/app/AppLayouts/Chat/panels/communities/CommunityPermissionsSettingsPanel.qml
+++ b/ui/app/AppLayouts/Chat/panels/communities/CommunityPermissionsSettingsPanel.qml
@@ -21,10 +21,6 @@ SettingsPageLayout {
property int viewWidth: 560 // by design
- // TODO: temporary property, to be removed when no need to hide the switch
- // in the app
- property bool showWhoHoldsSwitch: false
-
signal createPermissionRequested(
int permissionType, var holdings, var channels, bool isPrivate)
@@ -182,8 +178,6 @@ SettingsPageLayout {
holdingsRequired: selectedHoldingsModel ? selectedHoldingsModel.count > 0
: false
- showWhoHoldsSwitch: root.showWhoHoldsSwitch
-
permissionDuplicated: {
// dependencies
holdingsTracker.revision
diff --git a/ui/app/AppLayouts/Chat/panels/communities/JoinCommunityCenterPanel.qml b/ui/app/AppLayouts/Chat/panels/communities/JoinCommunityCenterPanel.qml
new file mode 100644
index 0000000000..22f7062d01
--- /dev/null
+++ b/ui/app/AppLayouts/Chat/panels/communities/JoinCommunityCenterPanel.qml
@@ -0,0 +1,171 @@
+import QtQuick 2.15
+import QtQuick.Layouts 1.15
+import QtGraphicalEffects 1.0
+
+import StatusQ.Core 0.1
+import StatusQ.Core.Theme 0.1
+import StatusQ.Components 0.1
+import StatusQ.Controls 0.1
+import StatusQ.Layout 0.1
+
+ColumnLayout {
+ id: root
+
+ property bool joinCommunity: true // Otherwise it means join channel action
+
+ property string name
+ property string channelName
+
+ property bool isInvitationPending: false
+ property bool isJoinRequestRejected: false
+ property bool requiresRequest: false
+ property alias loginType: overlayPanel.loginType
+
+ property bool requirementsMet: true
+
+ property var communityHoldingsModel
+ property var viewOnlyHoldingsModel
+ property var viewAndPostHoldingsModel
+ property var moderateHoldingsModel
+ property var assetsModel
+ property var collectiblesModel
+
+ property string chatDateTimeText
+ property string listUsersText
+ property var messagesModel
+
+ signal revealAddressClicked
+ signal invitationPendingClicked
+
+ spacing: 0
+
+ // Blur background:
+ Item {
+ Layout.fillWidth: true
+ Layout.preferredHeight: Math.min(
+ centralPanelData.implicitHeight,
+ parent.height - overlayPanel.implicitHeight)
+
+ ColumnLayout {
+ id: centralPanelData
+ width: parent.width
+ layer.enabled: true
+ layer.effect: fastBlur
+
+ StatusBaseText {
+ Layout.alignment: Qt.AlignHCenter
+ Layout.topMargin: 30
+ Layout.bottomMargin: 30
+ text: root.chatDateTimeText
+ font.pixelSize: 13
+ color: Theme.palette.baseColor1
+ }
+
+ RowLayout {
+ Layout.alignment: Qt.AlignHCenter
+
+ StatusBaseText {
+ text: root.listUsersText
+ font.pixelSize: 13
+ }
+
+ StatusBaseText {
+ text: qsTr("joined the channel")
+ font.pixelSize: 13
+ color: Theme.palette.baseColor1
+ }
+ }
+
+ ListView {
+ Layout.fillWidth: true
+ Layout.preferredHeight: childrenRect.height + spacing
+ Layout.topMargin: 16
+ spacing: 16
+ model: root.messagesModel
+ delegate: StatusMessage {
+ width: ListView.view.width
+ timestamp: model.timestamp
+ enabled: false
+ messageDetails: StatusMessageDetails {
+ messageText: model.message
+ contentType: model.contentType
+ sender.displayName: model.senderDisplayName
+ sender.isContact: model.isContact
+ sender.trustIndicator: model.trustIndicator
+ sender.profileImage: StatusProfileImageSettings {
+ width: 40
+ height: 40
+ name: model.profileImage || ""
+ colorId: model.colorId
+ }
+ }
+ }
+ }
+ }
+ }
+
+ // Permissions base information content:
+ Rectangle {
+ id: panelBase
+
+ Layout.fillWidth: true
+ Layout.fillHeight: true
+ color: Theme.palette.statusAppLayout.rightPanelBackgroundColor
+ gradient: Gradient {
+ GradientStop {
+ position: 0.000
+ color: "transparent"
+ }
+ GradientStop {
+ position: 0.180
+ color: panelBase.color
+ }
+ }
+
+ StatusScrollView {
+ anchors.fill: parent
+ padding: 0
+
+ Item {
+ implicitHeight: Math.max(overlayPanel.implicitHeight,
+ panelBase.height)
+ implicitWidth: Math.max(overlayPanel.implicitWidth,
+ panelBase.width)
+
+ JoinPermissionsOverlayPanel {
+ id: overlayPanel
+
+ anchors.centerIn: parent
+
+ topPadding: 2 * bottomPadding
+ joinCommunity: root.joinCommunity
+ requirementsMet: root.requirementsMet
+ isInvitationPending: root.isInvitationPending
+ isJoinRequestRejected: root.isJoinRequestRejected
+ requiresRequest: root.requiresRequest
+ communityName: root.name
+ communityHoldingsModel: root.communityHoldingsModel
+ channelName: root.channelName
+
+ viewOnlyHoldingsModel: root.viewOnlyHoldingsModel
+ viewAndPostHoldingsModel: root.viewAndPostHoldingsModel
+ moderateHoldingsModel: root.moderateHoldingsModel
+ assetsModel: root.assetsModel
+ collectiblesModel: root.collectiblesModel
+
+ onRevealAddressClicked: root.revealAddressClicked()
+ onInvitationPendingClicked: root.invitationPendingClicked()
+ }
+ }
+ }
+ }
+
+ Component {
+ id: fastBlur
+
+ FastBlur {
+ radius: 32
+ transparentBorder: true
+ }
+ }
+}
diff --git a/ui/app/AppLayouts/Chat/panels/communities/JoinCommunityHeaderPanel.qml b/ui/app/AppLayouts/Chat/panels/communities/JoinCommunityHeaderPanel.qml
new file mode 100644
index 0000000000..cbc1dc81fd
--- /dev/null
+++ b/ui/app/AppLayouts/Chat/panels/communities/JoinCommunityHeaderPanel.qml
@@ -0,0 +1,73 @@
+import QtQuick 2.15
+import QtQuick.Layouts 1.15
+import QtGraphicalEffects 1.0
+
+import StatusQ.Core 0.1
+import StatusQ.Core.Theme 0.1
+import StatusQ.Components 0.1
+import StatusQ.Controls 0.1
+
+RowLayout {
+ id: root
+
+ property bool joinCommunity: true // Otherwise it means join channel action
+
+ property color color
+
+ property string name
+ property string channelName
+
+ property string communityDesc
+ property string channelDesc
+
+ spacing: 30
+
+ StatusChatInfoButton {
+ id: headerInfoButton
+ Layout.preferredHeight: parent.height
+ Layout.minimumWidth: 100
+ Layout.fillWidth: true
+ title: root.joinCommunity ? root.name : root.channelName
+ subTitle: root.joinCommunity ? root.communityDesc : root.channelDesc
+ asset.color: root.color
+ enabled: false
+ type: StatusChatInfoButton.Type.CommunityChat
+ layer.enabled: root.joinCommunity // Blured when joining community but not when entering channel
+ layer.effect: fastBlur
+ }
+
+ RowLayout {
+ Layout.preferredHeight: parent.height
+ spacing: 10
+ layer.enabled: true
+ layer.effect: fastBlur
+
+ StatusFlatRoundButton {
+ id: search
+ icon.name: "search"
+ type: StatusFlatRoundButton.Type.Secondary
+ enabled: false
+ }
+
+ StatusFlatRoundButton {
+ icon.name: "group-chat"
+ type: StatusFlatRoundButton.Type.Secondary
+ enabled: false
+ }
+
+ StatusFlatRoundButton {
+ icon.name: "more"
+ type: StatusFlatRoundButton.Type.Secondary
+ enabled: false
+ }
+ }
+
+ Component {
+ id: fastBlur
+
+ FastBlur {
+ radius: 32
+ transparentBorder: true
+ }
+ }
+}
diff --git a/ui/app/AppLayouts/Chat/panels/communities/JoinPermissionsOverlayPanel.qml b/ui/app/AppLayouts/Chat/panels/communities/JoinPermissionsOverlayPanel.qml
index c8a18d731d..920be552b8 100644
--- a/ui/app/AppLayouts/Chat/panels/communities/JoinPermissionsOverlayPanel.qml
+++ b/ui/app/AppLayouts/Chat/panels/communities/JoinPermissionsOverlayPanel.qml
@@ -65,6 +65,38 @@ Control {
if(root.loginType == Constants.LoginType.Password) return "password"
return root.loginType == Constants.LoginType.Biometrics ? "touch-id" : "keycard"
}
+
+ function filterPermissions(model) {
+ return !!model && (model.tokenCriteriaMet || !model.isPrivate)
+ }
+
+ readonly property var communityPermissionsModel: SortFilterProxyModel {
+ sourceModel: root.communityHoldingsModel
+ filters: [
+ ExpressionFilter {
+ expression: d.filterPermissions(model)
+ }
+ ]
+ }
+
+ readonly property var viewOnlyPermissionsModel: SortFilterProxyModel {
+ sourceModel: root.viewOnlyHoldingsModel
+ filters: [
+ ExpressionFilter {
+ expression: d.filterPermissions(model)
+ }
+ ]
+ }
+
+ readonly property var viewAndPostPermissionsModel: SortFilterProxyModel {
+ sourceModel: root.viewAndPostHoldingsModel
+ filters: [
+ ExpressionFilter {
+ expression: d.filterPermissions(model)
+ }
+ ]
+ }
+
}
padding: 35 // default by design
@@ -84,38 +116,46 @@ Control {
}
CustomHoldingsListPanel {
- visible: root.joinCommunity && root.communityHoldingsModel
- introText: qsTr("To join %1 you need to prove that you hold").arg(root.communityName)
- model: root.communityHoldingsModel
+ id: communityRequirements
+
+ visible: root.joinCommunity
+ introText: d.communityPermissionsModel.count > 0 ?
+ qsTr("To join %1 you need to prove that you hold").arg(root.communityName) :
+ qsTr("Sorry, you can't join %1 because it's a private, closed community").arg(root.communityName)
+ model: d.communityPermissionsModel
}
CustomHoldingsListPanel {
- visible: !root.joinCommunity && !!root.viewOnlyHoldingsModel
- introText: qsTr("To only view the %1 channel you need to hold").arg(root.channelName)
- model: root.viewOnlyHoldingsModel
+ visible: !root.joinCommunity && d.viewOnlyPermissionsModel.count > 0
+ introText: root.requiresRequest ?
+ qsTr("To view the #%1 channel you need to join %2 and prove that you hold").arg(root.channelName).arg(root.communityName) :
+ qsTr("To view the #%1 channel you need to hold").arg(root.channelName)
+ model: d.viewOnlyPermissionsModel
}
CustomHoldingsListPanel {
- visible: !root.joinCommunity && !!root.viewAndPostHoldingsModel
- introText: qsTr("To view and post in the %1 channel you need to hold").arg(root.channelName)
- model: root.viewAndPostHoldingsModel
+ visible: !root.joinCommunity && d.viewAndPostPermissionsModel.count > 0
+ introText: root.requiresRequest ?
+ qsTr("To view and post in the #%1 channel you need to join %2 and prove that you hold").arg(root.channelName).arg(root.communityName) :
+ qsTr("To view and post in the #%1 channel you need to hold").arg(root.channelName)
+ model: d.viewAndPostPermissionsModel
}
HoldingsListPanel {
Layout.fillWidth: true
spacing: root.spacing
- visible: !root.joinCommunity && !!root.moderateHoldings
+ visible: !root.joinCommunity && !!d.moderateHoldings
introText: qsTr("To moderate in the %1 channel you need to hold").arg(root.channelName)
- model: root.moderateHoldingsModel
+ model: d.moderateHoldingsModel
}
StatusButton {
Layout.alignment: Qt.AlignHCenter
- visible: !root.showOnlyPanels && !root.isJoinRequestRejected
+ visible: !root.showOnlyPanels && !root.isJoinRequestRejected && root.requiresRequest
text: root.isInvitationPending ? d.getInvitationPendingText() : d.getRevealAddressText()
icon.name: root.isInvitationPending ? "" : d.getRevealAddressIcon()
font.pixelSize: 13
- enabled: root.requirementsMet
+ enabled: root.requirementsMet || d.communityPermissionsModel.count == 0
onClicked: root.isInvitationPending ? root.invitationPendingClicked() : root.revealAddressClicked()
}
diff --git a/ui/app/AppLayouts/Chat/panels/communities/qmldir b/ui/app/AppLayouts/Chat/panels/communities/qmldir
index 30153d6718..7a6b3cc576 100644
--- a/ui/app/AppLayouts/Chat/panels/communities/qmldir
+++ b/ui/app/AppLayouts/Chat/panels/communities/qmldir
@@ -16,3 +16,5 @@ TokenHoldersPanel 1.0 TokenHoldersPanel.qml
TokenHoldersProxyModel 1.0 TokenHoldersProxyModel.qml
WarningPanel 1.0 WarningPanel.qml
ChatPermissionQualificationPanel 1.0 ChatPermissionQualificationPanel.qml
+JoinCommunityCenterPanel 1.0 JoinCommunityCenterPanel.qml
+JoinCommunityHeaderPanel 1.0 JoinCommunityHeaderPanel.qml
diff --git a/ui/app/AppLayouts/Chat/stores/PermissionsStore.qml b/ui/app/AppLayouts/Chat/stores/PermissionsStore.qml
index e5fdc2cdde..f598c81cb4 100644
--- a/ui/app/AppLayouts/Chat/stores/PermissionsStore.qml
+++ b/ui/app/AppLayouts/Chat/stores/PermissionsStore.qml
@@ -1,14 +1,71 @@
import QtQml 2.15
+import SortFilterProxyModel 0.2
+import utils 1.0
+
QtObject {
id: root
required property string activeSectionId
+ required property string activeChannelId
required property var chatCommunitySectionModuleInst
+ // all permissions model
readonly property var permissionsModel:
chatCommunitySectionModuleInst.permissionsModel
+ readonly property var becomeMemberPermissionsModel: SortFilterProxyModel {
+ id: becomeMemberPermissionsModel
+ sourceModel: root.permissionsModel
+ function filterPredicate(modelData) {
+ return (modelData.permissionType == Constants.permissionType.member) &&
+ (modelData.tokenCriteriaMet || !modelData.isPrivate)
+ }
+ filters: [
+ ExpressionFilter {
+ expression: becomeMemberPermissionsModel.filterPredicate(model)
+ }
+ ]
+ }
+
+ readonly property var viewOnlyPermissionsModel: SortFilterProxyModel {
+ id: viewOnlyPermissionsModel
+ sourceModel: root.permissionsModel
+
+ function filterPredicate(modelData) {
+ return (modelData.permissionType == Constants.permissionType.read) &&
+ root.permissionsModel.belongsToChat(modelData.id, root.activeChannelId) &&
+ (modelData.tokenCriteriaMet || !modelData.isPrivate)
+ }
+ filters: [
+ ExpressionFilter {
+ expression: {
+ root.activeChannelId // ensure predicate is re-triggered when activeChannelId changes
+ viewOnlyPermissionsModel.filterPredicate(model)
+ }
+ }
+ ]
+ }
+
+ readonly property var viewAndPostPermissionsModel: SortFilterProxyModel {
+ id: viewAndPostPermissionsModel
+ sourceModel: root.permissionsModel
+ function filterPredicate(modelData) {
+ return (modelData.permissionType == Constants.permissionType.viewAndPost) &&
+ root.permissionsModel.belongsToChat(modelData.id, root.activeChannelId) &&
+ (modelData.tokenCriteriaMet || !modelData.isPrivate)
+
+ }
+ filters: [
+ ExpressionFilter {
+ expression: {
+ root.activeChannelId // ensure predicate is re-triggered when activeChannelId changes
+ viewAndPostPermissionsModel.filterPredicate(model)
+ }
+ }
+ ]
+ }
+
readonly property bool isOwner: false
readonly property bool allTokenRequirementsMet: chatCommunitySectionModuleInst.allTokenRequirementsMet
@@ -33,6 +90,7 @@ QtObject {
root.activeSectionId, key,
permissionType,
JSON.stringify(holdings),
+ channels.map(c => c.key).join(","),
isPrivate)
}
}
diff --git a/ui/app/AppLayouts/Chat/stores/RootStore.qml b/ui/app/AppLayouts/Chat/stores/RootStore.qml
index 9c2e890536..6bd628910f 100644
--- a/ui/app/AppLayouts/Chat/stores/RootStore.qml
+++ b/ui/app/AppLayouts/Chat/stores/RootStore.qml
@@ -16,6 +16,7 @@ QtObject {
readonly property PermissionsStore permissionsStore: PermissionsStore {
activeSectionId: mainModuleInst.activeSection.id
+ activeChannelId: root.currentChatContentModule().chatDetails.id
chatCommunitySectionModuleInst: chatCommunitySectionModule
}
@@ -78,6 +79,8 @@ QtObject {
signal communityInfoAlreadyRequested()
+ signal communityAccessRequested(string communityId)
+
signal goToMembershipRequestsPage()
function setActiveCommunity(communityId) {
@@ -621,6 +624,10 @@ QtObject {
function onCommunityInfoAlreadyRequested() {
root.communityInfoAlreadyRequested()
}
+
+ function onCommunityAccessRequested(communityId) {
+ root.communityAccessRequested(communityId)
+ }
}
readonly property Connections mainModuleInstConnections: Connections {
diff --git a/ui/app/AppLayouts/Chat/views/ChatColumnView.qml b/ui/app/AppLayouts/Chat/views/ChatColumnView.qml
index d9ca18d6a5..d96ef4461a 100644
--- a/ui/app/AppLayouts/Chat/views/ChatColumnView.qml
+++ b/ui/app/AppLayouts/Chat/views/ChatColumnView.qml
@@ -44,10 +44,11 @@ Item {
property int activeChatType: parentModule && parentModule.activeItem.type
property bool stickersLoaded: false
property bool viewAndPostPermissionsSatisfied: true
- property var viewAndPostPermissionsModel
+ property var viewAndPostHoldingsModel
readonly property var contactDetails: rootStore ? rootStore.oneToOneChatContact : null
readonly property bool isUserAdded: !!root.contactDetails && root.contactDetails.isAdded
+ property bool amISectionAdmin: false
signal openStickerPackPopup(string stickerPackId)
@@ -267,8 +268,9 @@ Item {
if (!channelPostRestrictions.visible) {
if (d.activeChatContentModule.chatDetails.blocked)
return qsTr("This user has been blocked.")
- if (!root.rootStore.sectionDetails.joined || root.rootStore.sectionDetails.amIBanned)
+ if (!root.rootStore.sectionDetails.joined || root.rootStore.sectionDetails.amIBanned) {
return qsTr("You need to join this community to send messages")
+ }
if (!root.viewAndPostPermissionsSatisfied) {
return qsTr("Sorry, you don't have the tokens needed to post in this channel.")
}
@@ -355,7 +357,7 @@ Item {
height: chatInput.textInput.height
anchors.left: parent.left
anchors.leftMargin: (2*Style.current.bigPadding)
- visible: (!!root.viewAndPostPermissionsModel && (root.viewAndPostPermissionsModel.count > 0)
+ visible: (!!root.viewAndPostHoldingsModel && (root.viewAndPostHoldingsModel.count > 0)
&& !root.amISectionAdmin)
assetsModel: root.rootStore.assetsModel
collectiblesModel: root.rootStore.collectiblesModel
diff --git a/ui/app/AppLayouts/Chat/views/ChatView.qml b/ui/app/AppLayouts/Chat/views/ChatView.qml
index 6e1cb62e44..4b4ad5c908 100644
--- a/ui/app/AppLayouts/Chat/views/ChatView.qml
+++ b/ui/app/AppLayouts/Chat/views/ChatView.qml
@@ -35,11 +35,51 @@ StatusSectionLayout {
property var stickersPopup
property bool stickersLoaded: false
+ readonly property var chatContentModule: root.rootStore.currentChatContentModule() || null
+ readonly property bool viewOnlyPermissionsSatisfied: chatContentModule.viewOnlyPermissionsSatisfied
+ readonly property bool viewAndPostPermissionsSatisfied: chatContentModule.viewAndPostPermissionsSatisfied
+ property bool hasViewOnlyPermissions: false
+ property bool hasViewAndPostPermissions: false
+ property bool amIMember: false
+ property bool amISectionAdmin: false
+
+ property bool isInvitationPending: false
+
+ property var viewOnlyPermissionsModel
+ property var viewAndPostPermissionsModel
+ property var assetsModel
+ property var collectiblesModel
+
+ readonly property bool contentLocked: {
+ if (!rootStore.chatCommunitySectionModule.isCommunity()) {
+ return false
+ }
+ if (!amIMember) {
+ return hasViewAndPostPermissions || hasViewOnlyPermissions
+ }
+ if (amISectionAdmin) {
+ return false
+ }
+ if (!hasViewAndPostPermissions && hasViewOnlyPermissions) {
+ return !viewOnlyPermissionsSatisfied
+ }
+ if (hasViewAndPostPermissions && !hasViewOnlyPermissions) {
+ return !viewAndPostPermissionsSatisfied
+ }
+ if (hasViewOnlyPermissions && hasViewAndPostPermissions) {
+ return !viewOnlyPermissionsSatisfied && !viewAndPostPermissionsSatisfied
+ }
+ return false
+ }
+
signal communityInfoButtonClicked()
signal communityManageButtonClicked()
signal profileButtonClicked()
signal openAppSearch()
+ signal revealAddressClicked
+ signal invitationPendingClicked
+
Connections {
target: root.rootStore.stickersStore.stickersModule
@@ -61,12 +101,9 @@ StatusSectionLayout {
notificationCount: activityCenterStore.unreadNotificationsCount
hasUnseenNotifications: activityCenterStore.hasUnseenNotifications
- headerContent: ChatHeaderContentView {
- id: headerContent
- visible: !!root.rootStore.currentChatContentModule()
- rootStore: root.rootStore
- emojiPopup: root.emojiPopup
- onSearchButtonClicked: root.openAppSearch()
+ headerContent: Loader {
+ id: headerContentLoader
+ sourceComponent: root.contentLocked ? joinCommunityHeaderPanelComponent : chatHeaderContentViewComponent
}
leftPanel: Loader {
@@ -76,22 +113,16 @@ StatusSectionLayout {
contactsColumnComponent
}
- centerPanel: ChatColumnView {
- id: chatColumn
+ centerPanel: Loader {
anchors.fill: parent
- parentModule: root.rootStore.chatCommunitySectionModule
- rootStore: root.rootStore
- createChatPropertiesStore: root.createChatPropertiesStore
- contactsStore: root.contactsStore
- stickersLoaded: root.stickersLoaded
- emojiPopup: root.emojiPopup
- stickersPopup: root.stickersPopup
- onOpenStickerPackPopup: {
- Global.openPopup(statusStickerPackClickPopup, {packId: stickerPackId, store: root.stickersPopup.store} )
- }
+ sourceComponent: root.contentLocked ? joinCommunityCenterPanelComponent : chatColumnViewComponent
}
showRightPanel: {
+ if (root.contentLocked) {
+ return false
+ }
+
if (root.rootStore.openCreateChat ||
!localAccountSensitiveSettings.showOnlineUsers ||
!localAccountSensitiveSettings.expandUsersList) {
@@ -123,6 +154,67 @@ StatusSectionLayout {
}
}
+ Component {
+ id: chatHeaderContentViewComponent
+ ChatHeaderContentView {
+ visible: !!root.rootStore.currentChatContentModule()
+ rootStore: root.rootStore
+ emojiPopup: root.emojiPopup
+ onSearchButtonClicked: root.openAppSearch()
+ }
+ }
+
+ Component {
+ id: joinCommunityHeaderPanelComponent
+ JoinCommunityHeaderPanel {
+ readonly property var chatContentModule: root.rootStore.currentChatContentModule() || null
+ joinCommunity: false
+ color: chatContentModule.chatDetails.color
+ channelName: chatContentModule.chatDetails.name
+ channelDesc: chatContentModule.chatDetails.description
+ }
+ }
+
+ Component {
+ id: chatColumnViewComponent
+
+ ChatColumnView {
+ parentModule: root.rootStore.chatCommunitySectionModule
+ rootStore: root.rootStore
+ createChatPropertiesStore: root.createChatPropertiesStore
+ contactsStore: root.contactsStore
+ stickersLoaded: root.stickersLoaded
+ emojiPopup: root.emojiPopup
+ stickersPopup: root.stickersPopup
+ viewAndPostHoldingsModel: root.viewAndPostPermissionsModel
+ viewAndPostPermissionsSatisfied: !root.rootStore.chatCommunitySectionModule.isCommunity() || root.amISectionAdmin || root.viewAndPostPermissionsSatisfied
+ amISectionAdmin: root.amISectionAdmin
+ onOpenStickerPackPopup: {
+ Global.openPopup(statusStickerPackClickPopup, {packId: stickerPackId, store: root.stickersPopup.store} )
+ }
+ }
+ }
+
+ Component {
+ id: joinCommunityCenterPanelComponent
+
+ JoinCommunityCenterPanel {
+ joinCommunity: false
+ name: sectionItemModel.name
+ channelName: root.chatContentModule.chatDetails.name
+ viewOnlyHoldingsModel: root.viewOnlyPermissionsModel
+ viewAndPostHoldingsModel: root.viewAndPostPermissionsModel
+ assetsModel: root.assetsModel
+ collectiblesModel: root.collectiblesModel
+ isInvitationPending: root.isInvitationPending
+ requiresRequest: !root.amIMember
+ requirementsMet: (viewOnlyPermissionsSatisfied && viewOnlyPermissionsModel.count > 0) ||
+ (viewAndPostPermissionsSatisfied && viewAndPostPermissionsModel.count > 0)
+ onRevealAddressClicked: root.revealAddressClicked()
+ onInvitationPendingClicked: root.invitationPendingClicked()
+ }
+ }
+
Component {
id: contactsColumnComponent
ContactsColumnView {
@@ -138,7 +230,9 @@ StatusSectionLayout {
root.openAppSearch()
}
onAddRemoveGroupMemberClicked: {
- headerContent.addRemoveGroupMember()
+ if (headerContentLoader.item && headerContentLoader.item instanceof ChatHeaderContentView) {
+ headerContentLoader.item.addRemoveGroupMember()
+ }
}
}
}
diff --git a/ui/app/AppLayouts/Chat/views/communities/CommunityNewPermissionView.qml b/ui/app/AppLayouts/Chat/views/communities/CommunityNewPermissionView.qml
index ab877179df..8d23a9f929 100644
--- a/ui/app/AppLayouts/Chat/views/communities/CommunityNewPermissionView.qml
+++ b/ui/app/AppLayouts/Chat/views/communities/CommunityNewPermissionView.qml
@@ -29,10 +29,6 @@ StatusScrollView {
property int viewWidth: 560 // by design
property bool isEditState: false
- // TODO: temporary property, to be removed when no need to hide the switch
- // in the app
- property bool showWhoHoldsSwitch: false
-
readonly property bool dirty:
root.holdingsRequired !== d.dirtyValues.holdingsRequired ||
(d.dirtyValues.holdingsRequired && !holdingsModelComparator.equal) ||
@@ -221,8 +217,6 @@ StatusScrollView {
children: StatusSwitch {
id: whoHoldsSwitch
- visible: root.showWhoHoldsSwitch
-
padding: 0
anchors.right: parent.right
anchors.top: parent.top
diff --git a/ui/app/AppLayouts/Chat/views/communities/JoinCommunityView.qml b/ui/app/AppLayouts/Chat/views/communities/JoinCommunityView.qml
index 7bc602c075..9c0beed7e1 100644
--- a/ui/app/AppLayouts/Chat/views/communities/JoinCommunityView.qml
+++ b/ui/app/AppLayouts/Chat/views/communities/JoinCommunityView.qml
@@ -36,7 +36,7 @@ StatusSectionLayout {
property bool requirementsMet: true
property bool isJoinRequestRejected: false
property bool requiresRequest: false
- property alias loginType: overlayPanel.loginType
+ property alias loginType: joinCommunityCenterPanel.loginType
property var communityHoldingsModel
property var viewOnlyHoldingsModel
@@ -57,12 +57,7 @@ StatusSectionLayout {
signal adHocChatButtonClicked
signal revealAddressClicked
signal invitationPendingClicked
- signal joined
- signal cancelMembershipRequest
- function openJoinCommunityDialog() {
- joinCommunityDialog.open()
- }
QtObject {
id: d
@@ -70,50 +65,13 @@ StatusSectionLayout {
readonly property int blurryRadius: 32
}
- // Blur background:
- headerContent: RowLayout {
- anchors.fill: parent
- spacing: 30
-
- StatusChatInfoButton {
- id: headerInfoButton
- Layout.preferredHeight: parent.height
- Layout.minimumWidth: 100
- Layout.fillWidth: true
- title: root.joinCommunity ? root.name : root.channelName
- subTitle: root.joinCommunity ? root.communityDesc : root.channelDesc
- asset.color: root.color
- enabled: false
- type: StatusChatInfoButton.Type.CommunityChat
- layer.enabled: root.joinCommunity // Blured when joining community but not when entering channel
- layer.effect: fastBlur
- }
-
- RowLayout {
- Layout.preferredHeight: parent.height
- spacing: 10
- layer.enabled: true
- layer.effect: fastBlur
-
- StatusFlatRoundButton {
- id: search
- icon.name: "search"
- type: StatusFlatRoundButton.Type.Secondary
- enabled: false
- }
-
- StatusFlatRoundButton {
- icon.name: "group-chat"
- type: StatusFlatRoundButton.Type.Secondary
- enabled: false
- }
-
- StatusFlatRoundButton {
- icon.name: "more"
- type: StatusFlatRoundButton.Type.Secondary
- enabled: false
- }
- }
+ headerContent: JoinCommunityHeaderPanel {
+ joinCommunity: root.joinCommunity
+ color: root.color
+ name: root.name
+ channelName: root.channelName
+ communityDesc: root.communityDesc
+ channelDesc: root.channelDesc
}
// Blur background:
@@ -135,7 +93,7 @@ StatusSectionLayout {
ColumnLayout {
Layout.fillWidth: true
Layout.margins: Style.current.halfPadding
- layer.enabled: true
+ layer.enabled: root.joinCommunity
layer.effect: fastBlur
Repeater {
@@ -160,127 +118,36 @@ StatusSectionLayout {
}
// Blur background + Permissions base information content:
- centerPanel: ColumnLayout {
+ centerPanel: JoinCommunityCenterPanel {
+ id: joinCommunityCenterPanel
+
anchors.fill: parent
- spacing: 0
- // Blur background:
- Item {
- Layout.fillWidth: true
- Layout.preferredHeight: Math.min(centralPanelData.implicitHeight, parent.height - overlayPanel.implicitHeight)
+ joinCommunity: root.joinCommunity // Otherwise it means join channel action
- ColumnLayout {
- id: centralPanelData
- width: parent.width
- layer.enabled: true
- layer.effect: fastBlur
+ name: root.name
+ channelName: root.channelName
- StatusBaseText {
- Layout.alignment: Qt.AlignHCenter
- Layout.topMargin: 30
- Layout.bottomMargin: 30
- text: root.chatDateTimeText
- font.pixelSize: 13
- color: Theme.palette.baseColor1
- }
+ isInvitationPending: root.isInvitationPending
+ isJoinRequestRejected: root.isJoinRequestRejected
+ requiresRequest: root.requiresRequest
+ requirementsMet: root.requirementsMet
- RowLayout {
- Layout.alignment: Qt.AlignHCenter
+ communityHoldingsModel: root.communityHoldingsModel
+ viewOnlyHoldingsModel: root.viewOnlyHoldingsModel
+ viewAndPostHoldingsModel: root.viewAndPostHoldingsModel
+ moderateHoldingsModel: root.moderateHoldingsModel
+ assetsModel: root.assetsModel
+ collectiblesModel: root.collectiblesModel
- StatusBaseText {
- text: root.listUsersText
- font.pixelSize: 13
- }
+ chatDateTimeText: root.chatDateTimeText
+ listUsersText: root.listUsersText
+ messagesModel: root.messagesModel
- StatusBaseText {
- text: qsTr("joined the channel")
- font.pixelSize: 13
- color: Theme.palette.baseColor1
- }
- }
-
- ListView {
- Layout.fillWidth: true
- Layout.preferredHeight: childrenRect.height + spacing
- Layout.topMargin: 16
- spacing: 16
- model: root.messagesModel
- delegate: StatusMessage {
- width: ListView.view.width
- timestamp: model.timestamp
- enabled: false
- messageDetails: StatusMessageDetails {
- messageText: model.message
- contentType: model.contentType
- sender.displayName: model.senderDisplayName
- sender.isContact: model.isContact
- sender.trustIndicator: model.trustIndicator
- sender.profileImage: StatusProfileImageSettings {
- width: 40
- height: 40
- name: model.profileImage || ""
- colorId: model.colorId
- }
- }
- }
- }
- }
- }
-
- // Permissions base information content:
- Rectangle {
- id: panelBase
-
- Layout.fillWidth: true
- Layout.fillHeight: true
- color: Theme.palette.statusAppLayout.rightPanelBackgroundColor
- gradient: Gradient {
- GradientStop {
- position: 0.000
- color: "transparent"
- }
- GradientStop {
- position: 0.180
- color: panelBase.color
- }
- }
-
- StatusScrollView {
- anchors.fill: parent
- padding: 0
-
- Item {
- implicitHeight: Math.max(overlayPanel.implicitHeight, panelBase.height)
- implicitWidth: Math.max(overlayPanel.implicitWidth, panelBase.width)
-
- JoinPermissionsOverlayPanel {
- id: overlayPanel
-
- anchors.centerIn: parent
-
- topPadding: 2 * bottomPadding
- joinCommunity: root.joinCommunity
- requirementsMet: root.requirementsMet
- isInvitationPending: root.isInvitationPending
- isJoinRequestRejected: root.isJoinRequestRejected
- requiresRequest: root.requiresRequest
- communityName: root.name
- communityHoldingsModel: root.communityHoldingsModel
- channelName: root.channelName
-
- viewOnlyHoldingsModel: root.viewOnlyHoldingsModel
- viewAndPostHoldingsModel: root.viewAndPostHoldingsModel
- moderateHoldingsModel: root.moderateHoldingsModel
- assetsModel: root.assetsModel
- collectiblesModel: root.collectiblesModel
-
- onRevealAddressClicked: root.revealAddressClicked()
- onInvitationPendingClicked: root.invitationPendingClicked()
- }
- }
- }
- }
+ onRevealAddressClicked: root.revealAddressClicked()
+ onInvitationPendingClicked: root.invitationPendingClicked()
}
+
showRightPanel: false
Component {
@@ -291,17 +158,4 @@ StatusSectionLayout {
transparentBorder: true
}
}
-
- CommunityIntroDialog {
- id: joinCommunityDialog
-
- name: root.name
- introMessage: root.introMessage
- imageSrc: root.image
- accessType: root.accessType
- isInvitationPending: root.isInvitationPending
-
- onJoined: root.joined()
- onCancelMembershipRequest: root.cancelMembershipRequest()
- }
}
diff --git a/ui/imports/utils/Constants.qml b/ui/imports/utils/Constants.qml
index 0c296123dd..613864bf92 100644
--- a/ui/imports/utils/Constants.qml
+++ b/ui/imports/utils/Constants.qml
@@ -404,6 +404,14 @@ QtObject {
readonly property int admin: 4
}
+ readonly property QtObject permissionType: QtObject{
+ readonly property int none: 0
+ readonly property int admin: 1
+ readonly property int member: 2
+ readonly property int read: 3
+ readonly property int viewAndPost: 4
+ }
+
readonly property QtObject messageContentType: QtObject {
readonly property int newMessagesMarker: -3
readonly property int fetchMoreMessagesButton: -2
diff --git a/vendor/status-go b/vendor/status-go
index a46bf97bf3..bf64f97d5a 160000
--- a/vendor/status-go
+++ b/vendor/status-go
@@ -1 +1 @@
-Subproject commit a46bf97bf3f46b07d1f447732947011e20fa499f
+Subproject commit bf64f97d5a2bcb1b5fb6b134dda69994e0ddd2bb