refactor: extract messages from chat view
refactor: extract messages from chat view refactor: extract messages from chat view refactor: extract messages from chat view update references to messageView fix setup remove duplicated method
This commit is contained in:
parent
702f52f6ed
commit
f8e5b25a09
|
@ -36,7 +36,8 @@ proc init*(self: ChatController) =
|
||||||
let pubKey = self.status.settings.getSetting[:string](Setting.PublicKey, "0x0")
|
let pubKey = self.status.settings.getSetting[:string](Setting.PublicKey, "0x0")
|
||||||
let messagesFromContactsOnly = self.status.settings.getSetting[:bool](Setting.MessagesFromContactsOnly, false, true)
|
let messagesFromContactsOnly = self.status.settings.getSetting[:bool](Setting.MessagesFromContactsOnly, false, true)
|
||||||
|
|
||||||
self.view.pubKey = pubKey
|
# self.view.pubKey = pubKey
|
||||||
|
self.view.setPubKey(pubKey)
|
||||||
self.status.chat.init(pubKey, messagesFromContactsOnly)
|
self.status.chat.init(pubKey, messagesFromContactsOnly)
|
||||||
self.status.stickers.init()
|
self.status.stickers.init()
|
||||||
self.view.reactions.init()
|
self.view.reactions.init()
|
||||||
|
|
|
@ -26,7 +26,7 @@ proc handleSignals(self: ChatController) =
|
||||||
for messageId in data.messageIds:
|
for messageId in data.messageIds:
|
||||||
if self.status.messages.messages.hasKey(messageId):
|
if self.status.messages.messages.hasKey(messageId):
|
||||||
let chatId = self.status.messages.messages[messageId].chatId
|
let chatId = self.status.messages.messages[messageId].chatId
|
||||||
self.view.messageList[chatId].checkTimeout(messageId)
|
self.view.messageView.messageList[chatId].checkTimeout(messageId)
|
||||||
|
|
||||||
self.status.events.on(SignalType.CommunityFound.event) do(e: Args):
|
self.status.events.on(SignalType.CommunityFound.event) do(e: Args):
|
||||||
var data = CommunitySignal(e)
|
var data = CommunitySignal(e)
|
||||||
|
@ -41,4 +41,3 @@ proc handleSignals(self: ChatController) =
|
||||||
# TODO: retry mailserver request up to N times or change mailserver
|
# TODO: retry mailserver request up to N times or change mailserver
|
||||||
# If > N, then
|
# If > N, then
|
||||||
self.view.hideLoadingIndicator()
|
self.view.hideLoadingIndicator()
|
||||||
|
|
|
@ -9,7 +9,7 @@ import ../../status/ens as status_ens
|
||||||
import ../../status/chat/[chat, message]
|
import ../../status/chat/[chat, message]
|
||||||
import ../../status/profile/profile
|
import ../../status/profile/profile
|
||||||
import web3/[conversions, ethtypes]
|
import web3/[conversions, ethtypes]
|
||||||
import views/[channels_list, message_list, chat_item, suggestions_list, reactions, stickers, groups, transactions, communities, community_list, community_item, format_input, ens, activity_notification_list, channel]
|
import views/[channels_list, message_list, chat_item, suggestions_list, reactions, stickers, groups, transactions, communities, community_list, community_item, format_input, ens, activity_notification_list, channel, messages]
|
||||||
import ../utils/image_utils
|
import ../utils/image_utils
|
||||||
import ../../status/tasks/[qt, task_runner_impl]
|
import ../../status/tasks/[qt, task_runner_impl]
|
||||||
import ../../status/tasks/marathon/mailserver/worker
|
import ../../status/tasks/marathon/mailserver/worker
|
||||||
|
@ -23,14 +23,10 @@ logScope:
|
||||||
topics = "chats-view"
|
topics = "chats-view"
|
||||||
|
|
||||||
type
|
type
|
||||||
ChatViewRoles {.pure.} = enum
|
|
||||||
MessageList = UserRole + 1
|
|
||||||
GetLinkPreviewDataTaskArg = ref object of QObjectTaskArg
|
GetLinkPreviewDataTaskArg = ref object of QObjectTaskArg
|
||||||
link: string
|
link: string
|
||||||
uuid: string
|
uuid: string
|
||||||
AsyncActivityNotificationLoadTaskArg = ref object of QObjectTaskArg
|
AsyncActivityNotificationLoadTaskArg = ref object of QObjectTaskArg
|
||||||
AsyncMessageLoadTaskArg = ref object of QObjectTaskArg
|
|
||||||
chatId: string
|
|
||||||
|
|
||||||
const getLinkPreviewDataTask: Task = proc(argEncoded: string) {.gcsafe, nimcall.} =
|
const getLinkPreviewDataTask: Task = proc(argEncoded: string) {.gcsafe, nimcall.} =
|
||||||
let arg = decode[GetLinkPreviewDataTaskArg](argEncoded)
|
let arg = decode[GetLinkPreviewDataTaskArg](argEncoded)
|
||||||
|
@ -50,34 +46,6 @@ proc getLinkPreviewData[T](self: T, slot: string, link: string, uuid: string) =
|
||||||
)
|
)
|
||||||
self.status.tasks.threadpool.start(arg)
|
self.status.tasks.threadpool.start(arg)
|
||||||
|
|
||||||
const asyncMessageLoadTask: Task = proc(argEncoded: string) {.gcsafe, nimcall.} =
|
|
||||||
let arg = decode[AsyncMessageLoadTaskArg](argEncoded)
|
|
||||||
var messages: JsonNode
|
|
||||||
var msgCallSuccess: bool
|
|
||||||
let msgCallResult = status_chat.rpcChatMessages(arg.chatId, newJString(""), 20, msgCallSuccess)
|
|
||||||
if(msgCallSuccess):
|
|
||||||
messages = msgCallResult.parseJson()["result"]
|
|
||||||
|
|
||||||
var reactions: JsonNode
|
|
||||||
var reactionsCallSuccess: bool
|
|
||||||
let reactionsCallResult = status_chat.rpcReactions(arg.chatId, newJString(""), 20, reactionsCallSuccess)
|
|
||||||
if(reactionsCallSuccess):
|
|
||||||
reactions = reactionsCallResult.parseJson()["result"]
|
|
||||||
|
|
||||||
var pinnedMessages: JsonNode
|
|
||||||
var pinnedMessagesCallSuccess: bool
|
|
||||||
let pinnedMessagesCallResult = status_chat.rpcPinnedChatMessages(arg.chatId, newJString(""), 20, pinnedMessagesCallSuccess)
|
|
||||||
if(pinnedMessagesCallSuccess):
|
|
||||||
pinnedMessages = pinnedMessagesCallResult.parseJson()["result"]
|
|
||||||
|
|
||||||
let responseJson = %*{
|
|
||||||
"chatId": arg.chatId,
|
|
||||||
"messages": messages,
|
|
||||||
"reactions": reactions,
|
|
||||||
"pinnedMessages": pinnedMessages
|
|
||||||
}
|
|
||||||
arg.finish(responseJson)
|
|
||||||
|
|
||||||
const asyncActivityNotificationLoadTask: Task = proc(argEncoded: string) {.gcsafe, nimcall.} =
|
const asyncActivityNotificationLoadTask: Task = proc(argEncoded: string) {.gcsafe, nimcall.} =
|
||||||
let arg = decode[AsyncActivityNotificationLoadTaskArg](argEncoded)
|
let arg = decode[AsyncActivityNotificationLoadTaskArg](argEncoded)
|
||||||
var activityNotifications: JsonNode
|
var activityNotifications: JsonNode
|
||||||
|
@ -91,15 +59,6 @@ const asyncActivityNotificationLoadTask: Task = proc(argEncoded: string) {.gcsaf
|
||||||
}
|
}
|
||||||
arg.finish(responseJson)
|
arg.finish(responseJson)
|
||||||
|
|
||||||
proc asyncMessageLoad[T](self: T, slot: string, chatId: string) =
|
|
||||||
let arg = AsyncMessageLoadTaskArg(
|
|
||||||
tptr: cast[ByteAddress](asyncMessageLoadTask),
|
|
||||||
vptr: cast[ByteAddress](self.vptr),
|
|
||||||
slot: slot,
|
|
||||||
chatId: chatId
|
|
||||||
)
|
|
||||||
self.status.tasks.threadpool.start(arg)
|
|
||||||
|
|
||||||
proc asyncActivityNotificationLoad[T](self: T, slot: string) =
|
proc asyncActivityNotificationLoad[T](self: T, slot: string) =
|
||||||
let arg = AsyncActivityNotificationLoadTaskArg(
|
let arg = AsyncActivityNotificationLoadTaskArg(
|
||||||
tptr: cast[ByteAddress](asyncActivityNotificationLoadTask),
|
tptr: cast[ByteAddress](asyncActivityNotificationLoadTask),
|
||||||
|
@ -115,21 +74,17 @@ QtObject:
|
||||||
formatInputView: FormatInputView
|
formatInputView: FormatInputView
|
||||||
ensView: EnsView
|
ensView: EnsView
|
||||||
channelView*: ChannelView
|
channelView*: ChannelView
|
||||||
|
messageView*: MessageView
|
||||||
currentSuggestions*: SuggestionsList
|
currentSuggestions*: SuggestionsList
|
||||||
activityNotificationList*: ActivityNotificationList
|
activityNotificationList*: ActivityNotificationList
|
||||||
callResult: string
|
callResult: string
|
||||||
messageList*: OrderedTable[string, ChatMessageList]
|
|
||||||
pinnedMessagesList*: OrderedTable[string, ChatMessageList]
|
|
||||||
reactions*: ReactionView
|
reactions*: ReactionView
|
||||||
stickers*: StickersView
|
stickers*: StickersView
|
||||||
groups*: GroupsView
|
groups*: GroupsView
|
||||||
transactions*: TransactionsView
|
transactions*: TransactionsView
|
||||||
communities*: CommunitiesView
|
communities*: CommunitiesView
|
||||||
replyTo: string
|
replyTo: string
|
||||||
channelOpenTime*: Table[string, int64]
|
|
||||||
connected: bool
|
connected: bool
|
||||||
unreadMessageCnt: int
|
|
||||||
loadingMessages: bool
|
|
||||||
timelineChat: Chat
|
timelineChat: Chat
|
||||||
pubKey*: string
|
pubKey*: string
|
||||||
|
|
||||||
|
@ -140,18 +95,11 @@ QtObject:
|
||||||
self.ensView.delete
|
self.ensView.delete
|
||||||
self.currentSuggestions.delete
|
self.currentSuggestions.delete
|
||||||
self.activityNotificationList.delete
|
self.activityNotificationList.delete
|
||||||
for msg in self.messageList.values:
|
|
||||||
msg.delete
|
|
||||||
for msg in self.pinnedMessagesList.values:
|
|
||||||
msg.delete
|
|
||||||
self.reactions.delete
|
self.reactions.delete
|
||||||
self.stickers.delete
|
self.stickers.delete
|
||||||
self.groups.delete
|
self.groups.delete
|
||||||
self.transactions.delete
|
self.transactions.delete
|
||||||
self.messageList = initOrderedTable[string, ChatMessageList]()
|
|
||||||
self.pinnedMessagesList = initOrderedTable[string, ChatMessageList]()
|
|
||||||
self.communities.delete
|
self.communities.delete
|
||||||
self.channelOpenTime = initTable[string, int64]()
|
|
||||||
self.QAbstractListModel.delete
|
self.QAbstractListModel.delete
|
||||||
|
|
||||||
proc newChatsView*(status: Status): ChatsView =
|
proc newChatsView*(status: Status): ChatsView =
|
||||||
|
@ -161,21 +109,21 @@ QtObject:
|
||||||
result.ensView = newEnsView(status)
|
result.ensView = newEnsView(status)
|
||||||
result.communities = newCommunitiesView(status)
|
result.communities = newCommunitiesView(status)
|
||||||
result.channelView = newChannelView(status, result.communities)
|
result.channelView = newChannelView(status, result.communities)
|
||||||
|
result.messageView = newMessageView(status, result.channelView, result.communities)
|
||||||
result.connected = false
|
result.connected = false
|
||||||
result.currentSuggestions = newSuggestionsList()
|
result.currentSuggestions = newSuggestionsList()
|
||||||
result.activityNotificationList = newActivityNotificationList(status)
|
result.activityNotificationList = newActivityNotificationList(status)
|
||||||
result.messageList = initOrderedTable[string, ChatMessageList]()
|
result.reactions = newReactionView(status, result.messageView.messageList.addr, result.channelView.activeChannel)
|
||||||
result.pinnedMessagesList = initOrderedTable[string, ChatMessageList]()
|
|
||||||
result.reactions = newReactionView(status, result.messageList.addr, result.channelView.activeChannel)
|
|
||||||
result.stickers = newStickersView(status, result.channelView.activeChannel)
|
result.stickers = newStickersView(status, result.channelView.activeChannel)
|
||||||
result.groups = newGroupsView(status,result.channelView.activeChannel)
|
result.groups = newGroupsView(status,result.channelView.activeChannel)
|
||||||
result.transactions = newTransactionsView(status)
|
result.transactions = newTransactionsView(status)
|
||||||
result.unreadMessageCnt = 0
|
|
||||||
result.loadingMessages = false
|
|
||||||
result.messageList[status_utils.getTimelineChatId()] = newChatMessageList(status_utils.getTimelineChatId(), result.status, false)
|
|
||||||
|
|
||||||
result.setup()
|
result.setup()
|
||||||
|
|
||||||
|
proc setPubKey*(self: ChatsView, pubKey: string) =
|
||||||
|
self.pubKey = pubKey
|
||||||
|
self.messageView.pubKey = pubKey
|
||||||
|
|
||||||
proc getFormatInput(self: ChatsView): QVariant {.slot.} = newQVariant(self.formatInputView)
|
proc getFormatInput(self: ChatsView): QVariant {.slot.} = newQVariant(self.formatInputView)
|
||||||
QtProperty[QVariant] formatInputView:
|
QtProperty[QVariant] formatInputView:
|
||||||
read = getFormatInput
|
read = getFormatInput
|
||||||
|
@ -198,70 +146,13 @@ QtObject:
|
||||||
self.channelView.activeChannelChanged()
|
self.channelView.activeChannelChanged()
|
||||||
self.triggerActiveChannelChange()
|
self.triggerActiveChannelChange()
|
||||||
|
|
||||||
proc getMessageListIndexById(self: ChatsView, id: string): int
|
proc getMessageView*(self: ChatsView): QVariant {.slot.} = newQVariant(self.messageView)
|
||||||
|
QtProperty[QVariant] messageView:
|
||||||
proc replaceMentionsWithPubKeys(self: ChatsView, mentions: seq[string], contacts: seq[Profile], message: string, predicate: proc (contact: Profile): string): string =
|
read = getMessageView
|
||||||
var updatedMessage = message
|
|
||||||
for mention in mentions:
|
|
||||||
let matches = contacts.filter(c => "@" & predicate(c).toLowerAscii == mention.toLowerAscii).map(c => c.address)
|
|
||||||
if matches.len > 0:
|
|
||||||
let pubKey = matches[0]
|
|
||||||
var startIndex = 0
|
|
||||||
var index = updatedMessage.find(mention)
|
|
||||||
|
|
||||||
while index > -1:
|
|
||||||
if index == 0 or updatedMessage[index-1] == ' ':
|
|
||||||
updatedMessage = updatedMessage.replaceWord(mention, '@' & pubKey)
|
|
||||||
startIndex = index + mention.len
|
|
||||||
index = updatedMessage.find(mention, startIndex)
|
|
||||||
|
|
||||||
result = updatedMessage
|
|
||||||
|
|
||||||
proc plainText(self: ChatsView, input: string): string {.slot.} =
|
proc plainText(self: ChatsView, input: string): string {.slot.} =
|
||||||
result = plain_text(input)
|
result = plain_text(input)
|
||||||
|
|
||||||
proc sendMessage*(self: ChatsView, message: string, replyTo: string, contentType: int = ContentType.Message.int, isStatusUpdate: bool = false, contactsString: string = "") {.slot.} =
|
|
||||||
let aliasPattern = re(r"(@[A-z][a-z]+ [A-z][a-z]* [A-z][a-z]*)", flags = {reStudy, reIgnoreCase})
|
|
||||||
let ensPattern = re(r"(@\w+(?=(\.stateofus)?\.eth))", flags = {reStudy, reIgnoreCase})
|
|
||||||
let namePattern = re(r"(@\w+)", flags = {reStudy, reIgnoreCase})
|
|
||||||
|
|
||||||
var contacts: seq[Profile]
|
|
||||||
if (contactsString == ""):
|
|
||||||
contacts = self.status.contacts.getContacts()
|
|
||||||
else:
|
|
||||||
let contactsJSON = parseJson(contactsString)
|
|
||||||
contacts = @[]
|
|
||||||
for contact in contactsJSON:
|
|
||||||
contacts.add(Profile(
|
|
||||||
address: contact["address"].str,
|
|
||||||
alias: contact["alias"].str,
|
|
||||||
ensName: contact["ensName"].str
|
|
||||||
))
|
|
||||||
|
|
||||||
let aliasMentions = findAll(message, aliasPattern)
|
|
||||||
let ensMentions = findAll(message, ensPattern)
|
|
||||||
let nameMentions = findAll(message, namePattern)
|
|
||||||
|
|
||||||
var m = self.replaceMentionsWithPubKeys(aliasMentions, contacts, message, (c => c.alias))
|
|
||||||
m = self.replaceMentionsWithPubKeys(ensMentions, contacts, m, (c => c.ensName))
|
|
||||||
m = self.replaceMentionsWithPubKeys(nameMentions, contacts, m, (c => c.ensName.split(".")[0]))
|
|
||||||
|
|
||||||
var channelId = self.channelView.activeChannel.id
|
|
||||||
|
|
||||||
if isStatusUpdate:
|
|
||||||
channelId = "@" & self.pubKey
|
|
||||||
|
|
||||||
self.status.chat.sendMessage(channelId, m, replyTo, contentType)
|
|
||||||
|
|
||||||
proc verifyMessageSent*(self: ChatsView, data: string) {.slot.} =
|
|
||||||
let messageData = data.parseJson
|
|
||||||
self.messageList[messageData["chatId"].getStr].checkTimeout(messageData["id"].getStr)
|
|
||||||
|
|
||||||
proc resendMessage*(self: ChatsView, chatId: string, messageId: string) {.slot.} =
|
|
||||||
self.status.messages.trackMessage(messageId, chatId)
|
|
||||||
self.status.chat.resendMessage(messageId)
|
|
||||||
self.messageList[chatId].resetTimeOut(messageId)
|
|
||||||
|
|
||||||
proc sendImage*(self: ChatsView, imagePath: string, isStatusUpdate: bool = false): string {.slot.} =
|
proc sendImage*(self: ChatsView, imagePath: string, isStatusUpdate: bool = false): string {.slot.} =
|
||||||
result = ""
|
result = ""
|
||||||
try:
|
try:
|
||||||
|
@ -297,12 +188,8 @@ QtObject:
|
||||||
error "Error sending images", msg = e.msg
|
error "Error sending images", msg = e.msg
|
||||||
result = fmt"Error sending images: {e.msg}"
|
result = fmt"Error sending images: {e.msg}"
|
||||||
|
|
||||||
proc sendingMessage*(self: ChatsView) {.signal.}
|
|
||||||
|
|
||||||
proc appReady*(self: ChatsView) {.signal.}
|
proc appReady*(self: ChatsView) {.signal.}
|
||||||
|
|
||||||
proc sendingMessageFailed*(self: ChatsView) {.signal.}
|
|
||||||
|
|
||||||
proc alias*(self: ChatsView, pubKey: string): string {.slot.} =
|
proc alias*(self: ChatsView, pubKey: string): string {.slot.} =
|
||||||
if (pubKey == ""):
|
if (pubKey == ""):
|
||||||
return ""
|
return ""
|
||||||
|
@ -328,49 +215,6 @@ QtObject:
|
||||||
read = getActivityNotificationList
|
read = getActivityNotificationList
|
||||||
notify = activityNotificationsChanged
|
notify = activityNotificationsChanged
|
||||||
|
|
||||||
proc upsertChannel(self: ChatsView, channel: string) =
|
|
||||||
var chat: Chat = nil
|
|
||||||
if self.status.chat.channels.hasKey(channel):
|
|
||||||
chat = self.status.chat.channels[channel]
|
|
||||||
else:
|
|
||||||
chat = self.communities.getChannel(channel)
|
|
||||||
if not self.messageList.hasKey(channel):
|
|
||||||
self.beginInsertRows(newQModelIndex(), self.messageList.len, self.messageList.len)
|
|
||||||
self.messageList[channel] = newChatMessageList(channel, self.status, not chat.isNil and chat.chatType != ChatType.Profile)
|
|
||||||
self.channelOpenTime[channel] = now().toTime.toUnix * 1000
|
|
||||||
self.endInsertRows();
|
|
||||||
if not self.pinnedMessagesList.hasKey(channel):
|
|
||||||
self.pinnedMessagesList[channel] = newChatMessageList(channel, self.status, false)
|
|
||||||
|
|
||||||
proc messagePushed*(self: ChatsView, messageIndex: int) {.signal.}
|
|
||||||
proc newMessagePushed*(self: ChatsView) {.signal.}
|
|
||||||
|
|
||||||
proc messageNotificationPushed*(self: ChatsView, chatId: string, text: string, messageType: string, chatType: int, timestamp: string, identicon: string, username: string, hasMention: bool, isAddedContact: bool, channelName: string) {.signal.}
|
|
||||||
|
|
||||||
proc messagesCleared*(self: ChatsView) {.signal.}
|
|
||||||
|
|
||||||
proc clearMessages*(self: ChatsView, id: string) =
|
|
||||||
let channel = self.channelView.getChannelById(id)
|
|
||||||
if (channel == nil):
|
|
||||||
return
|
|
||||||
self.messageList[id].clear(not channel.isNil and channel.chatType != ChatType.Profile)
|
|
||||||
self.messagesCleared()
|
|
||||||
|
|
||||||
proc isAddedContact*(self: ChatsView, id: string): bool {.slot.} =
|
|
||||||
result = self.status.contacts.isAdded(id)
|
|
||||||
|
|
||||||
proc pushPinnedMessages*(self:ChatsView, pinnedMessages: var seq[Message]) =
|
|
||||||
for msg in pinnedMessages.mitems:
|
|
||||||
self.upsertChannel(msg.chatId)
|
|
||||||
|
|
||||||
var message = self.messageList[msg.chatId].getMessageById(msg.id)
|
|
||||||
message.pinnedBy = msg.pinnedBy
|
|
||||||
message.isPinned = true
|
|
||||||
|
|
||||||
self.pinnedMessagesList[msg.chatId].add(message)
|
|
||||||
# put the message as pinned in the message list
|
|
||||||
self.messageList[msg.chatId].changeMessagePinned(msg.id, true, msg.pinnedBy)
|
|
||||||
|
|
||||||
proc pushActivityCenterNotifications*(self:ChatsView, activityCenterNotifications: seq[ActivityCenterNotification]) =
|
proc pushActivityCenterNotifications*(self:ChatsView, activityCenterNotifications: seq[ActivityCenterNotification]) =
|
||||||
self.activityNotificationList.addActivityNotificationItemsToList(activityCenterNotifications)
|
self.activityNotificationList.addActivityNotificationItemsToList(activityCenterNotifications)
|
||||||
self.activityNotificationsChanged()
|
self.activityNotificationsChanged()
|
||||||
|
@ -386,42 +230,11 @@ QtObject:
|
||||||
self.channelView.activeChannel.setChatItem(self.timelineChat)
|
self.channelView.activeChannel.setChatItem(self.timelineChat)
|
||||||
self.activeChannelChanged()
|
self.activeChannelChanged()
|
||||||
|
|
||||||
proc pushMessages*(self:ChatsView, messages: var seq[Message]) =
|
|
||||||
for msg in messages.mitems:
|
|
||||||
self.upsertChannel(msg.chatId)
|
|
||||||
msg.userName = self.status.chat.getUserName(msg.fromAuthor, msg.alias)
|
|
||||||
var msgIndex:int;
|
|
||||||
if self.status.chat.channels.hasKey(msg.chatId):
|
|
||||||
let chat = self.status.chat.channels[msg.chatId]
|
|
||||||
if (chat.chatType == ChatType.Profile):
|
|
||||||
let timelineChatId = status_utils.getTimelineChatId()
|
|
||||||
self.messageList[timelineChatId].add(msg)
|
|
||||||
if self.channelView.activeChannel.id == timelineChatId: self.activeChannelChanged()
|
|
||||||
msgIndex = self.messageList[timelineChatId].messages.len - 1
|
|
||||||
else:
|
|
||||||
self.messageList[msg.chatId].add(msg)
|
|
||||||
msgIndex = self.messageList[msg.chatId].messages.len - 1
|
|
||||||
self.messagePushed(msgIndex)
|
|
||||||
if self.channelOpenTime.getOrDefault(msg.chatId, high(int64)) < msg.timestamp.parseFloat.fromUnixFloat.toUnix:
|
|
||||||
var channel = self.channelView.chats.getChannelById(msg.chatId)
|
|
||||||
if (channel == nil):
|
|
||||||
channel = self.communities.getChannel(msg.chatId)
|
|
||||||
if (channel == nil):
|
|
||||||
continue
|
|
||||||
|
|
||||||
if msg.chatId == self.channelView.activeChannel.id:
|
|
||||||
discard self.status.chat.markMessagesSeen(msg.chatId, @[msg.id])
|
|
||||||
self.newMessagePushed()
|
|
||||||
|
|
||||||
if not channel.muted:
|
|
||||||
let isAddedContact = channel.chatType.isOneToOne and self.isAddedContact(channel.id)
|
|
||||||
self.messageNotificationPushed(msg.chatId, escape_html(msg.text), msg.messageType, channel.chatType.int, msg.timestamp, msg.identicon, msg.userName, msg.hasMention, isAddedContact, channel.name)
|
|
||||||
|
|
||||||
proc updateUsernames*(self:ChatsView, contacts: seq[Profile]) =
|
proc updateUsernames*(self:ChatsView, contacts: seq[Profile]) =
|
||||||
if contacts.len > 0:
|
if contacts.len > 0:
|
||||||
# Updating usernames for all the messages list
|
# Updating usernames for all the messages list
|
||||||
for k in self.messageList.keys:
|
for k in self.messageView.messageList.keys:
|
||||||
self.messageList[k].updateUsernames(contacts)
|
self.messageView.messageList[k].updateUsernames(contacts)
|
||||||
self.channelView.activeChannel.contactsUpdated()
|
self.channelView.activeChannel.contactsUpdated()
|
||||||
|
|
||||||
proc updateChannelForContacts*(self: ChatsView, contacts: seq[Profile]) =
|
proc updateChannelForContacts*(self: ChatsView, contacts: seq[Profile]) =
|
||||||
|
@ -441,43 +254,9 @@ QtObject:
|
||||||
self.channelView.activeChannel.setChatItem(channel)
|
self.channelView.activeChannel.setChatItem(channel)
|
||||||
self.activeChannelChanged()
|
self.activeChannelChanged()
|
||||||
|
|
||||||
|
|
||||||
proc markMessageAsSent*(self:ChatsView, chat: string, messageId: string) =
|
|
||||||
if self.messageList.contains(chat):
|
|
||||||
self.messageList[chat].markMessageAsSent(messageId)
|
|
||||||
else:
|
|
||||||
error "Message could not be marked as sent", chat, messageId
|
|
||||||
|
|
||||||
proc getMessageIndex(self: ChatsView, chatId: string, messageId: string): int {.slot.} =
|
|
||||||
if (not self.messageList.hasKey(chatId)):
|
|
||||||
return -1
|
|
||||||
result = self.messageList[chatId].getMessageIndex(messageId)
|
|
||||||
|
|
||||||
proc getMessageData(self: ChatsView, chatId: string, index: int, data: string): string {.slot.} =
|
|
||||||
if (not self.messageList.hasKey(chatId)):
|
|
||||||
return
|
|
||||||
|
|
||||||
return self.messageList[chatId].getMessageData(index, data)
|
|
||||||
|
|
||||||
proc getMessageList(self: ChatsView): QVariant {.slot.} =
|
|
||||||
self.upsertChannel(self.channelView.activeChannel.id)
|
|
||||||
return newQVariant(self.messageList[self.channelView.activeChannel.id])
|
|
||||||
|
|
||||||
QtProperty[QVariant] messageList:
|
|
||||||
read = getMessageList
|
|
||||||
notify = triggerActiveChannelChange
|
|
||||||
|
|
||||||
proc getPinnedMessagesList(self: ChatsView): QVariant {.slot.} =
|
|
||||||
self.upsertChannel(self.channelView.activeChannel.id)
|
|
||||||
return newQVariant(self.pinnedMessagesList[self.channelView.activeChannel.id])
|
|
||||||
|
|
||||||
QtProperty[QVariant] pinnedMessagesList:
|
|
||||||
read = getPinnedMessagesList
|
|
||||||
notify = triggerActiveChannelChange
|
|
||||||
|
|
||||||
proc pushChatItem*(self: ChatsView, chatItem: Chat) =
|
proc pushChatItem*(self: ChatsView, chatItem: Chat) =
|
||||||
discard self.channelView.chats.addChatItemToList(chatItem)
|
discard self.channelView.chats.addChatItemToList(chatItem)
|
||||||
self.messagePushed(self.messageList[chatItem.id].messages.len - 1)
|
self.messageView.messagePushed(self.messageView.messageList[chatItem.id].messages.len - 1)
|
||||||
|
|
||||||
proc setTimelineChat*(self: ChatsView, chatItem: Chat) =
|
proc setTimelineChat*(self: ChatsView, chatItem: Chat) =
|
||||||
self.timelineChat = chatItem
|
self.timelineChat = chatItem
|
||||||
|
@ -499,54 +278,9 @@ QtObject:
|
||||||
return -1
|
return -1
|
||||||
selectedChannel.chatType.int
|
selectedChannel.chatType.int
|
||||||
|
|
||||||
proc messagesLoaded*(self: ChatsView) {.signal.}
|
|
||||||
|
|
||||||
proc loadMoreMessages*(self: ChatsView) {.slot.} =
|
|
||||||
trace "Loading more messages", chaId = self.channelView.activeChannel.id
|
|
||||||
self.status.chat.chatMessages(self.channelView.activeChannel.id, false)
|
|
||||||
self.status.chat.chatReactions(self.channelView.activeChannel.id, false)
|
|
||||||
self.messagesLoaded();
|
|
||||||
|
|
||||||
proc loadMoreMessagesWithIndex*(self: ChatsView, channelIndex: int) {.slot.} =
|
|
||||||
if (self.channelView.chats.chats.len == 0): return
|
|
||||||
let selectedChannel = self.channelView.getChannel(channelIndex)
|
|
||||||
if (selectedChannel == nil): return
|
|
||||||
trace "Loading more messages", chaId = selectedChannel.id
|
|
||||||
self.status.chat.chatMessages(selectedChannel.id, false)
|
|
||||||
self.status.chat.chatReactions(selectedChannel.id, false)
|
|
||||||
self.messagesLoaded();
|
|
||||||
|
|
||||||
proc loadingMessagesChanged*(self: ChatsView, value: bool) {.signal.}
|
|
||||||
|
|
||||||
proc asyncMessageLoad*(self: ChatsView, chatId: string) {.slot.} =
|
|
||||||
self.asyncMessageLoad("asyncMessageLoaded", chatId)
|
|
||||||
|
|
||||||
proc asyncActivityNotificationLoad*(self: ChatsView) {.slot.} =
|
proc asyncActivityNotificationLoad*(self: ChatsView) {.slot.} =
|
||||||
self.asyncActivityNotificationLoad("asyncActivityNotificationLoaded")
|
self.asyncActivityNotificationLoad("asyncActivityNotificationLoaded")
|
||||||
|
|
||||||
proc asyncMessageLoaded*(self: ChatsView, rpcResponse: string) {.slot.} =
|
|
||||||
let
|
|
||||||
rpcResponseObj = rpcResponse.parseJson
|
|
||||||
chatId = rpcResponseObj{"chatId"}.getStr
|
|
||||||
|
|
||||||
if chatId == "": # .getStr() returns "" when field is not found
|
|
||||||
return
|
|
||||||
|
|
||||||
let messages = rpcResponseObj{"messages"}
|
|
||||||
if(messages != nil and messages.kind != JNull):
|
|
||||||
let chatMessages = libstatus_chat.parseChatMessagesResponse(messages)
|
|
||||||
self.status.chat.chatMessages(chatId, true, chatMessages[0], chatMessages[1])
|
|
||||||
|
|
||||||
let rxns = rpcResponseObj{"reactions"}
|
|
||||||
if(rxns != nil and rxns.kind != JNull):
|
|
||||||
let reactions = status_chat.parseReactionsResponse(chatId, rxns)
|
|
||||||
self.status.chat.chatReactions(chatId, true, reactions[0], reactions[1])
|
|
||||||
|
|
||||||
let pinnedMsgs = rpcResponseObj{"pinnedMessages"}
|
|
||||||
if(pinnedMsgs != nil and pinnedMsgs.kind != JNull):
|
|
||||||
let pinnedMessages = libstatus_chat.parseChatMessagesResponse(pinnedMsgs)
|
|
||||||
self.status.chat.pinnedMessagesByChatID(chatId, pinnedMessages[0], pinnedMessages[1])
|
|
||||||
|
|
||||||
proc asyncActivityNotificationLoaded*(self: ChatsView, rpcResponse: string) {.slot.} =
|
proc asyncActivityNotificationLoaded*(self: ChatsView, rpcResponse: string) {.slot.} =
|
||||||
let rpcResponseObj = rpcResponse.parseJson
|
let rpcResponseObj = rpcResponse.parseJson
|
||||||
|
|
||||||
|
@ -554,77 +288,32 @@ QtObject:
|
||||||
let activityNotifications = parseActivityCenterNotifications(rpcResponseObj["activityNotifications"])
|
let activityNotifications = parseActivityCenterNotifications(rpcResponseObj["activityNotifications"])
|
||||||
self.status.chat.activityCenterNotifications(activityNotifications[0], activityNotifications[1])
|
self.status.chat.activityCenterNotifications(activityNotifications[0], activityNotifications[1])
|
||||||
|
|
||||||
proc hideLoadingIndicator*(self: ChatsView) {.slot.} =
|
|
||||||
self.loadingMessages = false
|
|
||||||
self.loadingMessagesChanged(false)
|
|
||||||
|
|
||||||
proc setLoadingMessages*(self: ChatsView, value: bool) {.slot.} =
|
|
||||||
self.loadingMessages = value
|
|
||||||
self.loadingMessagesChanged(value)
|
|
||||||
|
|
||||||
proc isLoadingMessages(self: ChatsView): QVariant {.slot.} =
|
|
||||||
return newQVariant(self.loadingMessages)
|
|
||||||
|
|
||||||
QtProperty[QVariant] loadingMessages:
|
|
||||||
read = isLoadingMessages
|
|
||||||
write = setLoadingMessages
|
|
||||||
notify = loadingMessagesChanged
|
|
||||||
|
|
||||||
proc requestMoreMessages*(self: ChatsView, fetchRange: int) {.slot.} =
|
|
||||||
self.loadingMessages = true
|
|
||||||
self.loadingMessagesChanged(true)
|
|
||||||
let mailserverWorker = self.status.tasks.marathon[MailserverWorker().name]
|
|
||||||
let task = RequestMessagesTaskArg( `method`: "requestMoreMessages", chatId: self.channelView.activeChannel.id)
|
|
||||||
mailserverWorker.start(task)
|
|
||||||
|
|
||||||
proc fillGaps*(self: ChatsView, messageId: string) {.slot.} =
|
|
||||||
self.loadingMessages = true
|
|
||||||
self.loadingMessagesChanged(true)
|
|
||||||
discard self.status.mailservers.fillGaps(self.channelView.activeChannel.id, @[messageId])
|
|
||||||
|
|
||||||
proc removeChat*(self: ChatsView, chatId: string) =
|
proc removeChat*(self: ChatsView, chatId: string) =
|
||||||
discard self.channelView.chats.removeChatItemFromList(chatId)
|
discard self.channelView.chats.removeChatItemFromList(chatId)
|
||||||
if (self.messageList.hasKey(chatId)):
|
if (self.messageView.messageList.hasKey(chatId)):
|
||||||
let index = self.getMessageListIndexById(chatId)
|
let index = self.messageView.getMessageListIndexById(chatId)
|
||||||
self.beginRemoveRows(newQModelIndex(), index, index)
|
self.beginRemoveRows(newQModelIndex(), index, index)
|
||||||
self.messageList[chatId].delete
|
self.messageView.messageList[chatId].delete
|
||||||
self.messageList.del(chatId)
|
self.messageView.messageList.del(chatId)
|
||||||
self.endRemoveRows()
|
self.endRemoveRows()
|
||||||
|
|
||||||
proc toggleReaction*(self: ChatsView, messageId: string, emojiId: int) {.slot.} =
|
proc toggleReaction*(self: ChatsView, messageId: string, emojiId: int) {.slot.} =
|
||||||
if self.channelView.activeChannel.id == status_utils.getTimelineChatId():
|
if self.channelView.activeChannel.id == status_utils.getTimelineChatId():
|
||||||
let message = self.messageList[status_utils.getTimelineChatId()].getMessageById(messageId)
|
let message = self.messageView.messageList[status_utils.getTimelineChatId()].getMessageById(messageId)
|
||||||
self.reactions.toggle(messageId, message.chatId, emojiId)
|
self.reactions.toggle(messageId, message.chatId, emojiId)
|
||||||
else:
|
else:
|
||||||
self.reactions.toggle(messageId, self.channelView.activeChannel.id, emojiId)
|
self.reactions.toggle(messageId, self.channelView.activeChannel.id, emojiId)
|
||||||
|
|
||||||
proc removeMessagesFromTimeline*(self: ChatsView, chatId: string) =
|
proc removeMessagesFromTimeline*(self: ChatsView, chatId: string) =
|
||||||
self.messageList[status_utils.getTimelineChatId()].deleteMessagesByChatId(chatId)
|
self.messageView.messageList[status_utils.getTimelineChatId()].deleteMessagesByChatId(chatId)
|
||||||
self.activeChannelChanged()
|
self.channelView.activeChannelChanged()
|
||||||
|
|
||||||
proc unreadMessages*(self: ChatsView): int {.slot.} =
|
|
||||||
result = self.unreadMessageCnt
|
|
||||||
|
|
||||||
proc unreadMessagesCntChanged*(self: ChatsView) {.signal.}
|
|
||||||
|
|
||||||
QtProperty[int] unreadMessagesCount:
|
|
||||||
read = unreadMessages
|
|
||||||
notify = unreadMessagesCntChanged
|
|
||||||
|
|
||||||
proc calculateUnreadMessages*(self: ChatsView) =
|
|
||||||
var unreadTotal = 0
|
|
||||||
for chatItem in self.channelView.chats.chats:
|
|
||||||
unreadTotal = unreadTotal + chatItem.unviewedMessagesCount
|
|
||||||
if unreadTotal != self.unreadMessageCnt:
|
|
||||||
self.unreadMessageCnt = unreadTotal
|
|
||||||
self.unreadMessagesCntChanged()
|
|
||||||
|
|
||||||
proc updateChats*(self: ChatsView, chats: seq[Chat]) =
|
proc updateChats*(self: ChatsView, chats: seq[Chat]) =
|
||||||
for chat in chats:
|
for chat in chats:
|
||||||
if (chat.communityId != ""):
|
if (chat.communityId != ""):
|
||||||
self.communities.updateCommunityChat(chat)
|
self.communities.updateCommunityChat(chat)
|
||||||
return
|
return
|
||||||
self.upsertChannel(chat.id)
|
self.messageView.upsertChannel(chat.id)
|
||||||
self.channelView.chats.updateChat(chat)
|
self.channelView.chats.updateChat(chat)
|
||||||
if(self.channelView.activeChannel.id == chat.id):
|
if(self.channelView.activeChannel.id == chat.id):
|
||||||
self.channelView.activeChannel.setChatItem(chat)
|
self.channelView.activeChannel.setChatItem(chat)
|
||||||
|
@ -633,10 +322,7 @@ QtObject:
|
||||||
if self.channelView.contextChannel.id == chat.id:
|
if self.channelView.contextChannel.id == chat.id:
|
||||||
self.channelView.contextChannel.setChatItem(chat)
|
self.channelView.contextChannel.setChatItem(chat)
|
||||||
self.channelView.contextChannelChanged()
|
self.channelView.contextChannelChanged()
|
||||||
self.calculateUnreadMessages()
|
self.messageView.calculateUnreadMessages()
|
||||||
|
|
||||||
proc deleteMessage*(self: ChatsView, channelId: string, messageId: string) =
|
|
||||||
self.messageList[channelId].deleteMessage(messageId)
|
|
||||||
|
|
||||||
proc isConnected*(self: ChatsView): bool {.slot.} =
|
proc isConnected*(self: ChatsView): bool {.slot.} =
|
||||||
result = self.status.network.isConnected
|
result = self.status.network.isConnected
|
||||||
|
@ -675,80 +361,17 @@ QtObject:
|
||||||
QtProperty[QVariant] transactions:
|
QtProperty[QVariant] transactions:
|
||||||
read = getTransactions
|
read = getTransactions
|
||||||
|
|
||||||
method rowCount*(self: ChatsView, index: QModelIndex = nil): int =
|
|
||||||
result = self.messageList.len
|
|
||||||
|
|
||||||
method data(self: ChatsView, index: QModelIndex, role: int): QVariant =
|
|
||||||
if not index.isValid:
|
|
||||||
return
|
|
||||||
if index.row < 0 or index.row >= self.messageList.len:
|
|
||||||
return
|
|
||||||
return newQVariant(toSeq(self.messageList.values)[index.row])
|
|
||||||
|
|
||||||
method roleNames(self: ChatsView): Table[int, string] =
|
|
||||||
{
|
|
||||||
ChatViewRoles.MessageList.int:"messages"
|
|
||||||
}.toTable
|
|
||||||
|
|
||||||
proc removeMessagesByUserId(self: ChatsView, publicKey: string) {.slot.} =
|
|
||||||
for k in self.messageList.keys:
|
|
||||||
self.messageList[k].removeMessagesByUserId(publicKey)
|
|
||||||
|
|
||||||
proc getMessageListIndex(self: ChatsView): int {.slot.} =
|
|
||||||
var idx = -1
|
|
||||||
for msg in toSeq(self.messageList.values):
|
|
||||||
idx = idx + 1
|
|
||||||
if(self.channelView.activeChannel.id == msg.id): return idx
|
|
||||||
return idx
|
|
||||||
|
|
||||||
proc getMessageListIndexById(self: ChatsView, id: string): int {.slot.} =
|
|
||||||
var idx = -1
|
|
||||||
for msg in toSeq(self.messageList.values):
|
|
||||||
idx = idx + 1
|
|
||||||
if(id == msg.id): return idx
|
|
||||||
return idx
|
|
||||||
|
|
||||||
proc addPinMessage*(self: ChatsView, messageId: string, chatId: string, pinnedBy: string) =
|
|
||||||
self.upsertChannel(chatId)
|
|
||||||
self.messageList[chatId].changeMessagePinned(messageId, true, pinnedBy)
|
|
||||||
var message = self.messageList[chatId].getMessageById(messageId)
|
|
||||||
message.pinnedBy = pinnedBy
|
|
||||||
self.pinnedMessagesList[chatId].add(message)
|
|
||||||
|
|
||||||
proc removePinMessage*(self: ChatsView, messageId: string, chatId: string) =
|
|
||||||
self.upsertChannel(chatId)
|
|
||||||
self.messageList[chatId].changeMessagePinned(messageId, false, "")
|
|
||||||
try:
|
|
||||||
self.pinnedMessagesList[chatId].remove(messageId)
|
|
||||||
except Exception as e:
|
|
||||||
error "Error removing ", msg = e.msg
|
|
||||||
|
|
||||||
proc pinMessage*(self: ChatsView, messageId: string, chatId: string) {.slot.} =
|
|
||||||
self.status.chat.setPinMessage(messageId, chatId, true)
|
|
||||||
self.addPinMessage(messageId, chatId, self.pubKey)
|
|
||||||
|
|
||||||
proc unPinMessage*(self: ChatsView, messageId: string, chatId: string) {.slot.} =
|
|
||||||
self.status.chat.setPinMessage(messageId, chatId, false)
|
|
||||||
self.removePinMessage(messageId, chatId)
|
|
||||||
|
|
||||||
proc addPinnedMessages*(self: ChatsView, pinnedMessages: seq[Message]) =
|
|
||||||
for pinnedMessage in pinnedMessages:
|
|
||||||
if (pinnedMessage.isPinned):
|
|
||||||
self.addPinMessage(pinnedMessage.id, pinnedMessage.localChatId, pinnedMessage.pinnedBy)
|
|
||||||
else:
|
|
||||||
self.removePinMessage(pinnedMessage.id, pinnedMessage.localChatId)
|
|
||||||
|
|
||||||
proc isActiveMailserverResult(self: ChatsView, resultEncoded: string) {.slot.} =
|
proc isActiveMailserverResult(self: ChatsView, resultEncoded: string) {.slot.} =
|
||||||
let isActiveMailserverAvailable = decode[bool](resultEncoded)
|
let isActiveMailserverAvailable = decode[bool](resultEncoded)
|
||||||
if isActiveMailserverAvailable:
|
if isActiveMailserverAvailable:
|
||||||
self.setLoadingMessages(true)
|
self.messageView.setLoadingMessages(true)
|
||||||
let
|
let
|
||||||
mailserverWorker = self.status.tasks.marathon[MailserverWorker().name]
|
mailserverWorker = self.status.tasks.marathon[MailserverWorker().name]
|
||||||
task = RequestMessagesTaskArg(`method`: "requestMessages")
|
task = RequestMessagesTaskArg(`method`: "requestMessages")
|
||||||
mailserverWorker.start(task)
|
mailserverWorker.start(task)
|
||||||
|
|
||||||
proc requestAllHistoricMessagesResult(self: ChatsView, resultEncoded: string) {.slot.} =
|
proc requestAllHistoricMessagesResult(self: ChatsView, resultEncoded: string) {.slot.} =
|
||||||
self.setLoadingMessages(true)
|
self.messageView.setLoadingMessages(true)
|
||||||
|
|
||||||
proc createCommunityChannel*(self: ChatsView, communityId: string, name: string, description: string, categoryId: string): string {.slot.} =
|
proc createCommunityChannel*(self: ChatsView, communityId: string, name: string, description: string, categoryId: string): string {.slot.} =
|
||||||
try:
|
try:
|
||||||
|
@ -789,3 +412,45 @@ QtObject:
|
||||||
proc setActiveChannel*(self: ChatsView, channel: string) {.slot.} =
|
proc setActiveChannel*(self: ChatsView, channel: string) {.slot.} =
|
||||||
self.channelView.setActiveChannel(channel)
|
self.channelView.setActiveChannel(channel)
|
||||||
|
|
||||||
|
# proc activeChannelChanged*(self: ChatsView) =
|
||||||
|
# self.channelView.activeChannelChanged()
|
||||||
|
|
||||||
|
proc requestMoreMessages*(self: ChatsView, fetchRange: int) {.slot.} =
|
||||||
|
self.messageView.loadingMessages = true
|
||||||
|
self.messageView.loadingMessagesChanged(true)
|
||||||
|
let mailserverWorker = self.status.tasks.marathon[MailserverWorker().name]
|
||||||
|
let task = RequestMessagesTaskArg( `method`: "requestMoreMessages", chatId: self.channelView.activeChannel.id)
|
||||||
|
mailserverWorker.start(task)
|
||||||
|
|
||||||
|
proc pushMessages*(self: ChatsView, messages: var seq[Message]) =
|
||||||
|
self.messageView.pushMessages(messages)
|
||||||
|
|
||||||
|
proc pushPinnedMessages*(self: ChatsView, pinnedMessages: var seq[Message]) =
|
||||||
|
self.messageView.pushPinnedMessages(pinnedMessages)
|
||||||
|
|
||||||
|
proc hideLoadingIndicator*(self: ChatsView) {.slot.} =
|
||||||
|
self.messageView.hideLoadingIndicator()
|
||||||
|
|
||||||
|
proc deleteMessage*(self: ChatsView, channelId: string, messageId: string) =
|
||||||
|
self.messageView.deleteMessage(channelId, messageId)
|
||||||
|
|
||||||
|
proc addPinnedMessages*(self: ChatsView, pinnedMessages: seq[Message]) =
|
||||||
|
self.messageView.addPinnedMessages(pinnedMessages)
|
||||||
|
|
||||||
|
proc clearMessages*(self: ChatsView, id: string) =
|
||||||
|
self.messageView.clearMessages(id)
|
||||||
|
|
||||||
|
proc asyncMessageLoad*(self: ChatsView, chatId: string) {.slot.} =
|
||||||
|
self.messageView.asyncMessageLoad(chatId)
|
||||||
|
|
||||||
|
proc calculateUnreadMessages*(self: ChatsView) =
|
||||||
|
self.messageView.calculateUnreadMessages()
|
||||||
|
|
||||||
|
proc sendingMessage*(self: ChatsView) =
|
||||||
|
self.messageView.sendingMessage()
|
||||||
|
|
||||||
|
proc sendingMessageFailed*(self: ChatsView) =
|
||||||
|
self.messageView.sendingMessageFailed()
|
||||||
|
|
||||||
|
proc markMessageAsSent*(self: ChatsView, chat: string, messageId: string) =
|
||||||
|
self.messageView.markMessageAsSent(chat, messageId)
|
||||||
|
|
|
@ -0,0 +1,422 @@
|
||||||
|
import NimQml, Tables, json, sequtils, chronicles, times, re, sugar, strutils, os, strformat, algorithm
|
||||||
|
|
||||||
|
import ../../../status/[status, contacts, types, mailservers]
|
||||||
|
import ../../../status/signals/types as signal_types
|
||||||
|
import ../../../status/ens as status_ens
|
||||||
|
import ../../../status/chat as status_chat
|
||||||
|
import ../../../status/messages as status_messages
|
||||||
|
import ../../../status/utils as status_utils
|
||||||
|
import ../../../status/chat/[chat, message]
|
||||||
|
import ../../../status/profile/profile
|
||||||
|
import ../../../status/tasks/[qt, task_runner_impl]
|
||||||
|
|
||||||
|
import communities, chat_item, channels_list, communities, community_list, message_list, channel
|
||||||
|
|
||||||
|
# TODO: remove me
|
||||||
|
import ../../../status/libstatus/chat as libstatus_chat
|
||||||
|
|
||||||
|
logScope:
|
||||||
|
topics = "messages-view"
|
||||||
|
|
||||||
|
type
|
||||||
|
ChatViewRoles {.pure.} = enum
|
||||||
|
MessageList = UserRole + 1
|
||||||
|
|
||||||
|
type
|
||||||
|
AsyncMessageLoadTaskArg = ref object of QObjectTaskArg
|
||||||
|
chatId: string
|
||||||
|
|
||||||
|
const asyncMessageLoadTask: Task = proc(argEncoded: string) {.gcsafe, nimcall.} =
|
||||||
|
let arg = decode[AsyncMessageLoadTaskArg](argEncoded)
|
||||||
|
var messages: JsonNode
|
||||||
|
var msgCallSuccess: bool
|
||||||
|
let msgCallResult = status_chat.rpcChatMessages(arg.chatId, newJString(""), 20, msgCallSuccess)
|
||||||
|
if(msgCallSuccess):
|
||||||
|
messages = msgCallResult.parseJson()["result"]
|
||||||
|
|
||||||
|
var reactions: JsonNode
|
||||||
|
var reactionsCallSuccess: bool
|
||||||
|
let reactionsCallResult = status_chat.rpcReactions(arg.chatId, newJString(""), 20, reactionsCallSuccess)
|
||||||
|
if(reactionsCallSuccess):
|
||||||
|
reactions = reactionsCallResult.parseJson()["result"]
|
||||||
|
|
||||||
|
var pinnedMessages: JsonNode
|
||||||
|
var pinnedMessagesCallSuccess: bool
|
||||||
|
let pinnedMessagesCallResult = status_chat.rpcPinnedChatMessages(arg.chatId, newJString(""), 20, pinnedMessagesCallSuccess)
|
||||||
|
if(pinnedMessagesCallSuccess):
|
||||||
|
pinnedMessages = pinnedMessagesCallResult.parseJson()["result"]
|
||||||
|
|
||||||
|
let responseJson = %*{
|
||||||
|
"chatId": arg.chatId,
|
||||||
|
"messages": messages,
|
||||||
|
"reactions": reactions,
|
||||||
|
"pinnedMessages": pinnedMessages
|
||||||
|
}
|
||||||
|
arg.finish(responseJson)
|
||||||
|
|
||||||
|
proc asyncMessageLoad[T](self: T, slot: string, chatId: string) =
|
||||||
|
let arg = AsyncMessageLoadTaskArg(
|
||||||
|
tptr: cast[ByteAddress](asyncMessageLoadTask),
|
||||||
|
vptr: cast[ByteAddress](self.vptr),
|
||||||
|
slot: slot,
|
||||||
|
chatId: chatId
|
||||||
|
)
|
||||||
|
self.status.tasks.threadpool.start(arg)
|
||||||
|
|
||||||
|
QtObject:
|
||||||
|
type MessageView* = ref object of QAbstractListModel
|
||||||
|
status: Status
|
||||||
|
messageList*: OrderedTable[string, ChatMessageList]
|
||||||
|
pinnedMessagesList*: OrderedTable[string, ChatMessageList]
|
||||||
|
channelView*: ChannelView
|
||||||
|
communities*: CommunitiesView
|
||||||
|
pubKey*: string
|
||||||
|
loadingMessages*: bool
|
||||||
|
unreadMessageCnt: int
|
||||||
|
channelOpenTime*: Table[string, int64]
|
||||||
|
|
||||||
|
proc setup(self: MessageView) = self.QAbstractListModel.setup
|
||||||
|
proc delete*(self: MessageView) =
|
||||||
|
for msg in self.messageList.values:
|
||||||
|
msg.delete
|
||||||
|
for msg in self.pinnedMessagesList.values:
|
||||||
|
msg.delete
|
||||||
|
self.messageList = initOrderedTable[string, ChatMessageList]()
|
||||||
|
self.pinnedMessagesList = initOrderedTable[string, ChatMessageList]()
|
||||||
|
self.channelOpenTime = initTable[string, int64]()
|
||||||
|
# self.QObject.delete
|
||||||
|
self.QAbstractListModel.delete
|
||||||
|
|
||||||
|
proc newMessageView*(status: Status, channelView: ChannelView, communitiesView: CommunitiesView): MessageView =
|
||||||
|
new(result, delete)
|
||||||
|
result.status = status
|
||||||
|
result.channelView = channelView
|
||||||
|
result.communities = communitiesView
|
||||||
|
result.messageList = initOrderedTable[string, ChatMessageList]()
|
||||||
|
result.pinnedMessagesList = initOrderedTable[string, ChatMessageList]()
|
||||||
|
result.messageList[status_utils.getTimelineChatId()] = newChatMessageList(status_utils.getTimelineChatId(), result.status, false)
|
||||||
|
result.loadingMessages = false
|
||||||
|
result.unreadMessageCnt = 0
|
||||||
|
result.setup
|
||||||
|
|
||||||
|
# proc getMessageListIndexById(self: MessageView, id: string): int
|
||||||
|
|
||||||
|
proc replaceMentionsWithPubKeys(self: MessageView, mentions: seq[string], contacts: seq[Profile], message: string, predicate: proc (contact: Profile): string): string =
|
||||||
|
var updatedMessage = message
|
||||||
|
for mention in mentions:
|
||||||
|
let matches = contacts.filter(c => "@" & predicate(c).toLowerAscii == mention.toLowerAscii).map(c => c.address)
|
||||||
|
if matches.len > 0:
|
||||||
|
let pubKey = matches[0]
|
||||||
|
var startIndex = 0
|
||||||
|
var index = updatedMessage.find(mention)
|
||||||
|
|
||||||
|
while index > -1:
|
||||||
|
if index == 0 or updatedMessage[index-1] == ' ':
|
||||||
|
updatedMessage = updatedMessage.replaceWord(mention, '@' & pubKey)
|
||||||
|
startIndex = index + mention.len
|
||||||
|
index = updatedMessage.find(mention, startIndex)
|
||||||
|
|
||||||
|
result = updatedMessage
|
||||||
|
|
||||||
|
proc sendMessage*(self: MessageView, message: string, replyTo: string, contentType: int = ContentType.Message.int, isStatusUpdate: bool = false, contactsString: string = "") {.slot.} =
|
||||||
|
let aliasPattern = re(r"(@[A-z][a-z]+ [A-z][a-z]* [A-z][a-z]*)", flags = {reStudy, reIgnoreCase})
|
||||||
|
let ensPattern = re(r"(@\w+(?=(\.stateofus)?\.eth))", flags = {reStudy, reIgnoreCase})
|
||||||
|
let namePattern = re(r"(@\w+)", flags = {reStudy, reIgnoreCase})
|
||||||
|
|
||||||
|
var contacts: seq[Profile]
|
||||||
|
if (contactsString == ""):
|
||||||
|
contacts = self.status.contacts.getContacts()
|
||||||
|
else:
|
||||||
|
let contactsJSON = parseJson(contactsString)
|
||||||
|
contacts = @[]
|
||||||
|
for contact in contactsJSON:
|
||||||
|
contacts.add(Profile(
|
||||||
|
address: contact["address"].str,
|
||||||
|
alias: contact["alias"].str,
|
||||||
|
ensName: contact["ensName"].str
|
||||||
|
))
|
||||||
|
|
||||||
|
let aliasMentions = findAll(message, aliasPattern)
|
||||||
|
let ensMentions = findAll(message, ensPattern)
|
||||||
|
let nameMentions = findAll(message, namePattern)
|
||||||
|
|
||||||
|
var m = self.replaceMentionsWithPubKeys(aliasMentions, contacts, message, (c => c.alias))
|
||||||
|
m = self.replaceMentionsWithPubKeys(ensMentions, contacts, m, (c => c.ensName))
|
||||||
|
m = self.replaceMentionsWithPubKeys(nameMentions, contacts, m, (c => c.ensName.split(".")[0]))
|
||||||
|
|
||||||
|
var channelId = self.channelView.activeChannel.id
|
||||||
|
|
||||||
|
if isStatusUpdate:
|
||||||
|
channelId = "@" & self.pubKey
|
||||||
|
|
||||||
|
self.status.chat.sendMessage(channelId, m, replyTo, contentType)
|
||||||
|
|
||||||
|
proc verifyMessageSent*(self: MessageView, data: string) {.slot.} =
|
||||||
|
let messageData = data.parseJson
|
||||||
|
self.messageList[messageData["chatId"].getStr].checkTimeout(messageData["id"].getStr)
|
||||||
|
|
||||||
|
proc resendMessage*(self: MessageView, chatId: string, messageId: string) {.slot.} =
|
||||||
|
self.status.messages.trackMessage(messageId, chatId)
|
||||||
|
self.status.chat.resendMessage(messageId)
|
||||||
|
self.messageList[chatId].resetTimeOut(messageId)
|
||||||
|
|
||||||
|
proc sendingMessage*(self: MessageView) {.signal.}
|
||||||
|
|
||||||
|
proc sendingMessageFailed*(self: MessageView) {.signal.}
|
||||||
|
|
||||||
|
proc messagePushed*(self: MessageView, messageIndex: int) {.signal.}
|
||||||
|
proc newMessagePushed*(self: MessageView) {.signal.}
|
||||||
|
|
||||||
|
proc messagesCleared*(self: MessageView) {.signal.}
|
||||||
|
|
||||||
|
proc clearMessages*(self: MessageView, id: string) =
|
||||||
|
let channel = self.channelView.getChannelById(id)
|
||||||
|
if (channel == nil):
|
||||||
|
return
|
||||||
|
self.messageList[id].clear(not channel.isNil and channel.chatType != ChatType.Profile)
|
||||||
|
self.messagesCleared()
|
||||||
|
|
||||||
|
proc upsertChannel*(self: MessageView, channel: string) =
|
||||||
|
var chat: Chat = nil
|
||||||
|
if self.status.chat.channels.hasKey(channel):
|
||||||
|
chat = self.status.chat.channels[channel]
|
||||||
|
else:
|
||||||
|
chat = self.communities.getChannel(channel)
|
||||||
|
if not self.messageList.hasKey(channel):
|
||||||
|
self.beginInsertRows(newQModelIndex(), self.messageList.len, self.messageList.len)
|
||||||
|
self.messageList[channel] = newChatMessageList(channel, self.status, not chat.isNil and chat.chatType != ChatType.Profile)
|
||||||
|
self.channelOpenTime[channel] = now().toTime.toUnix * 1000
|
||||||
|
self.endInsertRows();
|
||||||
|
if not self.pinnedMessagesList.hasKey(channel):
|
||||||
|
self.pinnedMessagesList[channel] = newChatMessageList(channel, self.status, false)
|
||||||
|
|
||||||
|
proc pushPinnedMessages*(self:MessageView, pinnedMessages: var seq[Message]) =
|
||||||
|
for msg in pinnedMessages.mitems:
|
||||||
|
self.upsertChannel(msg.chatId)
|
||||||
|
|
||||||
|
var message = self.messageList[msg.chatId].getMessageById(msg.id)
|
||||||
|
message.pinnedBy = msg.pinnedBy
|
||||||
|
message.isPinned = true
|
||||||
|
|
||||||
|
self.pinnedMessagesList[msg.chatId].add(message)
|
||||||
|
# put the message as pinned in the message list
|
||||||
|
self.messageList[msg.chatId].changeMessagePinned(msg.id, true, msg.pinnedBy)
|
||||||
|
|
||||||
|
proc isAddedContact*(self: MessageView, id: string): bool {.slot.} =
|
||||||
|
result = self.status.contacts.isAdded(id)
|
||||||
|
|
||||||
|
proc messageNotificationPushed*(self: MessageView, chatId: string, text: string, messageType: string, chatType: int, timestamp: string, identicon: string, username: string, hasMention: bool, isAddedContact: bool, channelName: string) {.signal.}
|
||||||
|
|
||||||
|
proc pushMessages*(self:MessageView, messages: var seq[Message]) =
|
||||||
|
for msg in messages.mitems:
|
||||||
|
self.upsertChannel(msg.chatId)
|
||||||
|
msg.userName = self.status.chat.getUserName(msg.fromAuthor, msg.alias)
|
||||||
|
var msgIndex:int;
|
||||||
|
if self.status.chat.channels.hasKey(msg.chatId):
|
||||||
|
let chat = self.status.chat.channels[msg.chatId]
|
||||||
|
if (chat.chatType == ChatType.Profile):
|
||||||
|
let timelineChatId = status_utils.getTimelineChatId()
|
||||||
|
self.messageList[timelineChatId].add(msg)
|
||||||
|
# if self.channelView.activeChannel.id == timelineChatId: self.activeChannelChanged()
|
||||||
|
if self.channelView.activeChannel.id == timelineChatId: self.channelView.activeChannelChanged()
|
||||||
|
msgIndex = self.messageList[timelineChatId].messages.len - 1
|
||||||
|
else:
|
||||||
|
self.messageList[msg.chatId].add(msg)
|
||||||
|
msgIndex = self.messageList[msg.chatId].messages.len - 1
|
||||||
|
self.messagePushed(msgIndex)
|
||||||
|
if self.channelOpenTime.getOrDefault(msg.chatId, high(int64)) < msg.timestamp.parseFloat.fromUnixFloat.toUnix:
|
||||||
|
var channel = self.channelView.chats.getChannelById(msg.chatId)
|
||||||
|
if (channel == nil):
|
||||||
|
channel = self.communities.getChannel(msg.chatId)
|
||||||
|
if (channel == nil):
|
||||||
|
continue
|
||||||
|
|
||||||
|
if msg.chatId == self.channelView.activeChannel.id:
|
||||||
|
discard self.status.chat.markMessagesSeen(msg.chatId, @[msg.id])
|
||||||
|
self.newMessagePushed()
|
||||||
|
|
||||||
|
if not channel.muted:
|
||||||
|
let isAddedContact = channel.chatType.isOneToOne and self.isAddedContact(channel.id)
|
||||||
|
self.messageNotificationPushed(msg.chatId, escape_html(msg.text), msg.messageType, channel.chatType.int, msg.timestamp, msg.identicon, msg.userName, msg.hasMention, isAddedContact, channel.name)
|
||||||
|
|
||||||
|
proc markMessageAsSent*(self:MessageView, chat: string, messageId: string) =
|
||||||
|
if self.messageList.contains(chat):
|
||||||
|
self.messageList[chat].markMessageAsSent(messageId)
|
||||||
|
else:
|
||||||
|
error "Message could not be marked as sent", chat, messageId
|
||||||
|
|
||||||
|
proc getMessageIndex(self: MessageView, chatId: string, messageId: string): int {.slot.} =
|
||||||
|
if (not self.messageList.hasKey(chatId)):
|
||||||
|
return -1
|
||||||
|
result = self.messageList[chatId].getMessageIndex(messageId)
|
||||||
|
|
||||||
|
proc getMessageData(self: MessageView, chatId: string, index: int, data: string): string {.slot.} =
|
||||||
|
if (not self.messageList.hasKey(chatId)):
|
||||||
|
return
|
||||||
|
|
||||||
|
return self.messageList[chatId].getMessageData(index, data)
|
||||||
|
|
||||||
|
proc getMessageList(self: MessageView): QVariant {.slot.} =
|
||||||
|
self.upsertChannel(self.channelView.activeChannel.id)
|
||||||
|
return newQVariant(self.messageList[self.channelView.activeChannel.id])
|
||||||
|
|
||||||
|
QtProperty[QVariant] messageList:
|
||||||
|
read = getMessageList
|
||||||
|
notify = activeChannelChanged
|
||||||
|
|
||||||
|
proc getPinnedMessagesList(self: MessageView): QVariant {.slot.} =
|
||||||
|
self.upsertChannel(self.channelView.activeChannel.id)
|
||||||
|
return newQVariant(self.pinnedMessagesList[self.channelView.activeChannel.id])
|
||||||
|
|
||||||
|
QtProperty[QVariant] pinnedMessagesList:
|
||||||
|
read = getPinnedMessagesList
|
||||||
|
notify = activeChannelChanged
|
||||||
|
|
||||||
|
proc messagesLoaded*(self: MessageView) {.signal.}
|
||||||
|
|
||||||
|
proc loadMoreMessages*(self: MessageView) {.slot.} =
|
||||||
|
trace "Loading more messages", chaId = self.channelView.activeChannel.id
|
||||||
|
self.status.chat.chatMessages(self.channelView.activeChannel.id, false)
|
||||||
|
self.status.chat.chatReactions(self.channelView.activeChannel.id, false)
|
||||||
|
self.messagesLoaded();
|
||||||
|
|
||||||
|
proc loadMoreMessagesWithIndex*(self: MessageView, channelIndex: int) {.slot.} =
|
||||||
|
if (self.channelView.chats.chats.len == 0): return
|
||||||
|
let selectedChannel = self.channelView.getChannel(channelIndex)
|
||||||
|
if (selectedChannel == nil): return
|
||||||
|
trace "Loading more messages", chaId = selectedChannel.id
|
||||||
|
self.status.chat.chatMessages(selectedChannel.id, false)
|
||||||
|
self.status.chat.chatReactions(selectedChannel.id, false)
|
||||||
|
self.messagesLoaded();
|
||||||
|
|
||||||
|
proc loadingMessagesChanged*(self: MessageView, value: bool) {.signal.}
|
||||||
|
|
||||||
|
proc asyncMessageLoad*(self: MessageView, chatId: string) {.slot.} =
|
||||||
|
self.asyncMessageLoad("asyncMessageLoaded", chatId)
|
||||||
|
|
||||||
|
proc asyncMessageLoaded*(self: MessageView, rpcResponse: string) {.slot.} =
|
||||||
|
let
|
||||||
|
rpcResponseObj = rpcResponse.parseJson
|
||||||
|
chatId = rpcResponseObj{"chatId"}.getStr
|
||||||
|
|
||||||
|
if chatId == "": # .getStr() returns "" when field is not found
|
||||||
|
return
|
||||||
|
|
||||||
|
let messages = rpcResponseObj{"messages"}
|
||||||
|
if(messages != nil and messages.kind != JNull):
|
||||||
|
let chatMessages = libstatus_chat.parseChatMessagesResponse(messages)
|
||||||
|
self.status.chat.chatMessages(chatId, true, chatMessages[0], chatMessages[1])
|
||||||
|
|
||||||
|
let rxns = rpcResponseObj{"reactions"}
|
||||||
|
if(rxns != nil and rxns.kind != JNull):
|
||||||
|
let reactions = status_chat.parseReactionsResponse(chatId, rxns)
|
||||||
|
self.status.chat.chatReactions(chatId, true, reactions[0], reactions[1])
|
||||||
|
|
||||||
|
let pinnedMsgs = rpcResponseObj{"pinnedMessages"}
|
||||||
|
if(pinnedMsgs != nil and pinnedMsgs.kind != JNull):
|
||||||
|
let pinnedMessages = libstatus_chat.parseChatMessagesResponse(pinnedMsgs)
|
||||||
|
self.status.chat.pinnedMessagesByChatID(chatId, pinnedMessages[0], pinnedMessages[1])
|
||||||
|
|
||||||
|
proc hideLoadingIndicator*(self: MessageView) {.slot.} =
|
||||||
|
self.loadingMessages = false
|
||||||
|
self.loadingMessagesChanged(false)
|
||||||
|
|
||||||
|
proc setLoadingMessages*(self: MessageView, value: bool) {.slot.} =
|
||||||
|
self.loadingMessages = value
|
||||||
|
self.loadingMessagesChanged(value)
|
||||||
|
|
||||||
|
proc isLoadingMessages(self: MessageView): QVariant {.slot.} =
|
||||||
|
return newQVariant(self.loadingMessages)
|
||||||
|
|
||||||
|
QtProperty[QVariant] loadingMessages:
|
||||||
|
read = isLoadingMessages
|
||||||
|
write = setLoadingMessages
|
||||||
|
notify = loadingMessagesChanged
|
||||||
|
|
||||||
|
proc fillGaps*(self: MessageView, messageId: string) {.slot.} =
|
||||||
|
self.loadingMessages = true
|
||||||
|
self.loadingMessagesChanged(true)
|
||||||
|
discard self.status.mailservers.fillGaps(self.channelView.activeChannel.id, @[messageId])
|
||||||
|
|
||||||
|
proc unreadMessages*(self: MessageView): int {.slot.} =
|
||||||
|
result = self.unreadMessageCnt
|
||||||
|
|
||||||
|
proc unreadMessagesCntChanged*(self: MessageView) {.signal.}
|
||||||
|
|
||||||
|
QtProperty[int] unreadMessagesCount:
|
||||||
|
read = unreadMessages
|
||||||
|
notify = unreadMessagesCntChanged
|
||||||
|
|
||||||
|
proc calculateUnreadMessages*(self: MessageView) =
|
||||||
|
var unreadTotal = 0
|
||||||
|
for chatItem in self.channelView.chats.chats:
|
||||||
|
unreadTotal = unreadTotal + chatItem.unviewedMessagesCount
|
||||||
|
if unreadTotal != self.unreadMessageCnt:
|
||||||
|
self.unreadMessageCnt = unreadTotal
|
||||||
|
self.unreadMessagesCntChanged()
|
||||||
|
|
||||||
|
proc deleteMessage*(self: MessageView, channelId: string, messageId: string) =
|
||||||
|
self.messageList[channelId].deleteMessage(messageId)
|
||||||
|
|
||||||
|
proc removeMessagesByUserId(self: MessageView, publicKey: string) {.slot.} =
|
||||||
|
for k in self.messageList.keys:
|
||||||
|
self.messageList[k].removeMessagesByUserId(publicKey)
|
||||||
|
|
||||||
|
proc getMessageListIndex(self: MessageView): int {.slot.} =
|
||||||
|
var idx = -1
|
||||||
|
for msg in toSeq(self.messageList.values):
|
||||||
|
idx = idx + 1
|
||||||
|
if(self.channelView.activeChannel.id == msg.id): return idx
|
||||||
|
return idx
|
||||||
|
|
||||||
|
proc getMessageListIndexById*(self: MessageView, id: string): int {.slot.} =
|
||||||
|
var idx = -1
|
||||||
|
for msg in toSeq(self.messageList.values):
|
||||||
|
idx = idx + 1
|
||||||
|
if(id == msg.id): return idx
|
||||||
|
return idx
|
||||||
|
|
||||||
|
proc addPinMessage*(self: MessageView, messageId: string, chatId: string, pinnedBy: string) =
|
||||||
|
self.upsertChannel(chatId)
|
||||||
|
self.messageList[chatId].changeMessagePinned(messageId, true, pinnedBy)
|
||||||
|
var message = self.messageList[chatId].getMessageById(messageId)
|
||||||
|
message.pinnedBy = pinnedBy
|
||||||
|
self.pinnedMessagesList[chatId].add(message)
|
||||||
|
|
||||||
|
proc removePinMessage*(self: MessageView, messageId: string, chatId: string) =
|
||||||
|
self.upsertChannel(chatId)
|
||||||
|
self.messageList[chatId].changeMessagePinned(messageId, false, "")
|
||||||
|
try:
|
||||||
|
self.pinnedMessagesList[chatId].remove(messageId)
|
||||||
|
except Exception as e:
|
||||||
|
error "Error removing ", msg = e.msg
|
||||||
|
|
||||||
|
proc pinMessage*(self: MessageView, messageId: string, chatId: string) {.slot.} =
|
||||||
|
self.status.chat.setPinMessage(messageId, chatId, true)
|
||||||
|
self.addPinMessage(messageId, chatId, self.pubKey)
|
||||||
|
|
||||||
|
proc unPinMessage*(self: MessageView, messageId: string, chatId: string) {.slot.} =
|
||||||
|
self.status.chat.setPinMessage(messageId, chatId, false)
|
||||||
|
self.removePinMessage(messageId, chatId)
|
||||||
|
|
||||||
|
proc addPinnedMessages*(self: MessageView, pinnedMessages: seq[Message]) =
|
||||||
|
for pinnedMessage in pinnedMessages:
|
||||||
|
if (pinnedMessage.isPinned):
|
||||||
|
self.addPinMessage(pinnedMessage.id, pinnedMessage.localChatId, pinnedMessage.pinnedBy)
|
||||||
|
else:
|
||||||
|
self.removePinMessage(pinnedMessage.id, pinnedMessage.localChatId)
|
||||||
|
|
||||||
|
method rowCount*(self: MessageView, index: QModelIndex = nil): int =
|
||||||
|
result = self.messageList.len
|
||||||
|
|
||||||
|
method data(self: MessageView, index: QModelIndex, role: int): QVariant =
|
||||||
|
if not index.isValid:
|
||||||
|
return
|
||||||
|
if index.row < 0 or index.row >= self.messageList.len:
|
||||||
|
return
|
||||||
|
return newQVariant(toSeq(self.messageList.values)[index.row])
|
||||||
|
|
||||||
|
method roleNames(self: MessageView): Table[int, string] =
|
||||||
|
{
|
||||||
|
ChatViewRoles.MessageList.int:"messages"
|
||||||
|
}.toTable
|
|
@ -90,14 +90,14 @@ StackLayout {
|
||||||
property var suggestionsObj: ([])
|
property var suggestionsObj: ([])
|
||||||
|
|
||||||
function addSuggestionFromMessageList(i){
|
function addSuggestionFromMessageList(i){
|
||||||
const contactAddr = chatsModel.messageList.getMessageData(i, "publicKey");
|
const contactAddr = chatsModel.messageView.messageList.getMessageData(i, "publicKey");
|
||||||
if(idMap[contactAddr]) return;
|
if(idMap[contactAddr]) return;
|
||||||
suggestionsObj.push({
|
suggestionsObj.push({
|
||||||
alias: chatsModel.messageList.getMessageData(i, "alias"),
|
alias: chatsModel.messageView.messageList.getMessageData(i, "alias"),
|
||||||
ensName: chatsModel.messageList.getMessageData(i, "ensName"),
|
ensName: chatsModel.messageView.messageList.getMessageData(i, "ensName"),
|
||||||
address: contactAddr,
|
address: contactAddr,
|
||||||
identicon: chatsModel.messageList.getMessageData(i, "identicon"),
|
identicon: chatsModel.messageView.messageList.getMessageData(i, "identicon"),
|
||||||
localNickname: chatsModel.messageList.getMessageData(i, "localName")
|
localNickname: chatsModel.messageView.messageList.getMessageData(i, "localName")
|
||||||
})
|
})
|
||||||
chatInput.suggestionsList.append(suggestionsObj[suggestionsObj.length - 1]);
|
chatInput.suggestionsList.append(suggestionsObj[suggestionsObj.length - 1]);
|
||||||
idMap[contactAddr] = true;
|
idMap[contactAddr] = true;
|
||||||
|
@ -123,7 +123,7 @@ StackLayout {
|
||||||
chatInput.suggestionsList.append(suggestionsObj[suggestionsObj.length - 1]);
|
chatInput.suggestionsList.append(suggestionsObj[suggestionsObj.length - 1]);
|
||||||
idMap[contactAddr] = true;
|
idMap[contactAddr] = true;
|
||||||
}
|
}
|
||||||
const len2 = chatsModel.messageList.rowCount();
|
const len2 = chatsModel.messageView.messageList.rowCount();
|
||||||
for (let f = 0; f < len2; f++) {
|
for (let f = 0; f < len2; f++) {
|
||||||
addSuggestionFromMessageList(f);
|
addSuggestionFromMessageList(f);
|
||||||
}
|
}
|
||||||
|
@ -132,12 +132,12 @@ StackLayout {
|
||||||
function showReplyArea() {
|
function showReplyArea() {
|
||||||
isReply = true;
|
isReply = true;
|
||||||
isImage = false;
|
isImage = false;
|
||||||
let replyMessageIndex = chatsModel.messageList.getMessageIndex(SelectedMessage.messageId);
|
let replyMessageIndex = chatsModel.messageView.messageList.getMessageIndex(SelectedMessage.messageId);
|
||||||
if (replyMessageIndex === -1) return;
|
if (replyMessageIndex === -1) return;
|
||||||
|
|
||||||
let userName = chatsModel.messageList.getMessageData(replyMessageIndex, "userName")
|
let userName = chatsModel.messageView.messageList.getMessageData(replyMessageIndex, "userName")
|
||||||
let message = chatsModel.messageList.getMessageData(replyMessageIndex, "message")
|
let message = chatsModel.messageView.messageList.getMessageData(replyMessageIndex, "message")
|
||||||
let identicon = chatsModel.messageList.getMessageData(replyMessageIndex, "identicon")
|
let identicon = chatsModel.messageView.messageList.getMessageData(replyMessageIndex, "identicon")
|
||||||
|
|
||||||
chatInput.showReplyArea(userName, message, identicon)
|
chatInput.showReplyArea(userName, message, identicon)
|
||||||
}
|
}
|
||||||
|
@ -165,7 +165,7 @@ StackLayout {
|
||||||
isBlocked = profileModel.contacts.isContactBlocked(activeChatId);
|
isBlocked = profileModel.contacts.isContactBlocked(activeChatId);
|
||||||
}
|
}
|
||||||
onContactBlocked: {
|
onContactBlocked: {
|
||||||
chatsModel.removeMessagesByUserId(publicKey)
|
chatsModel.messageView.removeMessagesByUserId(publicKey)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -260,7 +260,7 @@ StackLayout {
|
||||||
Layout.fillHeight: true
|
Layout.fillHeight: true
|
||||||
clip: true
|
clip: true
|
||||||
Repeater {
|
Repeater {
|
||||||
model: chatsModel
|
model: chatsModel.messageView
|
||||||
Loader {
|
Loader {
|
||||||
active: false
|
active: false
|
||||||
sourceComponent: ChatMessages {
|
sourceComponent: ChatMessages {
|
||||||
|
@ -273,7 +273,7 @@ StackLayout {
|
||||||
Connections {
|
Connections {
|
||||||
target: chatsModel.channelView
|
target: chatsModel.channelView
|
||||||
onActiveChannelChanged: {
|
onActiveChannelChanged: {
|
||||||
stackLayoutChatMessages.currentIndex = chatsModel.getMessageListIndex(chatsModel.channelView.activeChannelIndex)
|
stackLayoutChatMessages.currentIndex = chatsModel.messageView.getMessageListIndex(chatsModel.channelView.activeChannelIndex)
|
||||||
if(stackLayoutChatMessages.currentIndex > -1 && !stackLayoutChatMessages.children[stackLayoutChatMessages.currentIndex].active){
|
if(stackLayoutChatMessages.currentIndex > -1 && !stackLayoutChatMessages.children[stackLayoutChatMessages.currentIndex].active){
|
||||||
stackLayoutChatMessages.children[stackLayoutChatMessages.currentIndex].active = true;
|
stackLayoutChatMessages.children[stackLayoutChatMessages.currentIndex].active = true;
|
||||||
}
|
}
|
||||||
|
@ -295,7 +295,7 @@ StackLayout {
|
||||||
}
|
}
|
||||||
|
|
||||||
Connections {
|
Connections {
|
||||||
target: chatsModel
|
target: chatsModel.messageView
|
||||||
onMessagePushed: {
|
onMessagePushed: {
|
||||||
addSuggestionFromMessageList(messageIndex);
|
addSuggestionFromMessageList(messageIndex);
|
||||||
}
|
}
|
||||||
|
@ -323,7 +323,7 @@ StackLayout {
|
||||||
Layout.preferredHeight: height
|
Layout.preferredHeight: height
|
||||||
|
|
||||||
Connections {
|
Connections {
|
||||||
target: chatsModel
|
target: chatsModel.messageView
|
||||||
onLoadingMessagesChanged:
|
onLoadingMessagesChanged:
|
||||||
if(value){
|
if(value){
|
||||||
loadingMessagesIndicator.active = true
|
loadingMessagesIndicator.active = true
|
||||||
|
@ -336,7 +336,7 @@ StackLayout {
|
||||||
|
|
||||||
Loader {
|
Loader {
|
||||||
id: loadingMessagesIndicator
|
id: loadingMessagesIndicator
|
||||||
active: chatsModel.loadingMessages
|
active: chatsModel.messageView.loadingMessages
|
||||||
sourceComponent: loadingIndicator
|
sourceComponent: loadingIndicator
|
||||||
anchors.right: parent.right
|
anchors.right: parent.right
|
||||||
anchors.bottom: chatInput.top
|
anchors.bottom: chatInput.top
|
||||||
|
@ -396,7 +396,7 @@ StackLayout {
|
||||||
let msg = chatsModel.plainText(Emoji.deparse(chatInput.textInput.text))
|
let msg = chatsModel.plainText(Emoji.deparse(chatInput.textInput.text))
|
||||||
if (msg.length > 0){
|
if (msg.length > 0){
|
||||||
msg = chatInput.interpretMessage(msg)
|
msg = chatInput.interpretMessage(msg)
|
||||||
chatsModel.sendMessage(msg, chatInput.isReply ? SelectedMessage.messageId : "", Utils.isOnlyEmoji(msg) ? Constants.emojiType : Constants.messageType, false, JSON.stringify(suggestionsObj));
|
chatsModel.messageView.sendMessage(msg, chatInput.isReply ? SelectedMessage.messageId : "", Utils.isOnlyEmoji(msg) ? Constants.emojiType : Constants.messageType, false, JSON.stringify(suggestionsObj));
|
||||||
if(event) event.accepted = true
|
if(event) event.accepted = true
|
||||||
sendMessageSound.stop();
|
sendMessageSound.stop();
|
||||||
Qt.callLater(sendMessageSound.play);
|
Qt.callLater(sendMessageSound.play);
|
||||||
|
|
|
@ -48,7 +48,7 @@ Rectangle {
|
||||||
|
|
||||||
Item {
|
Item {
|
||||||
property int replyMessageIndex: chatsModel.getMessageIndex(chatId, responseTo)
|
property int replyMessageIndex: chatsModel.getMessageIndex(chatId, responseTo)
|
||||||
property string repliedMessageContent: replyMessageIndex > -1 ? chatsModel.getMessageData(chatId, replyMessageIndex, "message") : "";
|
property string repliedMessageContent: replyMessageIndex > -1 ? chatsModel.messageView.getMessageData(chatId, replyMessageIndex, "message") : "";
|
||||||
|
|
||||||
|
|
||||||
onReplyMessageIndexChanged: {
|
onReplyMessageIndexChanged: {
|
||||||
|
|
|
@ -11,7 +11,7 @@ Item {
|
||||||
height: chatInput.height
|
height: chatInput.height
|
||||||
|
|
||||||
Connections {
|
Connections {
|
||||||
target: chatsModel
|
target: chatsModel.messageView
|
||||||
onLoadingMessagesChanged:
|
onLoadingMessagesChanged:
|
||||||
if(value){
|
if(value){
|
||||||
loadingMessagesIndicator.active = true
|
loadingMessagesIndicator.active = true
|
||||||
|
@ -24,7 +24,7 @@ Item {
|
||||||
|
|
||||||
Loader {
|
Loader {
|
||||||
id: loadingMessagesIndicator
|
id: loadingMessagesIndicator
|
||||||
active: chatsModel.loadingMessages
|
active: chatsModel.messageView.loadingMessages
|
||||||
sourceComponent: loadingIndicator
|
sourceComponent: loadingIndicator
|
||||||
anchors.right: parent.right
|
anchors.right: parent.right
|
||||||
anchors.bottom: chatInput.top
|
anchors.bottom: chatInput.top
|
||||||
|
@ -81,7 +81,7 @@ Item {
|
||||||
let msg = chatsModel.plainText(Emoji.deparse(chatInput.textInput.text))
|
let msg = chatsModel.plainText(Emoji.deparse(chatInput.textInput.text))
|
||||||
if (msg.length > 0){
|
if (msg.length > 0){
|
||||||
msg = chatInput.interpretMessage(msg)
|
msg = chatInput.interpretMessage(msg)
|
||||||
chatsModel.sendMessage(msg, chatInput.isReply ? SelectedMessage.messageId : "", Utils.isOnlyEmoji(msg) ? Constants.emojiType : Constants.messageType, false, JSON.stringify(suggestionsObj));
|
chatsModel.messageView.sendMessage(msg, chatInput.isReply ? SelectedMessage.messageId : "", Utils.isOnlyEmoji(msg) ? Constants.emojiType : Constants.messageType, false, JSON.stringify(suggestionsObj));
|
||||||
if(event) event.accepted = true
|
if(event) event.accepted = true
|
||||||
sendMessageSound.stop();
|
sendMessageSound.stop();
|
||||||
Qt.callLater(sendMessageSound.play);
|
Qt.callLater(sendMessageSound.play);
|
||||||
|
|
|
@ -170,7 +170,7 @@ ScrollView {
|
||||||
}
|
}
|
||||||
|
|
||||||
Connections {
|
Connections {
|
||||||
target: chatsModel
|
target: chatsModel.messageView
|
||||||
onMessagesLoaded: {
|
onMessagesLoaded: {
|
||||||
loadingMessages = false;
|
loadingMessages = false;
|
||||||
}
|
}
|
||||||
|
@ -266,7 +266,7 @@ ScrollView {
|
||||||
property var loadMsgs : Backpressure.oneInTime(chatLogView, 500, function() {
|
property var loadMsgs : Backpressure.oneInTime(chatLogView, 500, function() {
|
||||||
if(loadingMessages) return;
|
if(loadingMessages) return;
|
||||||
loadingMessages = true;
|
loadingMessages = true;
|
||||||
chatsModel.loadMoreMessages();
|
chatsModel.messageView.loadMoreMessages();
|
||||||
});
|
});
|
||||||
|
|
||||||
onContentYChanged: {
|
onContentYChanged: {
|
||||||
|
|
|
@ -83,14 +83,14 @@ Item {
|
||||||
property bool isExpired: (outgoingStatus === "sending" && (Math.floor(timestamp) + 180000) < Date.now())
|
property bool isExpired: (outgoingStatus === "sending" && (Math.floor(timestamp) + 180000) < Date.now())
|
||||||
property bool isStatusUpdate: false
|
property bool isStatusUpdate: false
|
||||||
|
|
||||||
property int replyMessageIndex: chatsModel.messageList.getMessageIndex(responseTo);
|
property int replyMessageIndex: chatsModel.messageView.messageList.getMessageIndex(responseTo);
|
||||||
property string repliedMessageAuthor: replyMessageIndex > -1 ? chatsModel.messageList.getMessageData(replyMessageIndex, "userName") : "";
|
property string repliedMessageAuthor: replyMessageIndex > -1 ? chatsModel.messageView.messageList.getMessageData(replyMessageIndex, "userName") : "";
|
||||||
property string repliedMessageAuthorPubkey: replyMessageIndex > -1 ? chatsModel.messageList.getMessageData(replyMessageIndex, "publicKey") : "";
|
property string repliedMessageAuthorPubkey: replyMessageIndex > -1 ? chatsModel.messageView.messageList.getMessageData(replyMessageIndex, "publicKey") : "";
|
||||||
property bool repliedMessageAuthorIsCurrentUser: replyMessageIndex > -1 ? repliedMessageAuthorPubkey === profileModel.profile.pubKey : "";
|
property bool repliedMessageAuthorIsCurrentUser: replyMessageIndex > -1 ? repliedMessageAuthorPubkey === profileModel.profile.pubKey : "";
|
||||||
property string repliedMessageContent: replyMessageIndex > -1 ? chatsModel.messageList.getMessageData(replyMessageIndex, "message") : "";
|
property string repliedMessageContent: replyMessageIndex > -1 ? chatsModel.messageView.messageList.getMessageData(replyMessageIndex, "message") : "";
|
||||||
property int repliedMessageType: replyMessageIndex > -1 ? parseInt(chatsModel.messageList.getMessageData(replyMessageIndex, "contentType")) : 0;
|
property int repliedMessageType: replyMessageIndex > -1 ? parseInt(chatsModel.messageView.messageList.getMessageData(replyMessageIndex, "contentType")) : 0;
|
||||||
property string repliedMessageImage: replyMessageIndex > -1 ? chatsModel.messageList.getMessageData(replyMessageIndex, "image") : "";
|
property string repliedMessageImage: replyMessageIndex > -1 ? chatsModel.messageView.messageList.getMessageData(replyMessageIndex, "image") : "";
|
||||||
property string repliedMessageUserIdenticon: replyMessageIndex > -1 ? chatsModel.messageList.getMessageData(replyMessageIndex, "identicon") : "";
|
property string repliedMessageUserIdenticon: replyMessageIndex > -1 ? chatsModel.messageView.messageList.getMessageData(replyMessageIndex, "identicon") : "";
|
||||||
property string repliedMessageUserImage: replyMessageIndex > -1 ? appMain.getProfileImage(repliedMessageAuthorPubkey, repliedMessageAuthorIsCurrentUser , false) || "" : "";
|
property string repliedMessageUserImage: replyMessageIndex > -1 ? appMain.getProfileImage(repliedMessageAuthorPubkey, repliedMessageAuthorIsCurrentUser , false) || "" : "";
|
||||||
|
|
||||||
property var imageClick: function () {}
|
property var imageClick: function () {}
|
||||||
|
@ -256,7 +256,7 @@ Item {
|
||||||
cursorShape: Qt.PointingHandCursor
|
cursorShape: Qt.PointingHandCursor
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
onClicked: {
|
onClicked: {
|
||||||
chatsModel.fillGaps(messageId)
|
chatsModel.messageView.fillGaps(messageId)
|
||||||
root.visible = false;
|
root.visible = false;
|
||||||
root.height = 0;
|
root.height = 0;
|
||||||
}
|
}
|
||||||
|
@ -323,7 +323,7 @@ Item {
|
||||||
fetchMoreButton.visible = false;
|
fetchMoreButton.visible = false;
|
||||||
fetchDate.visible = false;
|
fetchDate.visible = false;
|
||||||
timer.setTimeout(function(){
|
timer.setTimeout(function(){
|
||||||
chatsModel.hideLoadingIndicator();
|
chatsModel.messageView.hideLoadingIndicator();
|
||||||
fetchLoaderIndicator.active = false;
|
fetchLoaderIndicator.active = false;
|
||||||
fetchMoreButton.visible = true;
|
fetchMoreButton.visible = true;
|
||||||
fetchDate.visible = true;
|
fetchDate.visible = true;
|
||||||
|
|
|
@ -128,7 +128,7 @@ Loader {
|
||||||
id: stickerId
|
id: stickerId
|
||||||
imageHeight: 56
|
imageHeight: 56
|
||||||
imageWidth: 56
|
imageWidth: 56
|
||||||
stickerData: chatsModel.messageList.getMessageData(replyMessageIndex, "sticker")
|
stickerData: chatsModel.messageView.messageList.getMessageData(replyMessageIndex, "sticker")
|
||||||
contentType: repliedMessageType
|
contentType: repliedMessageType
|
||||||
container: root.container
|
container: root.container
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,7 +14,7 @@ StyledText {
|
||||||
cursorShape: Qt.PointingHandCursor
|
cursorShape: Qt.PointingHandCursor
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
onClicked: {
|
onClicked: {
|
||||||
chatsModel.resendMessage(chatId, messageId)
|
chatsModel.messageView.resendMessage(chatId, messageId)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -52,7 +52,7 @@ StatusIconTabButton {
|
||||||
height: 22
|
height: 22
|
||||||
Text {
|
Text {
|
||||||
id: messageCount
|
id: messageCount
|
||||||
font.pixelSize: chatsModel.unreadMessagesCount > 99 ? 10 : 12
|
font.pixelSize: chatsModel.messageView.unreadMessagesCount > 99 ? 10 : 12
|
||||||
color: Style.current.white
|
color: Style.current.white
|
||||||
anchors.centerIn: parent
|
anchors.centerIn: parent
|
||||||
text: unviewedMessagesCount > 99 ? "99+" : unviewedMessagesCount
|
text: unviewedMessagesCount > 99 ? "99+" : unviewedMessagesCount
|
||||||
|
|
|
@ -195,7 +195,7 @@ ModalPopup {
|
||||||
|
|
||||||
StyledText {
|
StyledText {
|
||||||
id: nbPinMessagesText
|
id: nbPinMessagesText
|
||||||
text: chatsModel.pinnedMessagesList.count
|
text: chatsModel.messageView.pinnedMessagesList.count
|
||||||
anchors.verticalCenter: parent.verticalCenter
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
padding: 0
|
padding: 0
|
||||||
font.pixelSize: 15
|
font.pixelSize: 15
|
||||||
|
|
|
@ -106,7 +106,7 @@ Item {
|
||||||
Connections {
|
Connections {
|
||||||
target: chatsModel.channelView
|
target: chatsModel.channelView
|
||||||
onActiveChannelChanged: {
|
onActiveChannelChanged: {
|
||||||
chatsModel.hideLoadingIndicator()
|
chatsModel.messageView.hideLoadingIndicator()
|
||||||
chatGroupsListView.currentIndex = chatsModel.channelView.activeChannelIndex
|
chatGroupsListView.currentIndex = chatsModel.channelView.activeChannelIndex
|
||||||
SelectedMessage.reset();
|
SelectedMessage.reset();
|
||||||
chatColumn.isReply = false;
|
chatColumn.isReply = false;
|
||||||
|
|
|
@ -17,7 +17,7 @@ PopupMenu {
|
||||||
onTriggered: {
|
onTriggered: {
|
||||||
chatsModel.requestMoreMessages(Constants.fetchRangeLast24Hours)
|
chatsModel.requestMoreMessages(Constants.fetchRangeLast24Hours)
|
||||||
timer.setTimeout(function(){
|
timer.setTimeout(function(){
|
||||||
chatsModel.hideLoadingIndicator()
|
chatsModel.messageView.hideLoadingIndicator()
|
||||||
}, 3000);
|
}, 3000);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -28,7 +28,7 @@ PopupMenu {
|
||||||
onTriggered: {
|
onTriggered: {
|
||||||
chatsModel.requestMoreMessages(Constants.fetchRangeLast2Days)
|
chatsModel.requestMoreMessages(Constants.fetchRangeLast2Days)
|
||||||
timer.setTimeout(function(){
|
timer.setTimeout(function(){
|
||||||
chatsModel.hideLoadingIndicator()
|
chatsModel.messageView.hideLoadingIndicator()
|
||||||
}, 4000);
|
}, 4000);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -39,7 +39,7 @@ PopupMenu {
|
||||||
onTriggered: {
|
onTriggered: {
|
||||||
chatsModel.requestMoreMessages(Constants.fetchRangeLast3Days)
|
chatsModel.requestMoreMessages(Constants.fetchRangeLast3Days)
|
||||||
timer.setTimeout(function(){
|
timer.setTimeout(function(){
|
||||||
chatsModel.hideLoadingIndicator()
|
chatsModel.messageView.hideLoadingIndicator()
|
||||||
}, 5000);
|
}, 5000);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -50,7 +50,7 @@ PopupMenu {
|
||||||
onTriggered: {
|
onTriggered: {
|
||||||
chatsModel.requestMoreMessages(Constants.fetchRangeLast7Days)
|
chatsModel.requestMoreMessages(Constants.fetchRangeLast7Days)
|
||||||
timer.setTimeout(function(){
|
timer.setTimeout(function(){
|
||||||
chatsModel.hideLoadingIndicator()
|
chatsModel.messageView.hideLoadingIndicator()
|
||||||
}, 7000);
|
}, 7000);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -212,7 +212,7 @@ ModalPopup {
|
||||||
}
|
}
|
||||||
|
|
||||||
StatusSettingsLineButton {
|
StatusSettingsLineButton {
|
||||||
property int pinnedCount: chatsModel.pinnedMessagesList.count
|
property int pinnedCount: chatsModel.messageView.pinnedMessagesList.count
|
||||||
|
|
||||||
id: pinnedMessagesBtn
|
id: pinnedMessagesBtn
|
||||||
visible: pinnedCount > 0
|
visible: pinnedCount > 0
|
||||||
|
|
|
@ -143,11 +143,11 @@ PopupMenu {
|
||||||
qsTr("Pin")
|
qsTr("Pin")
|
||||||
onTriggered: {
|
onTriggered: {
|
||||||
if (pinnedMessage) {
|
if (pinnedMessage) {
|
||||||
chatsModel.unPinMessage(messageId, chatsModel.channelView.activeChannel.id)
|
chatsModel.messageView.unPinMessage(messageId, chatsModel.channelView.activeChannel.id)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
chatsModel.pinMessage(messageId, chatsModel.channelView.activeChannel.id)
|
chatsModel.messageView.pinMessage(messageId, chatsModel.channelView.activeChannel.id)
|
||||||
messageContextMenu.close()
|
messageContextMenu.close()
|
||||||
}
|
}
|
||||||
icon.source: "../../../img/pin"
|
icon.source: "../../../img/pin"
|
||||||
|
|
|
@ -55,7 +55,7 @@ ModalPopup {
|
||||||
|
|
||||||
ListView {
|
ListView {
|
||||||
id: pinnedMessageListView
|
id: pinnedMessageListView
|
||||||
model: chatsModel.pinnedMessagesList
|
model: chatsModel.messageView.pinnedMessagesList
|
||||||
height: parent.height
|
height: parent.height
|
||||||
anchors.left: parent.left
|
anchors.left: parent.left
|
||||||
anchors.leftMargin: -Style.current.padding
|
anchors.leftMargin: -Style.current.padding
|
||||||
|
|
|
@ -83,7 +83,7 @@ ScrollView {
|
||||||
var msg = chatsModel.plainText(Emoji.deparse(statusUpdateInput.textInput.text))
|
var msg = chatsModel.plainText(Emoji.deparse(statusUpdateInput.textInput.text))
|
||||||
if (msg.length > 0){
|
if (msg.length > 0){
|
||||||
msg = statusUpdateInput.interpretMessage(msg)
|
msg = statusUpdateInput.interpretMessage(msg)
|
||||||
chatsModel.sendMessage(msg, "", Utils.isOnlyEmoji(msg) ? Constants.emojiType : Constants.messageType, true, "");
|
chatsModel.messageView.sendMessage(msg, "", Utils.isOnlyEmoji(msg) ? Constants.emojiType : Constants.messageType, true, "");
|
||||||
statusUpdateInput.textInput.text = "";
|
statusUpdateInput.textInput.text = "";
|
||||||
if(event) event.accepted = true
|
if(event) event.accepted = true
|
||||||
sendMessageSound.stop()
|
sendMessageSound.stop()
|
||||||
|
@ -97,7 +97,7 @@ ScrollView {
|
||||||
anchors.top: statusUpdateInput.bottom
|
anchors.top: statusUpdateInput.bottom
|
||||||
anchors.topMargin: 40
|
anchors.topMargin: 40
|
||||||
anchors.horizontalCenter: parent.horizontalCenter
|
anchors.horizontalCenter: parent.horizontalCenter
|
||||||
visible: chatsModel.messageList.rowCount() === 0
|
visible: chatsModel.messageView.messageList.rowCount() === 0
|
||||||
}
|
}
|
||||||
|
|
||||||
ListView {
|
ListView {
|
||||||
|
|
|
@ -444,7 +444,7 @@ RowLayout {
|
||||||
checked: !chatsModel.communities.activeCommunity.active && sLayout.currentIndex === Utils.getAppSectionIndex(Constants.chat)
|
checked: !chatsModel.communities.activeCommunity.active && sLayout.currentIndex === Utils.getAppSectionIndex(Constants.chat)
|
||||||
|
|
||||||
Rectangle {
|
Rectangle {
|
||||||
property int badgeCount: chatsModel.unreadMessagesCount + profileModel.contacts.contactRequests.count
|
property int badgeCount: chatsModel.messageView.unreadMessagesCount + profileModel.contacts.contactRequests.count
|
||||||
|
|
||||||
id: chatBadge
|
id: chatBadge
|
||||||
visible: chatBadge.badgeCount > 0
|
visible: chatBadge.badgeCount > 0
|
||||||
|
@ -540,7 +540,7 @@ RowLayout {
|
||||||
Layout.fillHeight: true
|
Layout.fillHeight: true
|
||||||
// Loaders do not have access to the context, so props need to be set
|
// Loaders do not have access to the context, so props need to be set
|
||||||
// Adding a "_" to avoid a binding loop
|
// Adding a "_" to avoid a binding loop
|
||||||
property var _chatsModel: chatsModel
|
property var _chatsModel: chatsModel.messageView
|
||||||
property var _walletModel: walletModel
|
property var _walletModel: walletModel
|
||||||
property var _utilsModel: utilsModel
|
property var _utilsModel: utilsModel
|
||||||
property var _web3Provider: web3Provider
|
property var _web3Provider: web3Provider
|
||||||
|
|
|
@ -20,7 +20,7 @@ Item {
|
||||||
property string address: ""
|
property string address: ""
|
||||||
property bool resultClickable: true
|
property bool resultClickable: true
|
||||||
|
|
||||||
property bool isAddedContact: pubKey != "" ? chatsModel.isAddedContact(pubKey) : false
|
property bool isAddedContact: pubKey != "" ? chatsModel.messageView.isAddedContact(pubKey) : false
|
||||||
|
|
||||||
signal resultClicked(string pubKey)
|
signal resultClicked(string pubKey)
|
||||||
signal addToContactsButtonClicked(string pubKey)
|
signal addToContactsButtonClicked(string pubKey)
|
||||||
|
|
|
@ -151,7 +151,7 @@ Item {
|
||||||
property bool hovered: false
|
property bool hovered: false
|
||||||
|
|
||||||
id: pinnedMessagesGroup
|
id: pinnedMessagesGroup
|
||||||
visible: chatType !== Constants.chatTypePublic && chatsModel.pinnedMessagesList.count > 0
|
visible: chatType !== Constants.chatTypePublic && chatsModel.messageView.pinnedMessagesList.count > 0
|
||||||
width: childrenRect.width
|
width: childrenRect.width
|
||||||
height: vertiSep.height
|
height: vertiSep.height
|
||||||
anchors.left: chatInfo.right
|
anchors.left: chatInfo.right
|
||||||
|
@ -184,7 +184,7 @@ Item {
|
||||||
StyledText {
|
StyledText {
|
||||||
id: nbPinnedMessagesText
|
id: nbPinnedMessagesText
|
||||||
color: pinnedMessagesGroup.hovered ? Style.current.textColor : Style.current.secondaryText
|
color: pinnedMessagesGroup.hovered ? Style.current.textColor : Style.current.secondaryText
|
||||||
text: chatsModel.pinnedMessagesList.count
|
text: chatsModel.messageView.pinnedMessagesList.count
|
||||||
font.pixelSize: 12
|
font.pixelSize: 12
|
||||||
font.underline: pinnedMessagesGroup.hovered
|
font.underline: pinnedMessagesGroup.hovered
|
||||||
anchors.left: pinImg.right
|
anchors.left: pinImg.right
|
||||||
|
|
Loading…
Reference in New Issue