feat(desktop/chat): Updated create new chat/group flow

As per new designs

Closes #4781
This commit is contained in:
Alexandra Betouni 2022-02-15 23:00:05 +02:00 committed by Iuri Matias
parent 35bd8fb4ea
commit 8cab96fd24
19 changed files with 735 additions and 276 deletions

View File

@ -256,8 +256,8 @@ method getTransactionDetails*(self: Controller, message: MessageDto): (string,st
method getWalletAccounts*(self: Controller): seq[wallet_account_service.WalletAccountDto] =
return self.messageService.getWalletAccounts()
method joinGroupChat*(self: Controller) =
self.chatService.confirmJoiningGroup(self.chatId)
method joinGroupChat*(self: Controller, communityID: string, chatID: string) =
self.chatService.confirmJoiningGroup(communityID, self.chatId)
method leaveChat*(self: Controller) =
self.chatService.leaveChat(self.chatId)

View File

@ -173,7 +173,7 @@ method init*(self: Controller) =
let args = ChatExtArgs(e)
if (self.isCommunitySection):
return
self.delegate.createOneToOneChat(args.chatId, args.ensName)
self.delegate.createOneToOneChat(args.communityId, args.chatId, args.ensName)
self.events.on(SignalType.HistoryRequestStarted.event) do(e: Args):
self.delegate.setLoadingHistoryMessagesInProgress(true)
@ -238,8 +238,8 @@ method createPublicChat*(self: Controller, chatId: string) =
self.delegate.addNewChat(response.chatDto, false, self.events, self.settingsService, self.contactService, self.chatService,
self.communityService, self.messageService, self.gifService, self.mailserversService)
method createOneToOneChat*(self: Controller, chatId: string, ensName: string) =
let response = self.chatService.createOneToOneChat(chatId, ensName)
method createOneToOneChat*(self: Controller, communityID: string, chatId: string, ensName: string) =
let response = self.chatService.createOneToOneChat(communityID, chatId, ensName)
if(response.success):
self.delegate.addNewChat(response.chatDto, false, self.events, self.settingsService, self.contactService, self.chatService,
self.communityService, self.messageService, self.gifService, self.mailserversService)
@ -280,26 +280,26 @@ method rejectContactRequest*(self: Controller, publicKey: string) =
method blockContact*(self: Controller, publicKey: string) =
self.contactService.blockContact(publicKey)
method addGroupMembers*(self: Controller, chatId: string, pubKeys: seq[string]) =
self.chatService.addGroupMembers(chatId, pubKeys)
method addGroupMembers*(self: Controller, communityID: string, chatId: string, pubKeys: seq[string]) =
self.chatService.addGroupMembers(communityID, chatId, pubKeys)
method removeMemberFromGroupChat*(self: Controller, chatId: string, pubKey: string) =
self.chatService.removeMemberFromGroupChat(chatId, pubKey)
method removeMemberFromGroupChat*(self: Controller, communityID: string, chatId: string, pubKey: string) =
self.chatService.removeMemberFromGroupChat(communityID, chatId, pubKey)
method renameGroupChat*(self: Controller, chatId: string, newName: string) =
self.chatService.renameGroupChat(chatId, newName)
method renameGroupChat*(self: Controller, communityID: string, chatId: string, newName: string) =
self.chatService.renameGroupChat(communityID, chatId, newName)
method makeAdmin*(self: Controller, chatId: string, pubKey: string) =
self.chatService.makeAdmin(chatId, pubKey)
method makeAdmin*(self: Controller, communityID: string, chatId: string, pubKey: string) =
self.chatService.makeAdmin(communityID, chatId, pubKey)
method createGroupChat*(self: Controller, groupName: string, pubKeys: seq[string]) =
let response = self.chatService.createGroupChat(groupName, pubKeys)
method createGroupChat*(self: Controller, communityID: string, groupName: string, pubKeys: seq[string]) =
let response = self.chatService.createGroupChat(communityID, groupName, pubKeys)
if(response.success):
self.delegate.addNewChat(response.chatDto, false, self.events, self.settingsService, self.contactService, self.chatService,
self.communityService, self.messageService, self.gifService, self.mailserversService)
method joinGroup*(self: Controller) =
self.chatService.confirmJoiningGroup(self.getActiveChatId())
method confirmJoiningGroup*(self: Controller, communityID: string, chatID: string) =
self.chatService.confirmJoiningGroup(communityID, self.getActiveChatId())
method joinGroupChatFromInvitation*(self: Controller, groupName: string, chatId: string, adminPK: string) =
let response = self.chatService.createGroupChatFromInvitation(groupName, chatId, adminPK)
@ -388,4 +388,4 @@ method reorderCommunityChat*(self: Controller, categoryId: string, chatId: strin
self.communityService.reorderCommunityChat(self.sectionId, categoryId, chatId, position)
method getRenderedText*(self: Controller, parsedTextArray: seq[ParsedText]): string =
return self.messageService.getRenderedText(parsedTextArray)
return self.messageService.getRenderedText(parsedTextArray)

View File

@ -53,7 +53,7 @@ method getOneToOneChatNameAndImage*(self: AccessInterface, chatId: string):
method createPublicChat*(self: AccessInterface, chatId: string) {.base.} =
raise newException(ValueError, "No implementation available")
method createOneToOneChat*(self: AccessInterface, chatId: string, ensName: string) {.base.} =
method createOneToOneChat*(self: AccessInterface, communityID: string, chatId: string, ensName: string) {.base.} =
raise newException(ValueError, "No implementation available")
method switchToOrCreateOneToOneChat*(self: AccessInterface, chatId: string, ensName: string) {.base.} =
@ -92,19 +92,19 @@ method rejectContactRequest*(self: AccessInterface, publicKey: string): void {.b
method blockContact*(self: AccessInterface, publicKey: string): void {.base.} =
raise newException(ValueError, "No implementation available")
method addGroupMembers*(self: AccessInterface, chatId: string, pubKeys: seq[string]) {.base.} =
method addGroupMembers*(self: AccessInterface, communityID: string, chatId: string, pubKeys: seq[string]) {.base.} =
raise newException(ValueError, "No implementation available")
method removeMemberFromGroupChat*(self: AccessInterface, chatId: string, pubKey: string) {.base.} =
method removeMemberFromGroupChat*(self: AccessInterface, communityID: string, chatId: string, pubKey: string) {.base.} =
raise newException(ValueError, "No implementation available")
method renameGroupChat*(self: AccessInterface, chatId: string, newName: string) {.base.} =
method renameGroupChat*(self: AccessInterface, communityID: string, chatId: string, newName: string) {.base.} =
raise newException(ValueError, "No implementation available")
method makeAdmin*(self: AccessInterface, chatId: string, pubKey: string) {.base.} =
method makeAdmin*(self: AccessInterface, communityID: string, chatId: string, pubKey: string) {.base.} =
raise newException(ValueError, "No implementation available")
method createGroupChat*(self: AccessInterface, groupName: string, pubKeys: seq[string]) {.base.} =
method createGroupChat*(self: AccessInterface, communityID: string, groupName: string, pubKeys: seq[string]) {.base.} =
raise newException(ValueError, "No implementation available")
method joinGroup*(self: AccessInterface) {.base.} =

View File

@ -554,7 +554,7 @@ method onCommunityChannelEdited*(self: Module, chat: ChatDto) =
return
self.view.chatsModel().updateItemDetails(chat.id, chat.name, chat.description, chat.emoji)
method createOneToOneChat*(self: Module, chatId: string, ensName: string) =
method createOneToOneChat*(self: Module, communityID: string, chatId: string, ensName: string) =
if(self.controller.isCommunity()):
# initiate chat creation in the `Chat` seciton module.
self.controller.switchToOrCreateOneToOneChat(chatId, ensName)
@ -564,7 +564,7 @@ method createOneToOneChat*(self: Module, chatId: string, ensName: string) =
self.setActiveItemSubItem(chatId, "")
return
self.controller.createOneToOneChat(chatId, ensName)
self.controller.createOneToOneChat(communityID, chatId, ensName)
method leaveChat*(self: Module, chatId: string) =
self.controller.leaveChat(chatId)
@ -595,7 +595,7 @@ method getCurrentFleet*(self: Module): string =
method acceptContactRequest*(self: Module, publicKey: string) =
self.controller.addContact(publicKey)
self.createOneToOneChat(publicKey, ensName = "")
self.createOneToOneChat(communityID = "" , publicKey, ensName = "")
method onContactAccepted*(self: Module, publicKey: string) =
self.view.contactRequestsModel().removeItemWithPubKey(publicKey)
@ -664,20 +664,20 @@ method onNewMessagesReceived*(self: Module, chatId: string, unviewedMessagesCoun
singletonInstance.globalEvents.showNormalMessageNotification(contactDetails.displayName, plainText,
self.controller.getMySectionId(), chatId, m.id)
method addGroupMembers*(self: Module, chatId: string, pubKeys: string) =
self.controller.addGroupMembers(chatId, self.convertPubKeysToJson(pubKeys))
method addGroupMembers*(self: Module, communityID: string, chatId: string, pubKeys: string) =
self.controller.addGroupMembers(communityID, chatId, self.convertPubKeysToJson(pubKeys))
method removeMemberFromGroupChat*(self: Module, chatId: string, pubKey: string) =
self.controller.removeMemberFromGroupChat(chatId, pubKey)
method removeMemberFromGroupChat*(self: Module, communityID: string, chatId: string, pubKey: string) =
self.controller.removeMemberFromGroupChat(communityID, chatId, pubKey)
method renameGroupChat*(self: Module, chatId: string, newName: string) =
self.controller.renameGroupChat(chatId, newName)
method renameGroupChat*(self: Module, communityID: string, chatId: string, newName: string) =
self.controller.renameGroupChat(communityID, chatId, newName)
method makeAdmin*(self: Module, chatId: string, pubKey: string) =
self.controller.makeAdmin(chatId, pubKey)
method makeAdmin*(self: Module, communityID: string, chatId: string, pubKey: string) =
self.controller.makeAdmin(communityID, chatId, pubKey)
method createGroupChat*(self: Module, groupName: string, pubKeys: string) =
self.controller.createGroupChat(groupName, self.convertPubKeysToJson(pubKeys))
method createGroupChat*(self: Module, communityID: string, groupName: string, pubKeys: string) =
self.controller.createGroupChat(communityID, groupName, self.convertPubKeysToJson(pubKeys))
method joinGroup*(self: Module) =
self.controller.joinGroup()

View File

@ -18,7 +18,7 @@ method getMySectionId*(self: AccessInterface): string {.base.} =
method createPublicChat*(self: AccessInterface, chatId: string) {.base.} =
raise newException(ValueError, "No implementation available")
method createOneToOneChat*(self: AccessInterface, chatId: string, ensName: string) {.base.} =
method createOneToOneChat*(self: AccessInterface, communityID: string, chatId: string, ensName: string) {.base.} =
raise newException(ValueError, "No implementation available")
method leaveChat*(self: AccessInterface, chatId: string) {.base.} =
@ -60,19 +60,19 @@ method rejectAllContactRequests*(self: AccessInterface) {.base.} =
method blockContact*(self: AccessInterface, publicKey: string) {.base.} =
raise newException(ValueError, "No implementation available")
method addGroupMembers*(self: AccessInterface, chatId: string, pubKeys: string) {.base.} =
method addGroupMembers*(self: AccessInterface, communityID: string, chatId: string, pubKeys: string) {.base.} =
raise newException(ValueError, "No implementation available")
method removeMemberFromGroupChat*(self: AccessInterface, chatId: string, pubKey: string) {.base.} =
method removeMemberFromGroupChat*(self: AccessInterface, communityID: string, chatId: string, pubKey: string) {.base.} =
raise newException(ValueError, "No implementation available")
method renameGroupChat*(self: AccessInterface, chatId: string, newName: string) {.base.} =
method renameGroupChat*(self: AccessInterface, communityID: string, chatId: string, newName: string) {.base.} =
raise newException(ValueError, "No implementation available")
method makeAdmin*(self: AccessInterface, chatId: string, pubKey: string) {.base.} =
method makeAdmin*(self: AccessInterface, communityID: string, chatId: string, pubKey: string) {.base.} =
raise newException(ValueError, "No implementation available")
method createGroupChat*(self: AccessInterface, groupName: string, pubKeys: string) {.base.} =
method createGroupChat*(self: AccessInterface, communityID: string, groupName: string, pubKeys: string) {.base.} =
raise newException(ValueError, "No implementation available")
method joinGroup*(self: AccessInterface) {.base.} =

View File

@ -138,8 +138,8 @@ QtObject:
proc createPublicChat*(self: View, chatId: string) {.slot.} =
self.delegate.createPublicChat(chatId)
proc createOneToOneChat*(self: View, chatId: string, ensName: string) {.slot.} =
self.delegate.createOneToOneChat(chatId, ensName)
proc createOneToOneChat*(self: View, communityID: string, chatId: string, ensName: string) {.slot.} =
self.delegate.createOneToOneChat(communityID, chatId, ensName)
proc leaveChat*(self: View, id: string) {.slot.} =
self.delegate.leaveChat(id)
@ -181,20 +181,20 @@ QtObject:
proc removeCommunityChat*(self: View, chatId: string) {.slot} =
self.delegate.removeCommunityChat(chatId)
proc addGroupMembers*(self: View, chatId: string, pubKeys: string) {.slot.} =
self.delegate.addGroupMembers(chatId, pubKeys)
proc addGroupMembers*(self: View, communityID: string, chatId: string, pubKeys: string) {.slot.} =
self.delegate.addGroupMembers(communityID, chatId, pubKeys)
proc removeMemberFromGroupChat*(self: View, chatId: string, pubKey: string) {.slot.} =
self.delegate.removeMemberFromGroupChat(chatId, pubKey)
proc removeMemberFromGroupChat*(self: View, communityID: string, chatId: string, pubKey: string) {.slot.} =
self.delegate.removeMemberFromGroupChat(communityID, chatId, pubKey)
proc renameGroupChat*(self: View, chatId: string, newName: string) {.slot.} =
self.delegate.renameGroupChat(chatId, newName)
proc renameGroupChat*(self: View, communityID: string, chatId: string, newName: string) {.slot.} =
self.delegate.renameGroupChat(communityID, chatId, newName)
proc makeAdmin*(self: View, chatId: string, pubKey: string) {.slot.} =
self.delegate.makeAdmin(chatId, pubKey)
proc makeAdmin*(self: View, communityID: string, chatId: string, pubKey: string) {.slot.} =
self.delegate.makeAdmin(communityID, chatId, pubKey)
proc createGroupChat*(self: View, groupName: string, pubKeys: string) {.slot.} =
self.delegate.createGroupChat(groupName, pubKeys)
proc createGroupChat*(self: View, communityID: string, groupName: string, pubKeys: string) {.slot.} =
self.delegate.createGroupChat(communityID, groupName, pubKeys)
proc joinGroup*(self: View) {.slot.} =
self.delegate.joinGroup()

View File

@ -5,6 +5,7 @@ import ../message/dto/message as message_dto
import ../activity_center/dto/notification as notification_dto
import ../contacts/service as contact_service
import ../../../backend/chat as status_chat
import ../../../backend/group_chat as status_group_chat
import ../../../backend/chatCommands as status_chat_commands
import ../../../app/global/global_singleton
import ../../../app/core/eventemitter
@ -37,6 +38,7 @@ type
# deletedMessages*: seq[RemovedMessage]
ChatArgs* = ref object of Args
communityId*: string
chatId*: string
ChatExtArgs* = ref object of ChatArgs
@ -196,46 +198,40 @@ QtObject:
return self.contactService.getContactNameAndImage(chatId)
proc createChatFromResponse(self: Service, response: RpcResponse[JsonNode]): tuple[chatDto: ChatDto, success: bool] =
var jsonArr: JsonNode
if (not response.result.getProp("chats", jsonArr)):
var jsonChat: JsonNode
if (not response.result.getProp("chat", jsonChat)):
error "error: response of creating chat doesn't contain created chats"
result.success = false
return
let chats = map(jsonArr.getElems(), proc(x: JsonNode): ChatDto = x.toChatDto())
# created chat is returned as the first elemnt of json array (it's up to `status-go`)
if(chats.len == 0):
error "error: unknown error occured creating chat"
result.success = false
return
result.chatDto = chats[0]
result.chatDto = jsonChat.toChatDto()
self.updateOrAddChat(result.chatDto)
result.success = true
proc createPublicChat*(self: Service, chatId: string): tuple[chatDto: ChatDto, success: bool] =
try:
let response = status_chat.createPublicChat(chatId)
result = self.createChatFromResponse(response)
result.chatDto = response.result.toChatDto()
self.updateOrAddChat(result.chatDto)
result.success = true
except Exception as e:
let errDesription = e.msg
error "error: ", errDesription
return
proc createOneToOneChat*(self: Service, chatId: string, ensName: string): tuple[chatDto: ChatDto, success: bool] =
proc createOneToOneChat*(self: Service, communityID: string, chatId: string, ensName: string): tuple[chatDto: ChatDto, success: bool] =
try:
if self.hasChannel(chatId):
# We want to show the chat to the user and for that we activate the chat
discard status_chat.saveChat(
discard status_group_chat.createOneToOneChat(
communityID,
chatId,
chat_dto.ChatType.OneToOne.int,
color=self.chats[chatId].color,
ensName=ensName)
result.success = true
result.chatDto = self.chats[chatId]
return
let response = status_chat.createOneToOneChat(chatId)
let response = status_group_chat.createOneToOneChat(communityID, chatId, ensName)
result = self.createChatFromResponse(response)
except Exception as e:
let errDesription = e.msg
@ -406,41 +402,41 @@ QtObject:
error "error: ", errDesription
return
method addGroupMembers*(self: Service, chatId: string, pubKeys: seq[string]) =
method addGroupMembers*(self: Service, communityID: string, chatID: string, members: seq[string]) =
try:
let response = status_chat.addGroupMembers(chatId, pubKeys)
let response = status_group_chat.addMembers(communityID, chatId, members)
if (response.error.isNil):
self.events.emit(SIGNAL_CHAT_MEMBERS_ADDED, ChatMembersAddedArgs(chatId: chatId, ids: pubKeys))
self.events.emit(SIGNAL_CHAT_MEMBERS_ADDED, ChatMembersAddedArgs(chatId: chatId, ids: members))
except Exception as e:
error "error while adding group members: ", msg = e.msg
method removeMemberFromGroupChat*(self: Service, chatId: string, pubKey: string) =
method removeMemberFromGroupChat*(self: Service, communityID: string, chatID: string, member: string) =
try:
let response = status_chat.removeMembersFromGroupChat(chatId, pubKey)
let response = status_group_chat.removeMember(communityID, chatId, member)
if (response.error.isNil):
self.events.emit(SIGNAL_CHAT_MEMBER_REMOVED, ChatMemberRemovedArgs(chatId: chatId, id: pubkey))
self.events.emit(SIGNAL_CHAT_MEMBER_REMOVED, ChatMemberRemovedArgs(chatId: chatId, id: member))
except Exception as e:
error "error while removing member from group: ", msg = e.msg
method renameGroupChat*(self: Service, chatId: string, newName: string) =
method renameGroupChat*(self: Service, communityID: string, chatID: string, name: string) =
try:
let response = status_chat.renameGroupChat(chatId, newName)
let response = status_group_chat.renameChat(communityID, chatId, name)
if (not response.error.isNil):
let msg = response.error.message & " chatId=" & chatId
error "error while renaming group chat", msg
return
self.events.emit(SIGNAL_CHAT_RENAMED, ChatRenameArgs(id: chatId, newName: newName))
self.events.emit(SIGNAL_CHAT_RENAMED, ChatRenameArgs(id: chatId, newName: name))
except Exception as e:
error "error while renaming group chat: ", msg = e.msg
method makeAdmin*(self: Service, chatId: string, pubKey: string) =
method makeAdmin*(self: Service, communityID: string, chatID: string, memberId: string) =
try:
let response = status_chat.makeAdmin(chatId, pubKey)
let response = status_group_chat.makeAdmin(communityID, chatId, memberId)
for member in self.chats[chatId].members.mitems:
if (member.id == pubKey):
if (member.id == memberId):
member.admin = true
self.events.emit(
SIGNAL_CHAT_MEMBER_UPDATED,
@ -451,23 +447,23 @@ QtObject:
error "error while making user admin: ", msg = e.msg
method confirmJoiningGroup*(self: Service, chatId: string) =
method confirmJoiningGroup*(self: Service, communityID: string, chatID: string) =
try:
let response = status_chat.confirmJoiningGroup(chatId)
let response = status_group_chat.confirmJoiningGroup(communityID, chatId)
self.emitUpdate(response)
except Exception as e:
error "error while confirmation joining to group: ", msg = e.msg
method createGroupChatFromInvitation*(self: Service, groupName: string, chatId: string, adminPK: string): tuple[chatDto: ChatDto, success: bool] =
try:
let response = status_chat.createGroupChatFromInvitation(groupName, chatId, adminPK)
let response = status_group_chat.createGroupChatFromInvitation(groupName, chatId, adminPK)
result = self.createChatFromResponse(response)
except Exception as e:
error "error while creating group from invitation: ", msg = e.msg
method createGroupChat*(self: Service, groupName: string, pubKeys: seq[string]): tuple[chatDto: ChatDto, success: bool] =
method createGroupChat*(self: Service, communityID: string, name: string, members: seq[string]): tuple[chatDto: ChatDto, success: bool] =
try:
let response = status_chat.createGroupChat(groupName, pubKeys)
let response = status_group_chat.createGroupChat(communityID, name, members)
result = self.createChatFromResponse(response)
except Exception as e:
error "error while creating group chat", msg = e.msg

View File

@ -36,12 +36,14 @@ proc getChats*(): RpcResponse[JsonNode] {.raises: [Exception].} =
result = callPrivateRPC("chats".prefix, payload)
proc createPublicChat*(chatId: string): RpcResponse[JsonNode] {.raises: [Exception].} =
let payload = %* [{"ID": chatId}]
result = callPrivateRPC("createPublicChat".prefix, payload)
let communityId = ""
let payload = %* [communityId, chatId]
result = callPrivateRPC("chat_joinChat", payload)
proc createOneToOneChat*(chatId: string): RpcResponse[JsonNode] {.raises: [Exception].} =
let payload = %* [{"ID": chatId}]
result = callPrivateRPC("createOneToOneChat".prefix, payload)
proc createOneToOneChat*(chatId: string, ensName: string = ""): RpcResponse[JsonNode] {.raises: [Exception].} =
let communityId = ""
let payload = %* [communityId, chatId, ensName]
result = callPrivateRPC("chat_createOneToOneChat", payload)
proc leaveGroupChat*(chatId: string): RpcResponse[JsonNode] {.raises: [Exception].} =
result = callPrivateRPC("leaveGroupChat".prefix, %* [nil, chatId, true])
@ -102,28 +104,28 @@ proc deleteMessagesByChatId*(chatId: string): RpcResponse[JsonNode] {.raises: [E
let payload = %* [chatId]
result = callPrivateRPC("deleteMessagesByChatID".prefix, payload)
proc addGroupMembers*(chatId: string, pubKeys: seq[string]): RpcResponse[JsonNode] {.raises: [Exception].} =
let payload = %* [nil, chatId, pubKeys]
proc addGroupMembers*(communityID: string, chatId: string, pubKeys: seq[string]): RpcResponse[JsonNode] {.raises: [Exception].} =
let payload = %* [nil, communityID, chatId, pubKeys]
result = callPrivateRPC("addMembersToGroupChat".prefix, payload)
proc removeMembersFromGroupChat*(chatId: string, pubKey: string): RpcResponse[JsonNode] {.raises: [Exception].} =
let payload = %* [nil, chatId, pubKey]
proc removeMemberFromGroupChat*(communityID: string, chatId: string, pubKey: string): RpcResponse[JsonNode] {.raises: [Exception].} =
let payload = %* [nil, communityID, chatId, pubKey]
result = callPrivateRPC("removeMemberFromGroupChat".prefix, payload)
proc renameGroupChat*(chatId: string, newName: string): RpcResponse[JsonNode] {.raises: [Exception].} =
let payload = %* [nil, chatId, newName]
proc renameGroupChat*(communityID: string, chatId: string, newName: string): RpcResponse[JsonNode] {.raises: [Exception].} =
let payload = %* [nil, communityID, chatId, newName]
result = callPrivateRPC("changeGroupChatName".prefix, payload)
proc makeAdmin*(chatId: string, pubKey: string): RpcResponse[JsonNode] {.raises: [Exception].} =
let payload = %* [nil, chatId, [pubKey]]
proc makeAdmin*(communityID: string, chatId: string, pubKey: string): RpcResponse[JsonNode] {.raises: [Exception].} =
let payload = %* [nil, communityID, chatId, [pubKey]]
result = callPrivateRPC("addAdminsToGroupChat".prefix, payload)
proc createGroupChat*(groupName: string, pubKeys: seq[string]): RpcResponse[JsonNode] {.raises: [Exception].} =
let payload = %* [nil, groupName, pubKeys]
proc createGroupChat*(communityID: string, groupName: string, pubKeys: seq[string]): RpcResponse[JsonNode] {.raises: [Exception].} =
let payload = %* [nil, communityID, groupName, pubKeys]
result = callPrivateRPC("createGroupChatWithMembers".prefix, payload)
proc confirmJoiningGroup*(chatId: string): RpcResponse[JsonNode] {.raises: [Exception].} =
let payload = %* [chatId]
proc confirmJoiningGroup*(communityID: string, chatId: string): RpcResponse[JsonNode] {.raises: [Exception].} =
let payload = %* [communityID, chatId]
result = callPrivateRPC("confirmJoiningGroup".prefix, payload)
proc createGroupChatFromInvitation*(groupName: string, chatId: string, adminPK: string): RpcResponse[JsonNode] {.raises: [Exception].} =

View File

@ -0,0 +1,70 @@
import json, sequtils, sugar
import core, utils
import response_type
export response_type
proc createOneToOneChat*(communityID: string, id: string, ensName: string): RpcResponse[JsonNode] {.raises: [Exception].} =
let payload = %* [communityID, id, ensName]
return core.callPrivateRPC("chat_createOneToOneChat", payload)
proc createGroupChat*(communityID: string, name: string, members: seq[string]): RpcResponse[JsonNode] {.raises: [Exception].} =
let payload = %* [communityID, name, members]
return core.callPrivateRPC("chat_createGroupChat", payload)
proc createGroupChatFromInvitation*(name: string, chatID: string, adminPK: string): RpcResponse[JsonNode] {.raises: [Exception].} =
let payload = %* [name, chatID, adminPK]
return core.callPrivateRPC("chat_createGroupChatFromInvitation", payload)
proc leaveChat*(communityID: string, chatID: string, remove: bool): RpcResponse[JsonNode] {.raises: [Exception].} =
let payload = %* [communityID, chatID, remove]
return core.callPrivateRPC("chat_leaveChat", payload)
proc addMembers*(communityID: string, chatID: string, members: seq[string]): RpcResponse[JsonNode] {.raises: [Exception].} =
let payload = %* [communityID, chatID, members]
return core.callPrivateRPC("chat_addMembers", payload)
proc removeMember*(communityID: string, chatID: string, member: string): RpcResponse[JsonNode] {.raises: [Exception].} =
let payload = %* [communityID, chatID, member]
return core.callPrivateRPC("chat_removeMember", payload)
proc makeAdmin*(communityID: string, chatID: string, member: string): RpcResponse[JsonNode] {.raises: [Exception].} =
let payload = %* [communityID, chatID, member]
return core.callPrivateRPC("chat_makeAdmin", payload)
proc confirmJoiningGroup*(communityID: string, chatID: string): RpcResponse[JsonNode] {.raises: [Exception].} =
let payload = %* [communityID, chatID]
return core.callPrivateRPC("chat_confirmJoiningGroup", payload)
proc renameChat*(communityID: string, chatID: string, name: string): RpcResponse[JsonNode] {.raises: [Exception].} =
let payload = %* [communityID, chatID, name]
return core.callPrivateRPC("chat_renameChat", payload)
proc sendGroupChatInvitationRequest*(communityID: string, chatID: string, adminPK: string, message: string): RpcResponse[JsonNode] {.raises: [Exception].} =
let payload = %* [communityID, chatID, adminPK, message]
return core.callPrivateRPC("chat_sendGroupChatInvitationRequest", payload)
proc getGroupChatInvitations*(): RpcResponse[JsonNode] {.raises: [Exception].} =
let payload = %* []
return core.callPrivateRPC("chat_getGroupChatInvitations", payload)
proc sendGroupChatInvitationRejection*(invitationRequestID: string): RpcResponse[JsonNode] {.raises: [Exception].} =
let payload = %* [invitationRequestID]
return core.callPrivateRPC("chat_sendGroupChatInvitationRejection", payload)
proc startGroupChat*(communityID: string, name: string, members: seq[string]): RpcResponse[JsonNode] {.raises: [Exception].} =
let payload = %* [communityID, name, members]
return core.callPrivateRPC("chat_startGroupChat", payload)

View File

@ -26,6 +26,9 @@ StatusAppThreePanelLayout {
property var contactsStore
property bool hasAddedContacts: root.contactsStore.myContactsModel.count > 0
// Not Refactored
property var messageStore
property RootStore rootStore: RootStore {
contactsStore: root.contactsStore
}
@ -69,7 +72,11 @@ StatusAppThreePanelLayout {
Global.openPopup(statusStickerPackClickPopup, {packId: stickerPackId} )
}
onOpenAppSearch: {
root.openAppSearch()
root.openAppSearch();
}
CreateChatView {
activeChatId: chatColumn.activeChatId
rootStore: root.rootStore
}
}
@ -180,7 +187,7 @@ StatusAppThreePanelLayout {
}
onCreateOneToOneChat: {
Global.changeAppSectionBySectionType(Constants.appSection.chat)
root.rootStore.chatCommunitySectionModule.createOneToOneChat(chatId, ensName)
root.rootStore.chatCommunitySectionModule.createOneToOneChat(communityId, chatId, ensName)
}
}
}

View File

@ -6,6 +6,13 @@ QtObject {
id: root
property var contactsStore
property bool openCreateChat: false
property bool hideInput: false
property string createChatInitMessage
property var chatTextInput
property var contactsModel: profileSectionModule.contactsModule.myContactsModel
signal addRemoveGroupMember()
signal createChatWithMessage()
// Important:
// Each `ChatLayout` has its own chatCommunitySectionModule
// (on the backend chat and community sections share the same module since they are actually the same)
@ -284,7 +291,7 @@ QtObject {
.arg(isChatKey(pk) ? globalUtils.generateAlias(pk) : ("@" + removeStatusEns(pk)))
result.callback = function () {
if (isChatKey(pk)) {
chatCommunitySectionModule.createOneToOneChat(pk, "")
chatCommunitySectionModule.createOneToOneChat("", pk, "")
} else {
// Not Refactored Yet
// chatsModel.channelView.joinWithENS(pk);

View File

@ -54,7 +54,6 @@ Item {
property bool stickersLoaded: false
property Timer timer: Timer { }
property var userList
property var contactDetails: Utils.getContactDetailsAsJson(root.activeChatId)
property bool isContact: root.contactDetails.isContact
property bool contactRequestReceived: root.contactDetails.requestReceived
@ -211,7 +210,6 @@ Item {
active: false
width: parent.width
height: isActiveChannel ? parent.height : 0
Connections {
id: loaderConnections
target: chatLoader
@ -227,6 +225,9 @@ Item {
sourceComponent: ChatContentView {
width: parent.width
height: parent.height
onHeightChanged: {
}
clip: true
rootStore: root.rootStore
contactsStore: root.contactsStore
@ -240,9 +241,22 @@ Item {
onOpenStickerPackPopup: {
root.openStickerPackPopup(stickerPackId)
}
onIsActiveChannelChanged: {
if (isActiveChannel && root.rootStore.openCreateChat) {
root.rootStore.chatTextInput = textInputField.textInput;
}
}
Component.onCompleted: {
parentModule.prepareChatContentModuleForChatId(model.itemId)
chatContentModule = parentModule.getChatContentModule()
if (root.rootStore.openCreateChat) {
root.rootStore.openCreateChat = false;
if (root.rootStore.createChatInitMessage !== "") {
textInputField.textInput.insert(0, root.rootStore.createChatInitMessage);
root.rootStore.createChatInitMessage = "";
textInputField.sendMessage(Qt.Key_Enter);
}
}
}
}
}

View File

@ -34,6 +34,7 @@ ColumnLayout {
property var contactsStore
property bool isActiveChannel: false
property var emojiPopup
property alias textInputField: chatInput
property UsersStore usersStore: UsersStore {}
onChatContentModuleChanged: {
@ -252,6 +253,15 @@ ColumnLayout {
channelPosition // TODO change this to the signal once it is modifiable
)
}
onAddRemoveGroupMember: {
chatContentRoot.rootStore.addRemoveGroupMember();
}
onFetchMoreMessages: {
chatContentRoot.rootStore.messageStore.requestMoreMessages();
}
onLeaveGroup: {
chatContentModule.leaveChat();
}
}
}
@ -351,7 +361,7 @@ ColumnLayout {
onCreateOneToOneChat: {
Global.changeAppSectionBySectionType(Constants.appSection.chat)
root.rootStore.chatCommunitySectionModule.createOneToOneChat(chatId, ensName)
root.rootStore.chatCommunitySectionModule.createOneToOneChat("", chatId, ensName)
}
}
@ -362,6 +372,7 @@ ColumnLayout {
ChatMessagesView {
id: chatMessages
opacity: !chatContentRoot.rootStore.openCreateChat ? 1.0 : 0.0
Layout.fillWidth: true
Layout.fillHeight: true
store: chatContentRoot.rootStore
@ -393,7 +404,7 @@ ColumnLayout {
Loader {
id: loadingMessagesIndicator
active: chatContentRoot.rootStore.loadingHistoryMessagesInProgress
visible: !chatContentRoot.rootStore.openCreateChat
sourceComponent: LoadingAnimation { }
anchors {
right: parent.right
@ -405,24 +416,27 @@ ColumnLayout {
StatusChatInput {
id: chatInput
store: root.rootStore
store: chatContentRoot.rootStore
usersStore: chatContentRoot.usersStore
visible: {
// Not Refactored Yet
return true
// if (chatContentRoot.rootStore.chatsModelInst.channelView.activeChannel.chatType === Constants.chatType.privateGroupChat) {
// return chatContentRoot.rootStore.chatsModelInst.channelView.activeChannel.isMember
// }
// if (chatContentRoot.rootStore.chatsModelInst.channelView.activeChannel.chatType === Constants.chatType.oneToOne) {
// return isContact
// }
// const community = chatContentRoot.rootStore.chatsModelInst.communities.activeCommunity
// return !community.active ||
// community.access === Constants.communityChatPublicAccess ||
// community.admin ||
// chatContentRoot.rootStore.chatsModelInst.channelView.activeChannel.canPost
if (chatContentRoot.rootStore.openCreateChat && chatContentRoot.rootStore.hideInput) {
return false;
} else {
return true;
// Not Refactored Yet
// if (chatContentRoot.rootStore.chatsModelInst.channelView.activeChannel.chatType === Constants.chatType.privateGroupChat) {
// return chatContentRoot.rootStore.chatsModelInst.channelView.activeChannel.isMember
// }
// if (chatContentRoot.rootStore.chatsModelInst.channelView.activeChannel.chatType === Constants.chatType.oneToOne) {
// return isContact
// }
// const community = chatContentRoot.rootStore.chatsModelInst.communities.activeCommunity
// return !community.active ||
// community.access === Constants.communityChatPublicAccess ||
// community.admin ||
// chatContentRoot.rootStore.chatsModelInst.channelView.activeChannel.canPost
}
}
messageContextMenu: contextmenu
emojiPopup: chatContentRoot.emojiPopup
@ -458,32 +472,40 @@ ColumnLayout {
chatInput.isReply ? SelectedMessage.messageId : "",
packId)
}
onSendMessage: {
if(!chatContentModule) {
console.debug("error on sending message - chat content module is not set")
return
}
if (chatContentRoot.rootStore.openCreateChat) {
chatContentRoot.rootStore.createChatInitMessage = textInput.getText(0, textInput.cursorPosition);
textInput.clear();
chatContentRoot.rootStore.createChatWithMessage();
} else {
if (!chatContentModule) {
console.debug("error on sending message - chat content module is not set")
return
}
if (chatInput.fileUrls.length > 0){
chatContentModule.inputAreaModule.sendImages(JSON.stringify(fileUrls));
}
let msg = globalUtils.plainText(StatusQUtils.Emoji.deparse(chatInput.textInput.text))
if (msg.length > 0) {
msg = chatInput.interpretMessage(msg)
if (chatInput.fileUrls.length > 0){
chatContentModule.inputAreaModule.sendImages(JSON.stringify(fileUrls));
}
let msg = globalUtils.plainText(StatusQUtils.Emoji.deparse(chatInput.textInput.text))
if (msg.length > 0) {
msg = chatInput.interpretMessage(msg)
chatContentModule.inputAreaModule.sendMessage(
msg,
chatInput.isReply ? chatInput.replyMessageId : "",
Utils.isOnlyEmoji(msg) ? Constants.messageContentType.emojiType : Constants.messageContentType.messageType,
false)
chatContentModule.inputAreaModule.sendMessage(
msg,
chatInput.isReply ? chatInput.replyMessageId : "",
Utils.isOnlyEmoji(msg) ? Constants.messageContentType.emojiType : Constants.messageContentType.messageType,
false)
if (event) event.accepted = true
sendMessageSound.stop();
Qt.callLater(sendMessageSound.play);
if (event) event.accepted = true
sendMessageSound.stop();
Qt.callLater(sendMessageSound.play);
chatInput.textInput.clear();
chatInput.textInput.textFormat = TextEdit.PlainText;
chatInput.textInput.textFormat = TextEdit.RichText;
chatInput.textInput.clear();
chatInput.textInput.textFormat = TextEdit.PlainText;
chatInput.textInput.textFormat = TextEdit.RichText;
}
}
}

View File

@ -37,9 +37,12 @@ StatusPopupMenu {
signal downloadMessages(string file)
signal deleteCommunityChat(string chatId)
signal leaveChat(string chatId)
signal leaveGroup(string chatId)
signal createCommunityChannel(string chatId, string newName, string newDescription, string newEmoji)
signal editCommunityChannel(string chatId, string newName, string newDescription, string newEmoji, string newCategory)
signal fetchMoreMessages(int timeFrame)
signal addRemoveGroupMember()
StatusMenuItem {
id: viewProfileMenuItem
@ -49,8 +52,7 @@ StatusPopupMenu {
//% "View Profile"
return qsTrId("view-profile")
case Constants.chatType.privateGroupChat:
//% "View Group"
return qsTrId("view-group")
return qsTr("View Members")
default:
return ""
}
@ -68,6 +70,16 @@ StatusPopupMenu {
}
}
StatusMenuItem {
text: qsTr("Add / remove from group")
icon.name: "notification"
enabled: (root.chatType === Constants.chatType.privateGroupChat &&
amIChatAdmin)
onTriggered: {
root.addRemoveGroupMember();
}
}
StatusMenuSeparator {
visible: viewProfileMenuItem.enabled
}
@ -84,6 +96,21 @@ StatusPopupMenu {
}
}
StatusMenuItem {
text: qsTr("Edit name and image")
icon.name: "edit"
enabled: (root.isCommunityChat ||root.chatType === Constants.chatType.privateGroupChat)
&& root.amIChatAdmin
onTriggered: {
Global.openPopup(editChannelPopup, {
isEdit: true,
channelName: root.chatName,
channelDescription: root.chatDescription,
categoryId: root.chatCategoryId
});
}
}
StatusMenuItem {
text: root.chatMuted ?
//% "Unmute chat"
@ -91,7 +118,6 @@ StatusPopupMenu {
//% "Mute chat"
qsTrId("mute-chat")
icon.name: "notification"
enabled: root.chatType !== Constants.chatType.privateGroupChat
onTriggered: {
if(root.chatMuted)
root.unmuteChat(root.chatId)
@ -104,12 +130,45 @@ StatusPopupMenu {
//% "Mark as Read"
text: qsTrId("mark-as-read")
icon.name: "checkmark-circle"
enabled: root.chatType !== Constants.chatType.privateGroupChat
onTriggered: {
root.markAllMessagesRead(root.chatId)
}
}
//TODO uncomment when implemented
// StatusPopupMenu {
// title: qsTr("Fetch messages")
// enabled: (root.chatType === Constants.chatType.oneToOne ||
// root.chatType === Constants.chatType.privateGroupChat)
// StatusMenuItem {
// text: "Last 24 hours"
// onTriggered: {
// root.fetchMoreMessages();
// }
// }
// StatusMenuItem {
// text: "Last 2 days"
// onTriggered: {
// }
// }
// StatusMenuItem {
// text: "Last 3 days"
// onTriggered: {
// }
// }
// StatusMenuItem {
// text: "Last 7 days"
// onTriggered: {
// }
// }
// }
StatusMenuItem {
//% "Clear history"
text: qsTrId("clear-history")
@ -170,6 +229,9 @@ StatusPopupMenu {
if (root.isCommunityChat) {
return qsTr("Delete Channel")
}
if (root.chatType === Constants.chatType.privateGroupChat) {
return qsTr("Leave group")
}
return root.chatType === Constants.chatType.oneToOne ?
//% "Delete chat"
qsTrId("delete-chat") :
@ -182,7 +244,11 @@ StatusPopupMenu {
type: StatusMenuItem.Type.Danger
onTriggered: {
Global.openPopup(deleteChatConfirmationDialogComponent)
if (root.chatType === Constants.chatType.privateGroupChat) {
root.leaveChat(root.chatId);
} else {
Global.openPopup(deleteChatConfirmationDialogComponent);
}
}
enabled: !root.isCommunityChat || root.amIChatAdmin

View File

@ -58,140 +58,65 @@ Item {
text: qsTrId("chat")
}
Item {
RowLayout {
id: searchInputWrapper
anchors.top: headline.bottom
anchors.topMargin: 16
width: parent.width
height: searchInput.height
anchors.top: headline.bottom
anchors.topMargin: 16
anchors.right: parent.right
anchors.rightMargin: 8
Item {
anchors.verticalCenter: parent.verticalCenter
anchors.left: parent.left
anchors.right: actionButton.left
anchors.leftMargin: 16
anchors.rightMargin: 16
implicitHeight: searchInput.height
implicitWidth: searchInput.width
StatusBaseInput {
id: searchInput
implicitHeight: 36
width: parent.width
topPadding: 9
//% "Search"
placeholderText: qsTrId("search")
icon.name: "search"
}
StatusBaseInput {
id: searchInput
Layout.fillWidth: true
Layout.alignment: Qt.AlignVCenter | Qt.AlignLeft
Layout.leftMargin: 17
implicitHeight: 36
topPadding: 9
//% "Search"
placeholderText: qsTrId("search")
icon.name: "search"
MouseArea {
anchors.fill: parent
onClicked: root.openAppSearch()
}
}
StatusRoundButton {
id: actionButton
anchors.verticalCenter: parent.verticalCenter
anchors.right: parent.right
anchors.rightMargin: 8
width: 32
height: 32
type: StatusRoundButton.Type.Secondary
icon.name: "add"
state: "default"
onClicked: {
chatContextMenu.opened ?
chatContextMenu.close() :
chatContextMenu.popup(actionButton.width-chatContextMenu.width, actionButton.height + 4)
}
states: [
State {
name: "default"
PropertyChanges {
target: actionButton
icon.rotation: 0
highlighted: false
}
},
State {
name: "pressed"
PropertyChanges {
target: actionButton
icon.rotation: 45
highlighted: true
}
}
]
transitions: [
Transition {
from: "default"
to: "pressed"
RotationAnimation {
duration: 150
direction: RotationAnimation.Clockwise
easing.type: Easing.InCubic
}
},
Transition {
from: "pressed"
to: "default"
RotationAnimation {
duration: 150
direction: RotationAnimation.Counterclockwise
easing.type: Easing.OutCubic
}
}
]
StatusIconTabButton {
icon.name: "public-chat"
onClicked: { publicChatCommunityContextMenu.popup(); }
StatusPopupMenu {
id: chatContextMenu
closePolicy: Popup.CloseOnReleaseOutsideParent | Popup.CloseOnEscape
id: publicChatCommunityContextMenu
closePolicy: Popup.CloseOnReleaseOutsideParent | Popup.CloseOnEscape
StatusMenuItem {
//% "Join public chat"
text: qsTrId("new-public-group-chat")
icon.name: "public-chat"
onTriggered: Global.openPopup(publicChatPopupComponent)
}
onOpened: {
actionButton.state = "pressed"
}
StatusMenuItem {
//% "Communities"
text: qsTrId("communities")
icon.name: "communities"
onTriggered: Global.openPopup(communitiesPopupComponent)
enabled: localAccountSensitiveSettings.communitiesEnabled
}
}
}
onClosed: {
actionButton.state = "default"
}
StatusMenuItem {
//% "Start new chat"
text: qsTrId("start-new-chat")
icon.name: "private-chat"
onTriggered: Global.openPopup(privateChatPopupComponent)
}
StatusMenuItem {
//% "Start group chat"
text: qsTrId("start-group-chat")
icon.name: "group-chat"
onTriggered: Global.openPopup(groupChatPopupComponent)
}
StatusMenuItem {
//% "Join public chat"
text: qsTrId("new-public-group-chat")
icon.name: "public-chat"
onTriggered: Global.openPopup(publicChatPopupComponent)
}
StatusMenuItem {
//% "Communities"
text: qsTrId("communities")
icon.name: "communities"
onTriggered: Global.openPopup(communitiesPopupComponent)
enabled: localAccountSensitiveSettings.communitiesEnabled
}
StatusIconTabButton {
icon.name: "edit"
onClicked: {
root.store.openCreateChat = !root.store.openCreateChat;
}
}
}
StatusContactRequestsIndicatorListItem {
id: contactRequests
@ -233,7 +158,10 @@ Item {
id: channelList
model: root.chatSectionModule.model
onChatItemSelected: root.chatSectionModule.setActiveItem(id, "")
onChatItemSelected: {
root.chatSectionModule.setActiveItem(id, "")
root.store.openCreateChat = false;
}
onChatItemUnmuted: root.chatSectionModule.unmuteChat(id)
popupMenu: ChatContextMenuView {
@ -295,7 +223,9 @@ Item {
onDisplayProfilePopup: {
Global.openProfilePopup(publicKey)
}
onLeaveGroup: {
chatSectionModule.leaveChat("", chatId, true);
}
onDisplayGroupInfoPopup: {
chatSectionModule.prepareChatContentModuleForChatId(chatId)
let chatContentModule = chatSectionModule.getChatContentModule()
@ -351,7 +281,7 @@ Item {
store: root.store
contactsStore: root.contactsStore
onJoinPrivateChat: {
chatSectionModule.createOneToOneChat(publicKey, ensName)
chatSectionModule.createOneToOneChat("", publicKey, ensName)
}
onClosed: {
destroy()

View File

@ -0,0 +1,343 @@
import QtQuick 2.12
import QtQuick.Controls 2.12
import QtQuick.Layouts 1.12
import QtQml.Models 2.2
import QtGraphicalEffects 1.0
import StatusQ.Controls 0.1
import StatusQ.Components 0.1
import StatusQ.Core 0.1
import StatusQ.Core.Theme 0.1
import utils 1.0
Page {
id: root
anchors.fill: parent
anchors.bottomMargin: (tagSelector.namesModel.count > 0) ? 64 : 0
Behavior on anchors.bottomMargin { NumberAnimation { duration: 30 }}
anchors.rightMargin: 32
property ListModel contactsModel: ListModel { }
property var rootStore
property string activeChatId
property bool editMembers: false
//nim model doesn't support a get function, hence
//passing it here so that it can be handled accordingly
ListView {
id: convertModel
model: root.rootStore.currentChatContentModule().usersModule.model
delegate: Item {
property string publicId: model.id
property string name: model.name
property bool isAdmin: model.isAdmin
}
}
ListView {
id: contactsModelListView
model: root.rootStore.contactsModel
delegate: Item {
property string publicId: model.pubKey
property string name: model.name
property string icon: model.icon
property bool isIdenticon: model.isIdenticon
}
}
Connections {
target: rootStore
onCreateChatWithMessage: {
root.createChat();
}
onAddRemoveGroupMember: {
for (var i = 0; i < convertModel.count; i ++) {
var entry = convertModel.itemAtIndex(i);
if (!entry.isAdmin) {
tagSelector.namesModel.insert(tagSelector.namesModel.count, {"name": entry.name, "publicId": entry.publicId});
}
}
root.rootStore.openCreateChat = true;
root.editMembers = true;
}
onOpenCreateChatChanged: {
if (root.rootStore.openCreateChat) {
for (var i = 0; i < contactsModelListView.count; i ++) {
var entry = contactsModelListView.itemAtIndex(i);
contactsModel.insert(contactsModel.count,
{"publicId": entry.publicId, "name": entry.name,
"icon": entry.icon, "isIdenticon": entry.isIdenticon});
}
} else {
tagSelector.namesModel.clear();
contactsModel.clear();
root.editMembers = false;
}
}
}
function createChat() {
if (tagSelector.namesModel.count === 1) {
var ensName = tagSelector.namesModel.get(0).name.includes(".eth") ? tagSelector.namesModel.get(0).name : "";
root.rootStore.chatCommunitySectionModule.createOneToOneChat("", tagSelector.namesModel.get(0).publicId, ensName);
} else {
var groupName = "";
var publicIds = [];
for (var i = 0; i < tagSelector.namesModel.count; i++) {
groupName += (tagSelector.namesModel.get(i).name + (i === tagSelector.namesModel.count - 1 ? "" : "&"));
publicIds.push(tagSelector.namesModel.get(i).publicId);
}
root.rootStore.chatCommunitySectionModule.createGroupChat("",groupName, JSON.stringify(publicIds));
}
}
visible: (opacity > 0.01)
onVisibleChanged: {
if (!visible) {
tagSelector.namesModel.clear();
}
}
opacity: (root.rootStore.openCreateChat) ? 1.0 : 0.0
Behavior on opacity { NumberAnimation {}}
background: Rectangle {
anchors.fill: parent
color: Theme.palette.statusPopupMenu.backgroundColor
}
header: RowLayout {
id: headerRow
width: parent.width
height: tagSelector.height
anchors.top: parent.top
anchors.topMargin: 8
anchors.right: parent.right
anchors.rightMargin: 8
StatusTagSelector {
id: tagSelector
Layout.fillWidth: true
Layout.alignment: Qt.AlignVCenter | Qt.AlignLeft
Layout.leftMargin: 17
implicitHeight: 44
toLabelText: qsTr("To: ")
warningText: qsTr("USER LIMIT REACHED")
Connections {
target: tagSelector.namesModel
onCountChanged: {
root.rootStore.hideInput = (tagSelector.namesModel.count === 0);
}
}
Component.onCompleted: {
root.rootStore.hideInput = (tagSelector.namesModel.count === 0);
}
//simulate model filtering, TODO this
//makes more sense to be provided by the backend
//figure how real implementation should look like
property ListModel sortedList: ListModel { }
onTextChanged: {
sortedList.clear();
if (text !== "") {
for (var i = 0; i < contactsModel.count; i++ ) {
var entry = contactsModel.get(i);
if (entry.name.toLowerCase().includes(text.toLowerCase())) {
sortedList.insert(sortedList.count, {"publicId": entry.publicId, "name": entry.name,
"icon": entry.icon, "isIdenticon": entry.isIdenticon});
userListView.model = sortedList;
}
}
} else {
userListView.model = contactsModel;
}
}
onAddMember: {
if (root.editMembers) {
var pubKeys = [];
pubKeys.push(memberId);
root.rootStore.chatCommunitySectionModule.addGroupMembers("", activeChatId, JSON.stringify(pubKeys));
}
if (root.rootStore.chatTextInput.length > 0) {
root.rootStore.chatTextInput.clear();
}
}
onRemoveMember: {
if (root.editMembers) {
root.rootStore.chatCommunitySectionModule.removeMemberFromGroupChat("", activeChatId, memberId);
}
if (root.rootStore.chatTextInput.length > 0) {
root.rootStore.chatTextInput.clear();
}
}
}
StatusButton {
id: confirmButton
implicitHeight: 44
enabled: (tagSelector.namesModel.count > 0)
text: "Confirm"
onClicked: {
if (root.rootStore.chatTextInput.length > 0) {
root.rootStore.createChatInitMessage = root.rootStore.chatTextInput.getText(0, root.rootStore.chatTextInput.cursorPosition);
root.rootStore.chatTextInput.clear();
}
root.createChat();
}
}
}
contentItem: Item {
anchors.fill: parent
anchors.topMargin: headerRow.height + 32
Item {
anchors.fill: parent
visible: (contactsModel.count > 0)
StatusBaseText {
id: contactsLabel
font.pixelSize: 15
anchors.left: parent.left
anchors.leftMargin: 8
color: Theme.palette.baseColor1
text: qsTr("Contacts")
}
Control {
width: 360
anchors {
top: contactsLabel.bottom
topMargin: Style.current.halfPadding
bottom: !statusPopupMenuBackgroundContent.visible ? parent.bottom : undefined
bottomMargin: Style.current.bigPadding
}
height: Style.current.padding + (!statusPopupMenuBackgroundContent.visible ? parent.height :
(((userListView.count * 64) > parent.height) ? parent.height : (userListView.count * 64)))
x: (statusPopupMenuBackgroundContent.visible && (tagSelector.namesModel.count > 0) &&
((tagSelector.textEdit.x + Style.current.bigPadding + statusPopupMenuBackgroundContent.width) < parent.width))
? (tagSelector.textEdit.x + Style.current.bigPadding) : 0
background: Rectangle {
id: statusPopupMenuBackgroundContent
anchors.fill: parent
visible: (tagSelector.sortedList.count > 0)
color: Theme.palette.statusPopupMenu.backgroundColor
radius: 8
layer.enabled: true
layer.effect: DropShadow {
width: statusPopupMenuBackgroundContent.width
height: statusPopupMenuBackgroundContent.height
x: statusPopupMenuBackgroundContent.x
visible: statusPopupMenuBackgroundContent.visible
source: statusPopupMenuBackgroundContent
horizontalOffset: 0
verticalOffset: 4
radius: 12
samples: 25
spread: 0.2
color: Theme.palette.dropShadow
}
}
contentItem: ListView {
id: userListView
anchors.fill: parent
anchors.topMargin: 8
anchors.bottomMargin: 8
clip: true
model: contactsModel
ScrollBar.vertical: ScrollBar {
policy: ScrollBar.AsNeeded
}
boundsBehavior: Flickable.StopAtBounds
delegate: Item {
id: wrapper
anchors.right: parent.right
anchors.left: parent.left
height: 64
property bool hovered: false
Rectangle {
id: rectangle
anchors.fill: parent
anchors.rightMargin: Style.current.halfPadding
anchors.leftMargin: Style.current.halfPadding
radius: Style.current.radius
visible: (tagSelector.sortedList.count > 0)
color: (wrapper.hovered) ? Theme.palette.baseColor2 : "transparent"
}
StatusSmartIdenticon {
id: contactImage
anchors.left: parent.left
anchors.leftMargin: Style.current.padding
anchors.verticalCenter: parent.verticalCenter
name: model.name
icon: StatusIconSettings {
width: 28
height: 28
letterSize: 15
}
image: StatusImageSettings {
width: 28
height: 28
source: model.icon
isIdenticon: model.isIdenticon
}
}
StatusBaseText {
id: contactInfo
text: model.name
anchors.right: parent.right
anchors.rightMargin: 8
anchors.left: contactImage.right
anchors.leftMargin: 16
anchors.verticalCenter: parent.verticalCenter
elide: Text.ElideRight
color: Theme.palette.directColor1
font.weight: Font.Medium
font.pixelSize: 15
}
MouseArea {
cursorShape: enabled ? Qt.PointingHandCursor : Qt.ArrowCursor
acceptedButtons: Qt.LeftButton | Qt.RightButton
anchors.fill: parent
hoverEnabled: true
onEntered: {
wrapper.hovered = true;
}
onExited: {
wrapper.hovered = false;
}
onClicked: {
tagSelector.insertTag(model.name, model.publicId);
}
}
}
}
}
Component.onCompleted: {
if (visible) {
tagSelector.textEdit.forceActiveFocus();
}
}
}
StatusBaseText {
width: parent.width
height: contentHeight
anchors.centerIn: parent
horizontalAlignment: Text.AlignHCenter
verticalAlignment: Text.AlignVCenter
visible: (contactsModel.count === 0)
wrapMode: Text.WordWrap
font.pixelSize: 15
color: Theme.palette.baseColor1
text: qsTr("You can only send direct messages to your Contacts.\n\n
Send a contact request to the person you would like to chat with, you will be able to
chat with them once they have accepted your contact request.")
Component.onCompleted: {
if (visible) {
tagSelector.enabled = false;
}
}
}
}
}

View File

@ -24,7 +24,7 @@ QtObject {
function joinPrivateChat(pubKey) {
Global.changeAppSectionBySectionType(Constants.appSection.chat)
let chatCommunitySectionModule = root.mainModuleInst.getChatSectionModule()
chatCommunitySectionModule.createOneToOneChat(pubKey, "")
chatCommunitySectionModule.createOneToOneChat("", pubKey, "")
}
function addContact(pubKey) {

View File

@ -204,8 +204,10 @@ Rectangle {
event.accepted = true
return;
}
if(event) event.accepted = true
messageTooLongDialog.open()
if (event) {
event.accepted = true
messageTooLongDialog.open()
}
}
if (event.key === Qt.Key_Tab) {

View File

@ -58,7 +58,7 @@ StatusPopupMenu {
signal pinnedMessagesLimitReached(string messageId)
signal jumpToMessage(string messageId)
signal shouldCloseParentPopup()
signal createOneToOneChat(string chatId, string ensName)
signal createOneToOneChat(string communityId, string chatId, string ensName)
signal showReplyArea()
signal toggleReaction(string messageId, int emojiId)
signal deleteMessage(string messageId)
@ -215,7 +215,7 @@ StatusPopupMenu {
qsTrId("reply-to")
onTriggered: {
if (root.isProfile) {
root.createOneToOneChat(root.selectedUserPublicKey, "")
root.createOneToOneChat("", root.selectedUserPublicKey, "")
} else {
root.showReplyArea()
}