feat: channel permissions
Closes: #10996, #10995, #10993, #10997, #9537
This commit is contained in:
parent
3e0a01883f
commit
b3329d790e
|
@ -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")
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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())
|
||||
|
|
|
@ -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")
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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()
|
||||
|
||||
|
@ -476,6 +493,10 @@ method activeItemSet*(self: Module, itemId: string) =
|
|||
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
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
)
|
||||
|
|
|
@ -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
|
||||
])
|
||||
|
|
|
@ -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,
|
||||
})
|
||||
|
|
|
@ -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()
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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
|
||||
}])
|
||||
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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()
|
||||
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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 <b>%1</b> 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 <b>%1</b> you need to prove that you hold").arg(root.communityName) :
|
||||
qsTr("Sorry, you can't join <b>%1</b> 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 <b>%1</b> 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 #<b>%1</b> channel you need to join <b>%2</b> and prove that you hold").arg(root.channelName).arg(root.communityName) :
|
||||
qsTr("To view the #<b>%1</b> 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 <b>%1</b> 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 #<b>%1</b> channel you need to join <b>%2</b> and prove that you hold").arg(root.channelName).arg(root.communityName) :
|
||||
qsTr("To view and post in the #<b>%1</b> 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 <b>%1</b> 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()
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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()
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -1 +1 @@
|
|||
Subproject commit a46bf97bf3f46b07d1f447732947011e20fa499f
|
||||
Subproject commit bf64f97d5a2bcb1b5fb6b134dda69994e0ddd2bb
|
Loading…
Reference in New Issue