refactor(@desktop/chat-communities): `ChannelIdentifierView` component updated
This commit is contained in:
parent
7f40ae0f57
commit
bfaf1b5250
|
@ -3,6 +3,7 @@ import controller_interface
|
|||
import io_interface
|
||||
|
||||
import ../../../../../../app_service/service/contacts/service as contact_service
|
||||
import ../../../../../../app_service/service/chat/service as chat_service
|
||||
import ../../../../../../app_service/service/message/service as message_service
|
||||
|
||||
import ../../../../../core/signals/types
|
||||
|
@ -20,16 +21,19 @@ type
|
|||
chatId: string
|
||||
belongsToCommunity: bool
|
||||
contactService: contact_service.Service
|
||||
chatService: chat_service.Service
|
||||
messageService: message_service.Service
|
||||
|
||||
proc newController*(delegate: io_interface.AccessInterface, events: EventEmitter, chatId: string, belongsToCommunity: bool,
|
||||
contactService: contact_service.Service, messageService: message_service.Service): Controller =
|
||||
contactService: contact_service.Service, chatService: chat_service.Service, messageService: message_service.Service):
|
||||
Controller =
|
||||
result = Controller()
|
||||
result.delegate = delegate
|
||||
result.events = events
|
||||
result.chatId = chatId
|
||||
result.belongsToCommunity = belongsToCommunity
|
||||
result.contactService = contactService
|
||||
result.chatService = chatService
|
||||
result.messageService = messageService
|
||||
|
||||
method delete*(self: Controller) =
|
||||
|
@ -57,6 +61,12 @@ method init*(self: Controller) =
|
|||
method getChatId*(self: Controller): string =
|
||||
return self.chatId
|
||||
|
||||
method getChatDetails*(self: Controller): ChatDto =
|
||||
return self.chatService.getChatById(self.chatId)
|
||||
|
||||
method getOneToOneChatNameAndImage*(self: Controller): tuple[name: string, image: string, isIdenticon: bool] =
|
||||
return self.chatService.getOneToOneChatNameAndImage(self.chatId)
|
||||
|
||||
method belongsToCommunity*(self: Controller): bool =
|
||||
return self.belongsToCommunity
|
||||
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
import ../../../../../../app_service/service/contacts/service as contact_service
|
||||
import ../../../../../../app_service/service/contacts/dto/[contacts]
|
||||
import ../../../../../../app_service/service/chat/dto/[chat]
|
||||
|
||||
type
|
||||
AccessInterface* {.pure inheritable.} = ref object of RootObj
|
||||
|
@ -13,6 +14,13 @@ method init*(self: AccessInterface) {.base.} =
|
|||
method getChatId*(self: AccessInterface): string {.base.} =
|
||||
raise newException(ValueError, "No implementation available")
|
||||
|
||||
method getChatDetails*(self: AccessInterface): ChatDto {.base.} =
|
||||
raise newException(ValueError, "No implementation available")
|
||||
|
||||
method getOneToOneChatNameAndImage*(self: AccessInterface): tuple[name: string, image: string, isIdenticon: bool]
|
||||
{.base.} =
|
||||
raise newException(ValueError, "No implementation available")
|
||||
|
||||
method belongsToCommunity*(self: AccessInterface): bool {.base.} =
|
||||
raise newException(ValueError, "No implementation available")
|
||||
|
||||
|
|
|
@ -7,12 +7,15 @@ import ../../../../shared_models/message_item
|
|||
import ../../../../../global/global_singleton
|
||||
|
||||
import ../../../../../../app_service/service/contacts/service as contact_service
|
||||
import ../../../../../../app_service/service/chat/service as chat_service
|
||||
import ../../../../../../app_service/service/message/service as message_service
|
||||
|
||||
import eventemitter
|
||||
|
||||
export io_interface
|
||||
|
||||
const CHAT_IDENTIFIER_MESSAGE_ID = "chat-identifier-message-id"
|
||||
|
||||
type
|
||||
Module* = ref object of io_interface.AccessInterface
|
||||
delegate: delegate_interface.AccessInterface
|
||||
|
@ -22,16 +25,20 @@ type
|
|||
moduleLoaded: bool
|
||||
|
||||
proc newModule*(delegate: delegate_interface.AccessInterface, events: EventEmitter, chatId: string,
|
||||
belongsToCommunity: bool, contactService: contact_service.Service, messageService: message_service.Service):
|
||||
belongsToCommunity: bool, contactService: contact_service.Service, chatService: chat_service.Service,
|
||||
messageService: message_service.Service):
|
||||
Module =
|
||||
result = Module()
|
||||
result.delegate = delegate
|
||||
result.view = view.newView(result)
|
||||
result.viewVariant = newQVariant(result.view)
|
||||
result.controller = controller.newController(result, events, chatId, belongsToCommunity, contactService,
|
||||
result.controller = controller.newController(result, events, chatId, belongsToCommunity, contactService, chatService,
|
||||
messageService)
|
||||
result.moduleLoaded = false
|
||||
|
||||
# Forward declaration
|
||||
proc createChatIdentifierItem(self: Module): Item
|
||||
|
||||
method delete*(self: Module) =
|
||||
self.view.delete
|
||||
self.viewVariant.delete
|
||||
|
@ -45,15 +52,32 @@ method isLoaded*(self: Module): bool =
|
|||
return self.moduleLoaded
|
||||
|
||||
method viewDidLoad*(self: Module) =
|
||||
# The first message in the model must be always ChatIdentifier message.
|
||||
self.view.model().appendItem(self.createChatIdentifierItem())
|
||||
|
||||
self.moduleLoaded = true
|
||||
self.delegate.messagesDidLoad()
|
||||
|
||||
method getModuleAsVariant*(self: Module): QVariant =
|
||||
return self.viewVariant
|
||||
|
||||
proc createChatIdentifierItem(self: Module): Item =
|
||||
let chatDto = self.controller.getChatDetails()
|
||||
var chatName = chatDto.name
|
||||
var chatIcon = chatDto.identicon
|
||||
var isIdenticon = false
|
||||
if(chatDto.chatType == ChatType.OneToOne):
|
||||
(chatName, chatIcon, isIdenticon) = self.controller.getOneToOneChatNameAndImage()
|
||||
|
||||
result = initItem(CHAT_IDENTIFIER_MESSAGE_ID, "", chatDto.id, chatName, "", chatIcon, isIdenticon, false, "", "", "",
|
||||
true, 0, ContentType.ChatIdentifier, -1)
|
||||
result.chatColorThisMessageBelongsTo = chatDto.color
|
||||
result.chatTypeThisMessageBelongsTo = chatDto.chatType.int
|
||||
|
||||
method newMessagesLoaded*(self: Module, messages: seq[MessageDto], reactions: seq[ReactionDto],
|
||||
pinnedMessages: seq[PinnedMessageDto]) =
|
||||
var viewItems: seq[Item]
|
||||
var viewItems: seq[Item]
|
||||
|
||||
for m in messages:
|
||||
let sender = self.controller.getContactById(m.`from`)
|
||||
let senderDisplayName = sender.userNameOrAlias()
|
||||
|
@ -77,8 +101,13 @@ method newMessagesLoaded*(self: Module, messages: seq[MessageDto], reactions: se
|
|||
item.pinned = true
|
||||
|
||||
# messages are sorted from the most recent to the least recent one
|
||||
viewItems = item & viewItems
|
||||
viewItems.add(item)
|
||||
|
||||
# ChatIdentifier message will be always the first message (the oldest one)
|
||||
viewItems.add(self.createChatIdentifierItem())
|
||||
# Delete the old ChatIdentifier message first
|
||||
self.view.model().removeItem(CHAT_IDENTIFIER_MESSAGE_ID)
|
||||
# Add new loaded messages
|
||||
self.view.model().prependItems(viewItems)
|
||||
|
||||
method toggleReaction*(self: Module, messageId: string, emojiId: int) =
|
||||
|
|
|
@ -48,7 +48,7 @@ proc newModule*(delegate: delegate_interface.AccessInterface, events: EventEmitt
|
|||
|
||||
result.inputAreaModule = input_area_module.newModule(result, chatId, belongsToCommunity, chatService, communityService)
|
||||
result.messagesModule = messages_module.newModule(result, events, chatId, belongsToCommunity, contactService,
|
||||
messageService)
|
||||
chatService, messageService)
|
||||
result.usersModule = users_module.newModule(result, events, sectionId, chatId, belongsToCommunity, isUsersListAvailable,
|
||||
contactService, communityService, messageService)
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import Tables, json
|
||||
import Tables, json, strformat
|
||||
|
||||
type
|
||||
ContentType* {.pure.} = enum
|
||||
|
@ -41,9 +41,13 @@ type
|
|||
reactions: OrderedTable[int, seq[tuple[publicKey: string, reactionId: string]]] # [emojiId, list of [user publicKey reacted with the emojiId, reaction id]]
|
||||
reactionIds: seq[string]
|
||||
pinned: bool
|
||||
# used in case of ContentType.ChatIdentifier only
|
||||
chatTypeThisMessageBelongsTo: int
|
||||
chatColorThisMessageBelongsTo: string
|
||||
|
||||
proc initItem*(id, responseToMessageWithId, senderId, senderDisplayName, senderLocalName, senderIcon: string, isSenderIconIdenticon, amISender: bool,
|
||||
outgoingStatus, text, image: string, seen: bool, timestamp: int64, contentType: ContentType, messageType: int): Item =
|
||||
proc initItem*(id, responseToMessageWithId, senderId, senderDisplayName, senderLocalName, senderIcon: string,
|
||||
isSenderIconIdenticon, amISender: bool, outgoingStatus, text, image: string, seen: bool, timestamp: int64,
|
||||
contentType: ContentType, messageType: int): Item =
|
||||
result = Item()
|
||||
result.id = id
|
||||
result.responseToMessageWithId = responseToMessageWithId
|
||||
|
@ -113,6 +117,19 @@ proc pinned*(self: Item): bool {.inline.} =
|
|||
proc `pinned=`*(self: Item, value: bool) {.inline.} =
|
||||
self.pinned = value
|
||||
|
||||
proc chatTypeThisMessageBelongsTo*(self: Item): int {.inline.} =
|
||||
self.chatTypeThisMessageBelongsTo
|
||||
|
||||
proc `chatTypeThisMessageBelongsTo=`*(self: Item, value: int) {.inline.} =
|
||||
self.chatTypeThisMessageBelongsTo = value
|
||||
|
||||
proc chatColorThisMessageBelongsTo*(self: Item): string {.inline.} =
|
||||
self.chatColorThisMessageBelongsTo
|
||||
|
||||
proc `chatColorThisMessageBelongsTo=`*(self: Item, value: string) {.inline.} =
|
||||
self.chatColorThisMessageBelongsTo = value
|
||||
|
||||
|
||||
proc shouldAddReaction*(self: Item, emojiId: int, publicKey: string): bool =
|
||||
for k, values in self.reactions:
|
||||
if(k != emojiId):
|
||||
|
@ -175,6 +192,21 @@ proc getCountsForReactions*(self: Item): seq[JsonNode] =
|
|||
|
||||
result.add(%* {"emojiId": k, "counts": v.len})
|
||||
|
||||
proc `$`*(self: Item): string =
|
||||
result = fmt"""MessageItem(
|
||||
id: {self.id},
|
||||
responseToMessageWithId: {self.responseToMessageWithId},
|
||||
senderId: {self.senderId},
|
||||
senderDisplayName: {self.senderDisplayName},
|
||||
senderLocalName: {self.senderLocalName},
|
||||
timestamp: {self.timestamp},
|
||||
contentType: {self.contentType.int},
|
||||
messageType:{self.messageType},
|
||||
chatTypeThisMessageBelongsTo:{self.chatTypeThisMessageBelongsTo},
|
||||
chatColorThisMessageBelongsTo:{self.chatColorThisMessageBelongsTo},
|
||||
pinned:{self.pinned}
|
||||
]"""
|
||||
|
||||
proc toJsonNode*(self: Item): JsonNode =
|
||||
result = %* {
|
||||
"id": self.id,
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import NimQml, Tables, json, strutils
|
||||
import NimQml, Tables, json, strutils, strformat
|
||||
|
||||
import message_item
|
||||
|
||||
|
@ -25,6 +25,8 @@ type
|
|||
# GapTo
|
||||
Pinned
|
||||
CountsForReactions
|
||||
ChatTypeThisMessageBelongsTo
|
||||
ChatColorThisMessageBelongsTo
|
||||
|
||||
QtObject:
|
||||
type
|
||||
|
@ -42,6 +44,12 @@ QtObject:
|
|||
new(result, delete)
|
||||
result.setup
|
||||
|
||||
proc `$`*(self: Model): string =
|
||||
for i in 0 ..< self.items.len:
|
||||
result &= fmt"""MessageModel:
|
||||
[{i}]:({$self.items[i]})
|
||||
"""
|
||||
|
||||
proc countChanged(self: Model) {.signal.}
|
||||
proc getCount(self: Model): int {.slot.} =
|
||||
self.items.len
|
||||
|
@ -75,6 +83,8 @@ QtObject:
|
|||
# ModelRole.GapTo.int:"gapTo",
|
||||
ModelRole.Pinned.int:"pinned",
|
||||
ModelRole.CountsForReactions.int:"countsForReactions",
|
||||
ModelRole.ChatTypeThisMessageBelongsTo.int:"chatTypeThisMessageBelongsTo",
|
||||
ModelRole.ChatColorThisMessageBelongsTo.int:"chatColorThisMessageBelongsTo",
|
||||
}.toTable
|
||||
|
||||
method data(self: Model, index: QModelIndex, role: int): QVariant =
|
||||
|
@ -130,6 +140,10 @@ QtObject:
|
|||
result = newQVariant(item.pinned)
|
||||
of ModelRole.CountsForReactions:
|
||||
result = newQVariant($(%* item.getCountsForReactions))
|
||||
of ModelRole.ChatTypeThisMessageBelongsTo:
|
||||
result = newQVariant(item.chatTypeThisMessageBelongsTo)
|
||||
of ModelRole.ChatColorThisMessageBelongsTo:
|
||||
result = newQVariant(item.chatColorThisMessageBelongsTo)
|
||||
|
||||
proc findIndexForMessageId(self: Model, messageId: string): int =
|
||||
for i in 0 ..< self.items.len:
|
||||
|
|
|
@ -64,6 +64,9 @@ QtObject:
|
|||
result.msgCursor = initTable[string, string]()
|
||||
result.pinnedMsgCursor = initTable[string, string]()
|
||||
|
||||
proc initialMessagesFetched(self: Service, chatId: string): bool =
|
||||
return self.msgCursor.hasKey(chatId)
|
||||
|
||||
proc getCurrentMessageCursor(self: Service, chatId: string): string =
|
||||
if(not self.msgCursor.hasKey(chatId)):
|
||||
self.msgCursor[chatId] = ""
|
||||
|
@ -140,6 +143,9 @@ QtObject:
|
|||
self.threadpool.start(arg)
|
||||
|
||||
proc asyncLoadInitialMessagesForChat*(self: Service, chatId: string) =
|
||||
if(self.initialMessagesFetched(chatId)):
|
||||
return
|
||||
|
||||
if(self.getCurrentMessageCursor(chatId).len > 0):
|
||||
return
|
||||
|
||||
|
|
|
@ -31,7 +31,6 @@ Item {
|
|||
|
||||
property real scrollY: chatLogView.visibleArea.yPosition * chatLogView.contentHeight
|
||||
property int newMessages: 0
|
||||
property int countOnStartUp: 0
|
||||
|
||||
ListView {
|
||||
id: chatLogView
|
||||
|
@ -286,41 +285,16 @@ Item {
|
|||
// }
|
||||
// }
|
||||
|
||||
model: messageListDelegate
|
||||
model: messageStore.messageModule.model
|
||||
section.property: "sectionIdentifier"
|
||||
section.criteria: ViewSection.FullString
|
||||
|
||||
// Not Refactored Yet
|
||||
//Component.onCompleted: scrollToBottom(true)
|
||||
}
|
||||
|
||||
// MessageDialog {
|
||||
// id: sendingMsgFailedPopup
|
||||
// standardButtons: StandardButton.Ok
|
||||
// //% "Failed to send message."
|
||||
// text: qsTrId("failed-to-send-message-")
|
||||
// icon: StandardIcon.Critical
|
||||
// }
|
||||
|
||||
Timer {
|
||||
id: modelLoadingDelayTimer
|
||||
interval: 1000
|
||||
onTriggered: {
|
||||
root.countOnStartUp = messageListDelegate.count;
|
||||
}
|
||||
}
|
||||
|
||||
DelegateModelGeneralized {
|
||||
id: messageListDelegate
|
||||
lessThan: [
|
||||
function(left, right) { return left.clock > right.clock }
|
||||
]
|
||||
|
||||
model: messageStore.messageModule.model
|
||||
|
||||
delegate: MessageView {
|
||||
id: msgDelegate
|
||||
rootStore: root.store
|
||||
|
||||
messageStore: root.messageStore
|
||||
|
||||
messageId: model.id
|
||||
|
@ -338,6 +312,10 @@ Item {
|
|||
messageContentType: model.contentType
|
||||
pinnedMessage: model.pinned
|
||||
|
||||
// Used only in case of ChatIdentifier
|
||||
chatTypeThisMessageBelongsTo: model.chatTypeThisMessageBelongsTo
|
||||
chatColorThisMessageBelongsTo: model.chatColorThisMessageBelongsTo
|
||||
|
||||
// This is possible since we have all data loaded before we load qml.
|
||||
// When we fetch messages to fulfill a gap we have to set them at once.
|
||||
prevMessageIndex: index - 1
|
||||
|
@ -345,125 +323,16 @@ Item {
|
|||
nextMessageIndex: index + 1
|
||||
nextMessageAsJsonObj: messageStore.getMessageByIndexAsJson(index + 1)
|
||||
|
||||
|
||||
/////////////TODO Remove
|
||||
// fromAuthor: model.fromAuthor
|
||||
// chatId: model.chatId
|
||||
// userName: model.userName
|
||||
// alias: model.alias
|
||||
// localName: model.localName
|
||||
// message: model.message
|
||||
// plainText: model.plainText
|
||||
// identicon: model.identicon
|
||||
// isCurrentUser: model.isCurrentUser
|
||||
// timestamp: model.timestamp
|
||||
// sticker: model.sticker
|
||||
// contentType: model.contentType
|
||||
// replaces: model.replaces
|
||||
// isEdited: model.isEdited
|
||||
// outgoingStatus: model.outgoingStatus
|
||||
// responseTo: model.responseTo
|
||||
// authorCurrentMsg: msgDelegate.ListView.section
|
||||
// // The previous message is actually the nextSection since we reversed the list order
|
||||
// authorPrevMsg: msgDelegate.ListView.nextSection
|
||||
// imageClick: imagePopup.openPopup.bind(imagePopup)
|
||||
// messageId: model.messageId
|
||||
// emojiReactions: model.emojiReactions
|
||||
// linkUrls: model.linkUrls
|
||||
// communityId: model.communityId
|
||||
// hasMention: model.hasMention
|
||||
// stickerPackId: model.stickerPackId
|
||||
// pinnedMessage: model.isPinned
|
||||
// pinnedBy: model.pinnedBy
|
||||
// gapFrom: model.gapFrom
|
||||
// gapTo: model.gapTo
|
||||
// visible: !model.hide
|
||||
// messageContextMenu: root.messageContextMenuInst
|
||||
|
||||
// prevMessageIndex: {
|
||||
// // This is used in order to have access to the previous message and determine the timestamp
|
||||
// // we can't rely on the index because the sequence of messages is not ordered on the nim side
|
||||
// if (msgDelegate.DelegateModel.itemsIndex < messageListDelegate.items.count - 1) {
|
||||
// return messageListDelegate.items.get(msgDelegate.DelegateModel.itemsIndex + 1).model.index
|
||||
// }
|
||||
// return -1;
|
||||
// }
|
||||
// nextMessageIndex: {
|
||||
// if (msgDelegate.DelegateModel.itemsIndex < 1) {
|
||||
// return -1
|
||||
// }
|
||||
// return messageListDelegate.items.get(msgDelegate.DelegateModel.itemsIndex - 1).model.index
|
||||
// }
|
||||
// scrollToBottom: chatLogView.scrollToBottom
|
||||
// timeout: model.timeout
|
||||
|
||||
Component.onCompleted: {
|
||||
if ((root.countOnStartUp > 0) && (root.countOnStartUp - 1) < index) {
|
||||
//new message, increment z order
|
||||
z = index;
|
||||
}
|
||||
|
||||
// messageStore.messageId = model.id
|
||||
// messageStore.responseToMessageWithId = model.responseToMessageWithId
|
||||
// messageStore.senderId = model.senderId
|
||||
// messageStore.senderDisplayName = model.senderDisplayName
|
||||
// messageStore.senderLocalName = model.senderLocalName
|
||||
// messageStore.senderIcon = model.senderIcon
|
||||
// messageStore.isSenderIconIdenticon = model.isSenderIconIdenticon
|
||||
// messageStore.amISender = model.amISender
|
||||
// messageStore.message = model.messageText
|
||||
// messageStore.messageImage = model.messageImage
|
||||
// messageStore.messageTimestamp = model.timestamp
|
||||
// messageStore.messageOutgoingStatus = model.outgoingStatus
|
||||
// messageStore.messageContentType = model.contentType
|
||||
// messageStore.pinnedMessage = model.pinned
|
||||
|
||||
|
||||
// messageStore.fromAuthor = model.fromAuthor;
|
||||
// messageStore.chatId = model.chatId;
|
||||
// messageStore.userName = model.userName;
|
||||
// messageStore.alias = model.alias;
|
||||
// messageStore.localName = model.localName;
|
||||
// messageStore.message = model.message;
|
||||
// messageStore.plainText = model.plainText;
|
||||
// messageStore.identicon = model.identicon;
|
||||
// messageStore.isCurrentUser = model.isCurrentUser;
|
||||
// messageStore.timestamp = model.timestamp;
|
||||
// messageStore.sticker = model.sticker;
|
||||
// messageStore.contentType = model.contentType;
|
||||
// messageStore.replaces = model.replaces;
|
||||
// messageStore.isEdited = model.isEdited;
|
||||
// messageStore.outgoingStatus = model.outgoingStatus;
|
||||
// messageStore.responseTo = model.responseTo;
|
||||
// messageStore.authorCurrentMsg = msgDelegate.ListView.section;
|
||||
// // The previous message is actually the nextSection since we reversed the list order
|
||||
// messageStore.authorPrevMsg = msgDelegate.ListView.nextSection;
|
||||
// messageStore.imageClick = imagePopup.openPopup.bind(imagePopup);
|
||||
// messageStore.messageId = model.messageId;
|
||||
// messageStore.emojiReactions = model.emojiReactions;
|
||||
// messageStore.linkUrls = model.linkUrls;
|
||||
// messageStore.communityId = model.communityId;
|
||||
// messageStore.hasMention = model.hasMention;
|
||||
// messageStore.stickerPackId = model.stickerPackId;
|
||||
// messageStore.pinnedMessage = model.isPinned;
|
||||
// messageStore.pinnedBy = model.pinnedBy;
|
||||
// messageStore.gapFrom = model.gapFrom;
|
||||
// messageStore.gapTo = model.gapTo;
|
||||
// messageStore.messageContextMenu = root.messageContextMenuInst;
|
||||
// messageStore.prevMessageIndex =
|
||||
// // This is used in order to have access to the previous message and determine the timestamp
|
||||
// // we can't rely on the index because the sequence of messages is not ordered on the nim side
|
||||
// (msgDelegate.DelegateModel.itemsIndex < messageListDelegate.items.count - 1) ?
|
||||
// messageListDelegate.items.get(msgDelegate.DelegateModel.itemsIndex + 1).model.index
|
||||
// : -1;
|
||||
// messageStore.nextMessageIndex = (msgDelegate.DelegateModel.itemsIndex < 1) ?
|
||||
// -1 : messageListDelegate.items.get(msgDelegate.DelegateModel.itemsIndex - 1).model.index;
|
||||
// messageStore.scrollToBottom = chatLogView.scrollToBottom;
|
||||
// messageStore.timeout = model.timeout;
|
||||
}
|
||||
}
|
||||
Component.onCompleted: {
|
||||
modelLoadingDelayTimer.start();
|
||||
}
|
||||
}
|
||||
|
||||
// MessageDialog {
|
||||
// id: sendingMsgFailedPopup
|
||||
// standardButtons: StandardButton.Ok
|
||||
// //% "Failed to send message."
|
||||
// text: qsTrId("failed-to-send-message-")
|
||||
// icon: StandardIcon.Critical
|
||||
// }
|
||||
}
|
||||
|
|
|
@ -7,14 +7,15 @@ import utils 1.0
|
|||
Column {
|
||||
id: root
|
||||
spacing: Style.current.padding
|
||||
visible: authorCurrentMsg === ""
|
||||
anchors.horizontalCenter: parent.horizontalCenter
|
||||
topPadding: visible ? Style.current.bigPadding : 0
|
||||
bottomPadding: visible? 50 : 0
|
||||
|
||||
property var store
|
||||
property string authorCurrentMsg: "authorCurrentMsg"
|
||||
property string profileImage
|
||||
property string chatName: ""
|
||||
property int chatType: -1
|
||||
property string chatColor: ""
|
||||
property string chatIcon: ""
|
||||
property bool chatIconIsIdenticon: true
|
||||
|
||||
Rectangle {
|
||||
id: circleId
|
||||
|
@ -22,38 +23,24 @@ Column {
|
|||
width: 120
|
||||
height: 120
|
||||
radius: 120
|
||||
border.width: root.store.chatsModelInst.channelView.activeChannel.chatType === Constants.chatType.oneToOne ? 2 : 0
|
||||
border.width: root.chatType === Constants.chatType.oneToOne ? 2 : 0
|
||||
border.color: Style.current.border
|
||||
color: {
|
||||
if (root.store.chatsModelInst.channelView.activeChannel.chatType === Constants.chatType.oneToOne) {
|
||||
return Style.current.transparent
|
||||
}
|
||||
if (root.store.chatsModelInst.channelView.activeChannel.color) {
|
||||
return root.store.chatsModelInst.channelView.activeChannel.color
|
||||
}
|
||||
const color = root.store.chatsModelInst.channelView.getChannelColor(chatId)
|
||||
if (!color) {
|
||||
return Style.current.orange
|
||||
}
|
||||
return color
|
||||
}
|
||||
color: root.chatColor
|
||||
|
||||
RoundedImage {
|
||||
visible: root.store.chatsModelInst.channelView.activeChannel.chatType === Constants.chatType.oneToOne
|
||||
visible: root.chatType === Constants.chatType.oneToOne
|
||||
anchors.horizontalCenter: parent.horizontalCenter
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
width: 120
|
||||
height: 120
|
||||
source: root.profileImage || root.store.chatsModelInst.channelView.activeChannel.identicon
|
||||
source: root.chatIcon
|
||||
smooth: false
|
||||
antialiasing: true
|
||||
}
|
||||
|
||||
StyledText {
|
||||
visible: root.store.chatsModelInst.channelView.activeChannel.chatType !== Constants.chatType.oneToOne
|
||||
text: Utils.removeStatusEns((root.store.chatsModelInst.channelView.activeChannel.name.charAt(0) === "#" ?
|
||||
root.store.chatsModelInst.channelView.activeChannel.name.charAt(1) :
|
||||
root.store.chatsModelInst.channelView.activeChannel.name.charAt(0)).toUpperCase())
|
||||
visible: root.chatType !== Constants.chatType.oneToOne
|
||||
text: root.chatName.charAt(0).toUpperCase()
|
||||
opacity: 0.7
|
||||
font.weight: Font.Bold
|
||||
font.pixelSize: 51
|
||||
|
@ -66,13 +53,7 @@ Column {
|
|||
StyledText {
|
||||
id: channelName
|
||||
wrapMode: Text.Wrap
|
||||
text: {
|
||||
switch(root.store.chatsModelInst.channelView.activeChannel.chatType) {
|
||||
case Constants.chatType.publicChat: return "#" + root.store.chatsModelInst.channelView.activeChannel.name;
|
||||
case Constants.chatType.oneToOne: return Utils.removeStatusEns(root.store.chatsModelInst.userNameOrAlias(chatsModel.channelView.activeChannel.id))
|
||||
default: return root.store.chatsModelInst.channelView.activeChannel.name
|
||||
}
|
||||
}
|
||||
text: root.chatName
|
||||
font.weight: Font.Bold
|
||||
font.pixelSize: 22
|
||||
color: Style.current.textColor
|
||||
|
@ -85,11 +66,13 @@ Column {
|
|||
anchors.horizontalCenter: parent.horizontalCenter
|
||||
width: 310
|
||||
text: {
|
||||
switch(root.store.chatsModelInst.channelView.activeChannel.chatType) {
|
||||
//% "Welcome to the beginning of the <span style='color: %1'>%2</span> group!"
|
||||
case Constants.chatType.privateGroupChat: return qsTrId("welcome-to-the-beginning-of-the--span-style--color---1---2--span--group-").arg(Style.current.textColor).arg(root.store.chatsModelInst.channelView.activeChannel.name);
|
||||
//% "Any messages you send here are encrypted and can only be read by you and <span style='color: %1'>%2</span>"
|
||||
case Constants.chatType.oneToOne: return qsTrId("any-messages-you-send-here-are-encrypted-and-can-only-be-read-by-you-and--span-style--color---1---2--span-").arg(Style.current.textColor).arg(channelName.text)
|
||||
switch(root.chatType) {
|
||||
case Constants.chatType.privateGroupChat:
|
||||
//% "Welcome to the beginning of the <span style='color: %1'>%2</span> group!"
|
||||
return qsTrId("welcome-to-the-beginning-of-the--span-style--color---1---2--span--group-").arg(Style.current.textColor).arg(root.chatName);
|
||||
case Constants.chatType.oneToOne:
|
||||
//% "Any messages you send here are encrypted and can only be read by you and <span style='color: %1'>%2</span>"
|
||||
return qsTrId("any-messages-you-send-here-are-encrypted-and-can-only-be-read-by-you-and--span-style--color---1---2--span-").arg(Style.current.textColor).arg(root.chatName)
|
||||
default: return "";
|
||||
}
|
||||
}
|
||||
|
@ -100,8 +83,10 @@ Column {
|
|||
}
|
||||
|
||||
Item {
|
||||
visible: root.store.chatsModelInst.channelView.activeChannel.chatType === Constants.chatType.privateGroupChat
|
||||
&& root.store.chatsModelInst.channelView.activeChannel.isMemberButNotJoined
|
||||
//NEED TO CHECK THIS
|
||||
// visible: root.store.chatsModelInst.channelView.activeChannel.chatType === Constants.chatType.privateGroupChat
|
||||
// && root.store.chatsModelInst.channelView.activeChannel.isMemberButNotJoined
|
||||
visible: root.chatType === Constants.chatType.privateGroupChat
|
||||
anchors.horizontalCenter: parent.horizontalCenter
|
||||
width: visible ? joinChat.width : 0
|
||||
height: visible ? 100 : 0
|
||||
|
@ -119,7 +104,8 @@ Column {
|
|||
cursorShape: Qt.PointingHandCursor
|
||||
anchors.fill: parent
|
||||
onClicked: {
|
||||
root.store.chatsModelInst.groups.join()
|
||||
//NEED TO CHECK THIS
|
||||
// root.store.chatsModelInst.groups.join()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -136,7 +122,8 @@ Column {
|
|||
cursorShape: Qt.PointingHandCursor
|
||||
anchors.fill: parent
|
||||
onClicked: {
|
||||
root.store.chatsModelInst.channelView.leaveActiveChat()
|
||||
//NEED TO CHECK THIS
|
||||
// root.store.chatsModelInst.channelView.leaveActiveChat()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -51,57 +51,58 @@ Item {
|
|||
height: root.veryLongChatText && !root.readMore ? Math.min(implicitHeight, 200) : implicitHeight
|
||||
clip: height < implicitHeight
|
||||
onLinkActivated: {
|
||||
root.linkActivated(link)
|
||||
if(link.startsWith("#")) {
|
||||
const channelName = link.substring(1);
|
||||
const foundChannelObj = root.store.chatsModelInst.getChannel(channelName);
|
||||
// Not Refactored Yet
|
||||
// root.linkActivated(link)
|
||||
// if(link.startsWith("#")) {
|
||||
// const channelName = link.substring(1);
|
||||
// const foundChannelObj = root.store.chatsModelInst.getChannel(channelName);
|
||||
|
||||
if (!foundChannelObj)
|
||||
{
|
||||
root.store.chatsModelInst.channelView.joinPublicChat(channelName)
|
||||
if(root.store.chatsModelInst.communities.activeCommunity.active)
|
||||
{
|
||||
root.store.chatsModelInst.channelView.joinPublicChat(channelName)
|
||||
Global.changeAppSectionBySectionType(Constants.appSection.chat)
|
||||
}
|
||||
return
|
||||
}
|
||||
// if (!foundChannelObj)
|
||||
// {
|
||||
// root.store.chatsModelInst.channelView.joinPublicChat(channelName)
|
||||
// if(root.store.chatsModelInst.communities.activeCommunity.active)
|
||||
// {
|
||||
// root.store.chatsModelInst.channelView.joinPublicChat(channelName)
|
||||
// Global.changeAppSectionBySectionType(Constants.appSection.chat)
|
||||
// }
|
||||
// return
|
||||
// }
|
||||
|
||||
let obj = JSON.parse(foundChannelObj)
|
||||
// let obj = JSON.parse(foundChannelObj)
|
||||
|
||||
if(obj.chatType === -1 || obj.chatType === Constants.chatTypePublic)
|
||||
{
|
||||
if(root.store.chatsModelInst.communities.activeCommunity.active) {
|
||||
root.store.chatsModelInst.channelView.joinPublicChat(channelName)
|
||||
Global.changeAppSectionBySectionType(Constants.appSection.chat)
|
||||
}
|
||||
root.store.chatsModelInst.channelView.setActiveChannel(channelName);
|
||||
}
|
||||
else if(obj.communityId === root.store.chatsModelInst.communities.activeCommunity.id &&
|
||||
obj.chatType === Constants.chatTypeCommunity &&
|
||||
root.store.chatsModelInst.channelView.activeChannel.id !== obj.id
|
||||
)
|
||||
{
|
||||
root.store.chatsModelInst.channelView.setActiveChannel(channelName);
|
||||
}
|
||||
// if(obj.chatType === -1 || obj.chatType === Constants.chatTypePublic)
|
||||
// {
|
||||
// if(root.store.chatsModelInst.communities.activeCommunity.active) {
|
||||
// root.store.chatsModelInst.channelView.joinPublicChat(channelName)
|
||||
// Global.changeAppSectionBySectionType(Constants.appSection.chat)
|
||||
// }
|
||||
// root.store.chatsModelInst.channelView.setActiveChannel(channelName);
|
||||
// }
|
||||
// else if(obj.communityId === root.store.chatsModelInst.communities.activeCommunity.id &&
|
||||
// obj.chatType === Constants.chatTypeCommunity &&
|
||||
// root.store.chatsModelInst.channelView.activeChannel.id !== obj.id
|
||||
// )
|
||||
// {
|
||||
// root.store.chatsModelInst.channelView.setActiveChannel(channelName);
|
||||
// }
|
||||
|
||||
return
|
||||
}
|
||||
// return
|
||||
// }
|
||||
|
||||
if (link.startsWith('//')) {
|
||||
let pk = link.replace("//", "");
|
||||
const userProfileImage = appMain.getProfileImage(pk)
|
||||
openProfilePopup(root.store.chatsModelInst.userNameOrAlias(pk), pk, userProfileImage || root.store.utilsModelInst.generateIdenticon(pk))
|
||||
return;
|
||||
}
|
||||
// if (link.startsWith('//')) {
|
||||
// let pk = link.replace("//", "");
|
||||
// const userProfileImage = appMain.getProfileImage(pk)
|
||||
// openProfilePopup(root.store.chatsModelInst.userNameOrAlias(pk), pk, userProfileImage || root.store.utilsModelInst.generateIdenticon(pk))
|
||||
// return;
|
||||
// }
|
||||
|
||||
const data = Utils.getLinkDataForStatusLinks(link)
|
||||
if (data && data.callback) {
|
||||
return data.callback()
|
||||
}
|
||||
// const data = Utils.getLinkDataForStatusLinks(link)
|
||||
// if (data && data.callback) {
|
||||
// return data.callback()
|
||||
// }
|
||||
|
||||
|
||||
Global.openLink(link)
|
||||
// Global.openLink(link)
|
||||
}
|
||||
|
||||
onLinkHovered: {
|
||||
|
|
|
@ -26,18 +26,13 @@ Item {
|
|||
// Not Refactored Yet
|
||||
|
||||
return false
|
||||
// if (!!rootStore) {
|
||||
// switch (rootStore.chatsModelInst.channelView.activeChannel.chatType) {
|
||||
// case Constants.chatType.oneToOne: return true
|
||||
// case Constants.chatType.privateGroupChat: return rootStore.chatsModelInst.channelView.activeChannel.isAdmin(userProfile.pubKey) ? true : isCurrentUser
|
||||
// case Constants.chatType.publicChat: return isCurrentUser
|
||||
// case Constants.chatType.communityChat: return rootStore.chatsModelInst.communities.activeCommunity.admin ? true : isCurrentUser
|
||||
// case Constants.chatType.profile: return false
|
||||
// default: return false
|
||||
// }
|
||||
// }
|
||||
// else {
|
||||
// return false;
|
||||
// switch (chatTypeThisMessageBelongsTo) {
|
||||
// case Constants.chatType.oneToOne: return true
|
||||
// case Constants.chatType.privateGroupChat: return rootStore.chatsModelInst.channelView.activeChannel.isAdmin(userProfile.pubKey) ? true : isCurrentUser
|
||||
// case Constants.chatType.publicChat: return isCurrentUser
|
||||
// case Constants.chatType.communityChat: return rootStore.chatsModelInst.communities.activeCommunity.admin ? true : isCurrentUser
|
||||
// case Constants.chatType.profile: return false
|
||||
// default: return false
|
||||
// }
|
||||
}
|
||||
|
||||
|
@ -206,8 +201,10 @@ Item {
|
|||
}
|
||||
|
||||
StyledText {
|
||||
//% "Pinned by %1"
|
||||
text: qsTrId("pinned-by--1").arg(rootStore.chatsModelInst.alias(pinnedBy))
|
||||
// Not Refactored Yet
|
||||
text: ""
|
||||
// //% "Pinned by %1"
|
||||
// text: qsTrId("pinned-by--1").arg(rootStore.chatsModelInst.alias(pinnedBy))
|
||||
anchors.left: pinImage.right
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
font.pixelSize: 13
|
||||
|
@ -217,14 +214,15 @@ Item {
|
|||
}
|
||||
|
||||
|
||||
Connections {
|
||||
enabled: !!rootStore
|
||||
target: enabled ? rootStore.chatsModelInst.messageView : null
|
||||
onMessageEdited: {
|
||||
if(chatReply.item)
|
||||
chatReply.item.messageEdited(editedMessageId, editedMessageContent)
|
||||
}
|
||||
}
|
||||
// Not Refactored Yet
|
||||
// Connections {
|
||||
// enabled: !!rootStore
|
||||
// target: enabled ? rootStore.chatsModelInst.messageView : null
|
||||
// onMessageEdited: {
|
||||
// if(chatReply.item)
|
||||
// chatReply.item.messageEdited(editedMessageId, editedMessageContent)
|
||||
// }
|
||||
// }
|
||||
|
||||
ChatReplyPanel {
|
||||
id: chatReply
|
||||
|
@ -303,7 +301,7 @@ Item {
|
|||
anchors.left: chatName.right
|
||||
anchors.leftMargin: 4
|
||||
color: Style.current.secondaryText
|
||||
//timestamp: timestamp
|
||||
timestamp: messageTimestamp
|
||||
}
|
||||
|
||||
Loader {
|
||||
|
@ -376,7 +374,7 @@ Item {
|
|||
StatusChatInput {
|
||||
id: editTextInput
|
||||
chatInputPlaceholder: qsTrId("type-a-message-")
|
||||
chatType: rootStore.chatsModelInst.channelView.activeChannel.chatType
|
||||
chatType: chatTypeThisMessageBelongsTo
|
||||
isEdit: true
|
||||
textInput.text: editMessageLoader.sourceText
|
||||
onSendMessage: {
|
||||
|
@ -437,7 +435,8 @@ Item {
|
|||
visible: !isEdit
|
||||
ChatTextView {
|
||||
id: chatText
|
||||
store: rootStore
|
||||
// Not Refactored Yet
|
||||
// store: rootStore
|
||||
readonly property int leftPadding: chatImage.anchors.leftMargin + chatImage.width + chatHorizontalPadding
|
||||
visible: {
|
||||
const urls = linkUrls.split(" ")
|
||||
|
@ -544,7 +543,8 @@ Item {
|
|||
|
||||
sourceComponent: Component {
|
||||
LinksMessageView {
|
||||
store: rootStore
|
||||
// Not Refactored Yet
|
||||
// store: rootStore
|
||||
linkUrls: linkUrls
|
||||
container: root.container
|
||||
isCurrentUser: isCurrentUser
|
||||
|
@ -585,7 +585,8 @@ Item {
|
|||
sourceComponent: Component {
|
||||
id: invitationBubble
|
||||
InvitationBubbleView {
|
||||
store: rootStore
|
||||
// Not Refactored Yet
|
||||
// store: rootStore
|
||||
communityId: root.container.communityId
|
||||
}
|
||||
}
|
||||
|
|
|
@ -16,9 +16,7 @@ Column {
|
|||
anchors.right: !isCurrentUser ? undefined : parent.right
|
||||
z: (typeof chatLogView === "undefined") ? 1 : (chatLogView.count - index)
|
||||
|
||||
property var rootStore
|
||||
property var messageStore
|
||||
//property var chatsModel: !!root.rootStore ? root.rootStore.chatsModelInst : null
|
||||
|
||||
property string messageId: ""
|
||||
property string responseToMessageWithId: ""
|
||||
|
@ -35,6 +33,10 @@ Column {
|
|||
property int messageContentType: 1
|
||||
property bool pinnedMessage: false
|
||||
|
||||
// Used only in case of ChatIdentifier
|
||||
property int chatTypeThisMessageBelongsTo: -1
|
||||
property string chatColorThisMessageBelongsTo: ""
|
||||
|
||||
property int prevMessageIndex: -1
|
||||
property var prevMessageAsJsonObj
|
||||
property int nextMessageIndex: -1
|
||||
|
@ -91,35 +93,18 @@ Column {
|
|||
property bool shouldRepeatHeader: ((parseInt(timestamp, 10) - parseInt(prevMsgTimestamp, 10)) / 60 / 1000) > Constants.repeatHeaderInterval
|
||||
|
||||
//////////////////////////////////////
|
||||
//TODO REMOVE
|
||||
// property string fromAuthor: "0x0011223344556677889910"
|
||||
// property string userName: "Jotaro Kujo"
|
||||
// property string alias: ""
|
||||
// property string localName: ""
|
||||
// property string message: "That's right. We're friends... Of justice, that is."
|
||||
//TODO CHECCK - REMOVE
|
||||
property string plainText: "That's right. We're friends... Of justice, that is."
|
||||
// property string identicon: "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAZAAAAGQAQMAAAC6caSPAAAABlBMVEXMzMz////TjRV2AAAAAWJLR0QB/wIt3gAAACpJREFUGBntwYEAAAAAw6D7Uw/gCtUAAAAAAAAAAAAAAAAAAAAAAAAAgBNPsAABAjKCqQAAAABJRU5ErkJggg=="
|
||||
// property bool isCurrentUser: false
|
||||
// property string timestamp: "1234567"
|
||||
property string sticker: "Qme8vJtyrEHxABcSVGPF95PtozDgUyfr1xGjePmFdZgk9v"
|
||||
// property int contentType: 1 // constants don't work in default props
|
||||
property string chatId: "chatId"
|
||||
// property string outgoingStatus: ""
|
||||
// property string responseTo: ""
|
||||
// property string messageId: ""
|
||||
property string emojiReactions: ""
|
||||
// property int prevMessageIndex: -1
|
||||
// property int nextMessageIndex: -1
|
||||
property bool timeout: false
|
||||
property bool hasMention: false
|
||||
property string linkUrls: ""
|
||||
property bool placeholderMessage: false
|
||||
property bool activityCenterMessage: false
|
||||
// property bool pinnedMessage: false
|
||||
property bool read: true
|
||||
property string pinnedBy
|
||||
property bool forceHoverHandler: false // Used to force the HoverHandler to be active (useful for messages in popups)
|
||||
property string communityId: ""
|
||||
property int stickerPackId: -1
|
||||
property int gapFrom: 0
|
||||
property int gapTo: 0
|
||||
|
@ -128,29 +113,8 @@ Column {
|
|||
property bool isEdited: false
|
||||
property bool showEdit: true
|
||||
property var messageContextMenu
|
||||
// property string displayUserName: {
|
||||
// if (isCurrentUser) {
|
||||
// //% "You"
|
||||
// return qsTrId("You")
|
||||
// }
|
||||
//////////////////////////////////////
|
||||
|
||||
// if (localName !== "") {
|
||||
// return localName
|
||||
// }
|
||||
|
||||
// if (userName !== "") {
|
||||
// return Utils.removeStatusEns(userName)
|
||||
// }
|
||||
// return Utils.removeStatusEns(alias)
|
||||
// }
|
||||
|
||||
// property string authorCurrentMsg: "authorCurrentMsg"
|
||||
// property string authorPrevMsg: "authorPrevMsg"
|
||||
|
||||
// property string prevMsgTimestamp: !!root.chatsModel ? root.chatsModel.messageView.messageList.getMessageData(prevMessageIndex, "timestamp") : ""
|
||||
// property string nextMsgTimestamp: !!root.chatsModel ? root.chatsModel.messageView.messageList.getMessageData(nextMessageIndex, "timestamp"): ""
|
||||
|
||||
// property bool shouldRepeatHeader: ((parseInt(timestamp, 10) - parseInt(prevMsgTimestamp, 10)) / 60 / 1000) > Constants.repeatHeaderInterval
|
||||
|
||||
property bool isEmoji: contentType === Constants.messageContentType.emojiType
|
||||
property bool isImage: contentType === Constants.messageContentType.imageType
|
||||
|
@ -165,30 +129,8 @@ Column {
|
|||
property bool isStatusUpdate: false
|
||||
property int statusAgeEpoch: 0
|
||||
|
||||
// TODO: we don't use replyMessageIndex any more, but messageId
|
||||
// property int replyMessageIndex: !!root.chatsModel ? root.chatsModel.messageView.messageList.getMessageIndex(responseTo) : -1
|
||||
// property string repliedMessageAuthor: replyMessageIndex > -1 ? !!root.chatsModel ? root.chatsModel.messageView.messageList.getMessageData(replyMessageIndex, "userName") : "" : "";
|
||||
// property string repliedMessageAuthorPubkey: replyMessageIndex > -1 ? root.chatsModel.messageView.messageList.getMessageData(replyMessageIndex, "publicKey") : "";
|
||||
// property bool repliedMessageAuthorIsCurrentUser: replyMessageIndex > -1 ? repliedMessageAuthorPubkey === userProfile.pubKey : "";
|
||||
// property bool repliedMessageIsEdited: replyMessageIndex > -1 ? !!root.chatsModel ? root.chatsModel.messageView.messageList.getMessageData(replyMessageIndex, "isEdited") === "true" : false : false;
|
||||
// property string repliedMessageContent: replyMessageIndex > -1 ? !!root.chatsModel ? root.chatsModel.messageView.messageList.getMessageData(replyMessageIndex, "message") : "" : "";
|
||||
// property int repliedMessageType: replyMessageIndex > -1 ? !!root.chatsModel ? parseInt(root.chatsModel.messageView.messageList.getMessageData(replyMessageIndex, "contentType")) : 0 : 0;
|
||||
// property string repliedMessageImage: replyMessageIndex > -1 ? !!root.chatsModel ? root.chatsModel.messageView.messageList.getMessageData(replyMessageIndex, "image") : "" : "";
|
||||
// property string repliedMessageUserIdenticon: replyMessageIndex > -1 ? !!root.chatsModel ? root.chatsModel.messageView.messageList.getMessageData(replyMessageIndex, "identicon") : "" : "";
|
||||
// property string repliedMessageUserImage: replyMessageIndex > -1 ? appMain.getProfileImage(repliedMessageAuthorPubkey, repliedMessageAuthorIsCurrentUser , false) || "" : "";
|
||||
|
||||
property var imageClick: function () {}
|
||||
property var scrollToBottom: function () {}
|
||||
// property string userPubKey: {
|
||||
// if (contentType === Constants.messageContentType.chatIdentifier) {
|
||||
// return chatId
|
||||
// }
|
||||
// return fromAuthor
|
||||
// }
|
||||
// property bool useLargeImage: contentType === Constants.messageContentType.chatIdentifier
|
||||
|
||||
// Not Refactored Yet - This will be determined on the backend
|
||||
// property string profileImageSource: !placeholderMessage && appMain.getProfileImage(userPubKey, isCurrentUser, useLargeImage) || ""
|
||||
|
||||
property var emojiReactionsModel: {
|
||||
// Not Refactored Yet
|
||||
|
@ -327,7 +269,7 @@ Column {
|
|||
id: gapComponent
|
||||
GapComponent {
|
||||
onClicked: {
|
||||
// Not Refactored Yet
|
||||
// Not Refactored Yet - Should do it via messageStore
|
||||
// root.chatsModel.messageView.fillGaps(messageStore.messageId);
|
||||
// root.visible = false;
|
||||
// root.height = 0;
|
||||
|
@ -338,14 +280,14 @@ Column {
|
|||
Component {
|
||||
id: fetchMoreMessagesButtonComponent
|
||||
FetchMoreMessagesButton {
|
||||
// nextMessageIndex: root.messageStore.nextMessageIndex
|
||||
// nextMsgTimestamp: root.messageStore.nextMsgTimestamp
|
||||
nextMessageIndex: root.nextMessageIndex
|
||||
nextMsgTimestamp: root.nextMsgTimestamp
|
||||
onClicked: {
|
||||
// Not Refactored Yet
|
||||
// Not Refactored Yet - Should do it via messageStore
|
||||
// root.chatsModel.messageView.hideLoadingIndicator();
|
||||
}
|
||||
onTimerTriggered: {
|
||||
// Not Refactored Yet
|
||||
// Not Refactored Yet - Should do it via messageStore
|
||||
// root.chatsModel.requestMoreMessages(Constants.fetchRangeLast24Hours);
|
||||
}
|
||||
}
|
||||
|
@ -353,17 +295,13 @@ Column {
|
|||
|
||||
Component {
|
||||
id: channelIdentifierComponent
|
||||
Rectangle {
|
||||
color: "blue"
|
||||
width: 100
|
||||
height: 100
|
||||
ChannelIdentifierView {
|
||||
chatName: root.senderDisplayName
|
||||
chatType: root.chatTypeThisMessageBelongsTo
|
||||
chatColor: root.chatColorThisMessageBelongsTo
|
||||
chatIcon: root.senderIcon
|
||||
chatIconIsIdenticon: root.isSenderIconIdenticon
|
||||
}
|
||||
// Not Refactored Yet
|
||||
// ChannelIdentifierView {
|
||||
// store: root.rootStore
|
||||
// profileImage: profileImageSource
|
||||
// authorCurrentMsg: root.authorCurrentMsg
|
||||
// }
|
||||
}
|
||||
|
||||
// Private group Messages
|
||||
|
@ -402,25 +340,31 @@ Column {
|
|||
StatusUpdateView {
|
||||
statusAgeEpoch: root.statusAgeEpoch
|
||||
container: root
|
||||
store: root.rootStore
|
||||
// Not Refactored Yet
|
||||
// store: root.rootStore
|
||||
messageContextMenu: root.messageContextMenu
|
||||
onAddEmoji: {
|
||||
root.clickMessage(isProfileClick, isSticker, isImage , image, emojiOnly, hideEmojiPicker);
|
||||
}
|
||||
onChatImageClicked: {
|
||||
messageStore.imageClick(image);
|
||||
// Not Refactored Yet - Should do it via messageStore
|
||||
// messageStore.imageClick(image);
|
||||
}
|
||||
onUserNameClicked: {
|
||||
root.parent.clickMessage(isProfileClick);
|
||||
// Not Refactored Yet - Should do it via messageStore
|
||||
// root.parent.clickMessage(isProfileClick);
|
||||
}
|
||||
onEmojiBtnClicked: {
|
||||
root.parent.clickMessage(isProfileClick, isSticker, isImage, image, emojiOnly);
|
||||
// Not Refactored Yet - Should do it via messageStore
|
||||
// root.parent.clickMessage(isProfileClick, isSticker, isImage, image, emojiOnly);
|
||||
}
|
||||
onClickMessage: {
|
||||
root.parent.clickMessage(isProfileClick, isSticker, isImage, image, emojiOnly, hideEmojiPicker, isReply);
|
||||
// Not Refactored Yet - Should do it via messageStore
|
||||
// root.parent.clickMessage(isProfileClick, isSticker, isImage, image, emojiOnly, hideEmojiPicker, isReply);
|
||||
}
|
||||
onSetMessageActive: {
|
||||
root.messageStore.setMessageActive(messageId, active);;
|
||||
// Not Refactored Yet - Should do it via messageStore
|
||||
// root.messageStore.setMessageActive(messageId, active);;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,205 @@
|
|||
import QtQuick 2.3
|
||||
import QtGraphicalEffects 1.13
|
||||
|
||||
import utils 1.0
|
||||
import shared 1.0
|
||||
import shared.panels 1.0
|
||||
import shared.status 1.0
|
||||
import shared.panels.chat 1.0
|
||||
import shared.controls.chat 1.0
|
||||
|
||||
import StatusQ.Controls 0.1
|
||||
|
||||
MouseArea {
|
||||
id: root
|
||||
// property var store
|
||||
property bool hovered: containsMouse
|
||||
property var container
|
||||
property int statusAgeEpoch: 0
|
||||
property var messageContextMenu
|
||||
|
||||
signal userNameClicked(bool isProfileClick)
|
||||
signal setMessageActive(string messageId, bool active)
|
||||
signal emojiBtnClicked(bool isProfileClick, bool isSticker, bool isImage, var image, bool emojiOnly)
|
||||
signal clickMessage(bool isProfileClick, bool isSticker, bool isImage, var image, bool emojiOnly, bool hideEmojiPicker, bool isReply)
|
||||
|
||||
// TODO bring those back and remove dynamic scoping
|
||||
// property var emojiReactionsModel
|
||||
// property string timestamp: ""
|
||||
// property bool isCurrentUser: false
|
||||
// property bool isMessageActive: false
|
||||
// property string userName: ""
|
||||
// property string localName: ""
|
||||
// property string displayUserName: ""
|
||||
// property bool isImage: false
|
||||
// property bool isMessage: false
|
||||
// property string profileImageSource: ""
|
||||
// property string userIdenticon: ""
|
||||
|
||||
anchors.top: parent.top
|
||||
anchors.topMargin: 0
|
||||
height: (isImage ? chatImageContent.height : chatText.height) + chatName.height + 2* Style.current.padding + (emojiReactionsModel.length ? 20 : 0)
|
||||
width: parent.width
|
||||
hoverEnabled: true
|
||||
cursorShape: Qt.PointingHandCursor
|
||||
propagateComposedEvents: true
|
||||
|
||||
signal chatImageClicked(string image)
|
||||
signal addEmoji(bool isProfileClick, bool isSticker, bool isImage , var image, bool emojiOnly, bool hideEmojiPicker)
|
||||
|
||||
onClicked: {
|
||||
mouse.accepted = false
|
||||
}
|
||||
|
||||
Rectangle {
|
||||
id: rootRect
|
||||
anchors.fill: parent
|
||||
radius: Style.current.radius
|
||||
color: root.hovered ? Style.current.border : Style.current.background
|
||||
|
||||
UserImage {
|
||||
id: chatImage
|
||||
active: isMessage || isImage
|
||||
anchors.left: parent.left
|
||||
anchors.leftMargin: Style.current.padding
|
||||
anchors.top: parent.top
|
||||
anchors.topMargin: Style.current.halfPadding
|
||||
// messageContextMenu: root.messageContextMenu
|
||||
// profileImage: root.profileImageSource
|
||||
// isMessage: root.isMessage
|
||||
// identiconImageSource: root.userIdenticon
|
||||
onClickMessage: {
|
||||
root.clickMessage(true, false, false, null, false, false, isReplyImage)
|
||||
}
|
||||
}
|
||||
|
||||
UsernameLabel {
|
||||
id: chatName
|
||||
z: 51
|
||||
visible: chatImage.visible
|
||||
anchors.leftMargin: Style.current.halfPadding
|
||||
anchors.top: chatImage.top
|
||||
anchors.left: chatImage.right
|
||||
label.font.pixelSize: Style.current.primaryTextFontSize
|
||||
// messageContextMenu: root.messageContextMenu
|
||||
// isCurrentUser: root.isCurrentUser
|
||||
// userName: root.userName
|
||||
// localName: root.localName
|
||||
// displayUserName: root.displayUserName
|
||||
onClickMessage: {
|
||||
root.userNameClicked(true);
|
||||
}
|
||||
}
|
||||
|
||||
ChatTimePanel {
|
||||
id: chatTime
|
||||
// statusAgeEpoch is used to trigger Qt property update
|
||||
// since the returned string will be the same in 99% cases, this should not trigger ChatTime re-rendering
|
||||
text: Utils.formatAgeFromTime(timestamp, statusAgeEpoch)
|
||||
visible: chatName.visible
|
||||
anchors.verticalCenter: chatName.verticalCenter
|
||||
anchors.left: chatName.right
|
||||
anchors.leftMargin: Style.current.halfPadding
|
||||
//timestamp: timestamp
|
||||
}
|
||||
|
||||
ChatTextView {
|
||||
id: chatText
|
||||
anchors.top: chatName.visible ? chatName.bottom : chatImage.top
|
||||
anchors.topMargin: chatName.visible ? 6 : 0
|
||||
anchors.left: chatImage.right
|
||||
anchors.leftMargin: Style.current.halfPadding
|
||||
anchors.right: parent.right
|
||||
anchors.rightMargin: Style.current.padding
|
||||
// store: root.store
|
||||
}
|
||||
|
||||
Loader {
|
||||
id: chatImageContent
|
||||
active: isImage
|
||||
anchors.left: chatImage.right
|
||||
anchors.leftMargin: Style.current.halfPadding
|
||||
anchors.top: chatText.bottom
|
||||
z: 51
|
||||
|
||||
sourceComponent: Component {
|
||||
StatusChatImage {
|
||||
imageSource: image
|
||||
imageWidth: 200
|
||||
container: root.container
|
||||
onClicked: {
|
||||
root.chatImageClicked(image);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
StatusFlatRoundButton {
|
||||
id: emojiBtn
|
||||
width: 32
|
||||
height: 32
|
||||
anchors.top: rootRect.top
|
||||
anchors.topMargin: -height / 4
|
||||
anchors.right: rootRect.right
|
||||
anchors.rightMargin: Style.current.halfPadding
|
||||
visible: root.hovered
|
||||
icon.name: "reaction-b"
|
||||
icon.width: 20
|
||||
icon.height: 20
|
||||
type: StatusFlatRoundButton.Type.Tertiary
|
||||
backgroundHoverColor: Style.current.background
|
||||
onClicked: {
|
||||
// Set parent, X & Y positions for the messageContextMenu
|
||||
messageContextMenu.parent = emojiBtn
|
||||
messageContextMenu.setXPosition = function() { return -messageContextMenu.width + emojiBtn.width}
|
||||
messageContextMenu.setYPosition = function() { return -messageContextMenu.height - 4}
|
||||
root.emojiBtnClicked(false, false, false, null, true)
|
||||
}
|
||||
}
|
||||
|
||||
DropShadow {
|
||||
anchors.fill: emojiBtn
|
||||
horizontalOffset: 0
|
||||
verticalOffset: 2
|
||||
radius: 10
|
||||
samples: 12
|
||||
color: "#22000000"
|
||||
source: emojiBtn
|
||||
}
|
||||
|
||||
Loader {
|
||||
id: emojiReactionLoader
|
||||
active: emojiReactionsModel.length
|
||||
sourceComponent: emojiReactionsComponent
|
||||
anchors.left: chatImage.right
|
||||
anchors.leftMargin: Style.current.halfPadding
|
||||
anchors.top: isImage ? chatImageContent.bottom : chatText.bottom
|
||||
anchors.topMargin: Style.current.halfPadding
|
||||
}
|
||||
|
||||
Component {
|
||||
id: emojiReactionsComponent
|
||||
EmojiReactionsPanel {
|
||||
// isMessageActive: root.isMessageActive
|
||||
// emojiReactionsModel: root.emojiReactionsModel
|
||||
onAddEmojiClicked: {
|
||||
root.addEmoji(false, false, false, null, true, false);
|
||||
// Set parent, X & Y positions for the messageContextMenu
|
||||
messageContextMenu.parent = emojiReactionLoader
|
||||
messageContextMenu.setXPosition = function() { return (messageContextMenu.parent.x + 4)}
|
||||
messageContextMenu.setYPosition = function() { return (-messageContextMenu.height - 4)}
|
||||
}
|
||||
onToggleReaction: chatsModel.toggleReaction(messageId, emojiID)
|
||||
|
||||
// onSetMessageActive: {
|
||||
// root.setMessageActive(messageId, active);;
|
||||
// }
|
||||
}
|
||||
}
|
||||
|
||||
Separator {
|
||||
anchors.bottom: parent.bottom
|
||||
visible: !root.hovered
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue