chores(@general): remove leftover code after merge

This commit is contained in:
Anthony Laibe 2022-02-07 10:38:05 +01:00 committed by Anthony Laibe
parent 2ca1b71364
commit 723613a5e0
3 changed files with 0 additions and 1039 deletions

View File

@ -1,249 +0,0 @@
import NimQml, Tables
import algorithm
import status/chat/[chat]
import status/status
import status/accounts
import status/types/[message]
import strutils
type
ChannelsRoles {.pure.} = enum
Name = UserRole + 1,
LastMessage = UserRole + 2
Timestamp = UserRole + 3
UnreadMessages = UserRole + 4
Identicon = UserRole + 5
ChatType = UserRole + 6
Color = UserRole + 7
MentionsCount = UserRole + 8
ContentType = UserRole + 9
Muted = UserRole + 10
Id = UserRole + 11
Description = UserRole + 12
CategoryId = UserRole + 13
Position = UserRole + 14
SyncedFrom = UserRole + 15
SyncedTo = UserRole + 16
QtObject:
type
ChannelsList* = ref object of QAbstractListModel
chats*: seq[Chat]
status: Status
proc setup(self: ChannelsList) = self.QAbstractListModel.setup
proc delete(self: ChannelsList) =
self.chats = @[]
self.QAbstractListModel.delete
proc newChannelsList*(status: Status): ChannelsList =
new(result, delete)
result.chats = @[]
result.status = status
result.setup()
method rowCount*(self: ChannelsList, index: QModelIndex = nil): int = self.chats.len
proc renderBlock(self: ChannelsList, message: Message): string
method data(self: ChannelsList, index: QModelIndex, role: int): QVariant =
if not index.isValid:
return
if index.row < 0 or index.row >= self.chats.len:
return
let chatItem = self.chats[index.row]
let chatItemRole = role.ChannelsRoles
case chatItemRole:
of ChannelsRoles.Name: result = newQVariant(self.status.chat.chatName(chatItem))
of ChannelsRoles.Timestamp: result = newQVariant($chatItem.timestamp)
of ChannelsRoles.LastMessage: result = newQVariant(self.renderBlock(chatItem.lastMessage))
of ChannelsRoles.ContentType: result = newQVariant(chatItem.lastMessage.contentType.int)
of ChannelsRoles.UnreadMessages: result = newQVariant(chatItem.unviewedMessagesCount)
of ChannelsRoles.Identicon: result = newQVariant(chatItem.identicon)
of ChannelsRoles.ChatType: result = newQVariant(chatItem.chatType.int)
of ChannelsRoles.Color: result = newQVariant(chatItem.color)
of ChannelsRoles.MentionsCount: result = newQVariant(chatItem.mentionsCount.int)
of ChannelsRoles.Muted: result = newQVariant(chatItem.muted.bool)
of ChannelsRoles.Id: result = newQVariant($chatItem.id)
of ChannelsRoles.CategoryId: result = newQVariant(chatItem.categoryId)
of ChannelsRoles.Description: result = newQVariant(chatItem.description)
of ChannelsRoles.Position: result = newQVariant(chatItem.position)
of ChannelsRoles.SyncedFrom: result = newQVariant($chatItem.syncedFrom)
of ChannelsRoles.SyncedTo: result = newQVariant($chatItem.syncedTo)
method roleNames(self: ChannelsList): Table[int, string] =
{
ChannelsRoles.Name.int:"name",
ChannelsRoles.Timestamp.int:"timestamp",
ChannelsRoles.LastMessage.int: "lastMessage",
ChannelsRoles.UnreadMessages.int: "unviewedMessagesCount",
ChannelsRoles.Identicon.int: "identicon",
ChannelsRoles.ChatType.int: "chatType",
ChannelsRoles.Color.int: "color",
ChannelsRoles.MentionsCount.int: "mentionsCount",
ChannelsRoles.ContentType.int: "contentType",
ChannelsRoles.Muted.int: "muted",
ChannelsRoles.Id.int: "id",
ChannelsRoles.Description.int: "description",
ChannelsRoles.CategoryId.int: "categoryId",
ChannelsRoles.Position.int: "position",
ChannelsRoles.SyncedFrom.int: "syncedFrom",
ChannelsRoles.SyncedTo.int: "syncedTo",
}.toTable
proc sortChats(x, y: Chat): int =
if x.position < y.position: -1
elif x.position == y.position: 0
else: 1
proc setChats*(self: ChannelsList, chats: seq[Chat]) =
self.beginResetModel()
var copy = chats
copy.sort(sortChats)
self.chats = copy
self.endResetModel()
proc addChatItemToList*(self: ChannelsList, channel: Chat): int =
var found = false
for chat in self.chats:
if chat.id == channel.id:
found = true
break
if not found:
self.beginInsertRows(newQModelIndex(), 0, 0)
self.chats.insert(channel, 0)
self.endInsertRows()
result = 0
proc removeChatItemFromList*(self: ChannelsList, channel: string): int =
let idx = self.chats.findIndexById(channel)
if idx == -1: return
self.beginRemoveRows(newQModelIndex(), idx, idx)
self.chats.delete(idx)
self.endRemoveRows()
result = self.chats.len
proc getChannel*(self: ChannelsList, index: int): Chat =
if index < 0 or index >= self.chats.len:
return nil
result = self.chats[index]
proc getChannelById*(self: ChannelsList, chatId: string): Chat =
for chat in self.chats:
if chat.id == chatId:
return chat
proc getChannelById*(self: ChannelsList, chatId: string, found: var bool): Chat =
found = false
for chat in self.chats:
if chat.id == chatId:
found = true
return chat
proc getChannelByName*(self: ChannelsList, name: string): Chat =
for chat in self.chats:
if chat.name == name:
return chat
return nil
proc upsertChannel(self: ChannelsList, channel: Chat): int =
let idx = self.chats.findIndexById(channel.id)
if idx == -1:
result = self.addChatItemToList(channel)
else:
result = idx
proc getChannelColor*(self: ChannelsList, name: string): string =
let channel = self.getChannelByName(name)
if (channel == nil): return
return channel.color
proc getChannelType*(self: ChannelsList, id: string): int {.slot.} =
let channel = self.getChannelById(id)
if (channel == nil): return ChatType.Unknown.int
return channel.chatType.int
proc updateChat*(self: ChannelsList, channel: Chat) =
let idx = self.upsertChannel(channel)
if idx == -1: return
let topLeft = self.createIndex(idx, 0, nil)
let bottomRight = self.createIndex(idx, 0, nil)
self.chats[idx] = channel
self.dataChanged(topLeft, bottomRight,
@[ChannelsRoles.Name.int,
ChannelsRoles.Description.int,
ChannelsRoles.ContentType.int,
ChannelsRoles.LastMessage.int,
ChannelsRoles.Timestamp.int,
ChannelsRoles.UnreadMessages.int,
ChannelsRoles.Identicon.int,
ChannelsRoles.ChatType.int,
ChannelsRoles.Color.int,
ChannelsRoles.MentionsCount.int,
ChannelsRoles.Muted.int,
ChannelsRoles.Position.int,
ChannelsRoles.SyncedFrom.int,
ChannelsRoles.SyncedTo.int])
proc clearUnreadMessages*(self: ChannelsList, channelId: string) =
let idx = self.chats.findIndexById(channelId)
if idx == -1:
return
let index = self.createIndex(idx, 0, nil)
self.chats[idx].unviewedMessagesCount = 0
self.dataChanged(index, index, @[ChannelsRoles.UnreadMessages.int])
proc clearAllMentionsFromChannelWithId*(self: ChannelsList, channelId: string) =
let idx = self.chats.findIndexById(channelId)
if idx == -1:
return
let index = self.createIndex(idx, 0, nil)
self.chats[idx].mentionsCount = 0
self.chats[idx].unviewedMentionsCount = 0
self.dataChanged(index, index, @[ChannelsRoles.MentionsCount.int])
proc clearAllMentionsFromAllChannels*(self: ChannelsList) =
for c in self.chats:
self.clearAllMentionsFromChannelWithId(c.id)
proc decrementMentions*(self: ChannelsList, channelId: string) =
let idx = self.chats.findIndexById(channelId)
if idx == -1:
return
let index = self.createIndex(idx, 0, nil)
self.chats[idx].mentionsCount.dec
self.chats[idx].unviewedMentionsCount.dec
self.dataChanged(index, index, @[ChannelsRoles.MentionsCount.int])
proc renderInline(self: ChannelsList, elem: TextItem): string =
case elem.textType:
of "mention": result = self.status.chat.userNameOrAlias(elem.literal)
of "link": result = elem.destination
else: result = escape_html(elem.literal)
proc renderBlock(self: ChannelsList, message: Message): string =
for pMsg in message.parsedText:
case pMsg.textType:
of "paragraph":
for children in pMsg.children:
result = result & self.renderInline(children)
else:
result = escape_html(pMsg.literal)

View File

@ -1,482 +0,0 @@
import NimQml, Tables, sets, json, sugar, chronicles, sequtils
import strutils
import status/status
import status/accounts
import status/chat as status_chat
import status/chat/[stickers,chat]
import status/ens
import status/types/[message, profile]
import message_format
import user_list
type
ChatMessageRoles {.pure.} = enum
UserName = UserRole + 1,
Message = UserRole + 2,
Timestamp = UserRole + 3
Identicon = UserRole + 4
IsCurrentUser = UserRole + 5
ContentType = UserRole + 6
Sticker = UserRole + 7
FromAuthor = UserRole + 8
Clock = UserRole + 9
ChatId = UserRole + 10
SectionIdentifier = UserRole + 11
Id = UserRole + 12
OutgoingStatus = UserRole + 13
ResponseTo = UserRole + 14
PlainText = UserRole + 15
Index = UserRole + 16
Timeout = UserRole + 18
Image = UserRole + 19
Audio = UserRole + 20
AudioDurationMs = UserRole + 21
EmojiReactions = UserRole + 22
CommandParameters = UserRole + 23
LinkUrls = UserRole + 24
Alias = UserRole + 25
LocalName = UserRole + 26
CommunityId = UserRole + 27
HasMention = UserRole + 28
StickerPackId = UserRole + 29
IsPinned = UserRole + 30
PinnedBy = UserRole + 31
GapFrom = UserRole + 32
GapTo = UserRole + 33
Replace = UserRole + 34
IsEdited = UserRole + 35
Hide = UserRole + 36
QtObject:
type
ChatMessageList* = ref object of QAbstractListModel
messages*: seq[Message]
status: Status
id*: string
messageIndex: Table[string, int]
isEdited*: Table[string, bool]
messageReactions*: Table[string, string]
timedoutMessages: HashSet[string]
userList*: UserListView
loadingHistoryMessages: bool
initialMessagesLoaded: bool
blockedContacts: seq[string]
proc delete*(self: ChatMessageList) =
self.messages = @[]
self.isEdited = initTable[string, bool]()
self.messageIndex = initTable[string, int]()
self.timedoutMessages = initHashSet[string]()
self.QAbstractListModel.delete
proc fetchMoreMessagesButton(self: ChatMessageList): Message =
result = Message()
result.contentType = ContentType.FetchMoreMessagesButton;
proc chatIdentifier(self: ChatMessageList, chatId:string): Message =
result = Message()
result.contentType = ContentType.ChatIdentifier;
result.chatId = chatId
proc addFakeMessages*(self: ChatMessageList) =
self.messages.add(self.fetchMoreMessagesButton())
self.messages.add(self.chatIdentifier(self.id))
proc setup*(self: ChatMessageList, chatId: string, status: Status, addFakeMessages: bool, blockedContacts: seq[string]) =
self.messages = @[]
self.id = chatId
self.loadingHistoryMessages = false
self.initialMessagesLoaded = false
if addFakeMessages:
self.addFakeMessages()
self.messageIndex = initTable[string, int]()
self.timedoutMessages = initHashSet[string]()
self.isEdited = initTable[string, bool]()
self.userList = newUserListView(status)
self.status = status
self.blockedContacts = blockedContacts
self.QAbstractListModel.setup
proc newChatMessageList*(chatId: string, status: Status, addFakeMessages: bool, blockedContacts: seq[string] = @[]): ChatMessageList =
new(result, delete)
result.setup(chatId, status, addFakeMessages, blockedContacts)
#################################################
# Properties
#################################################
proc loadingHistoryMessagesChanged*(self: ChatMessageList) {.signal.}
proc setLoadingHistoryMessages*(self: ChatMessageList, value: bool) =
if (value == self.loadingHistoryMessages):
return
self.loadingHistoryMessages = value
self.loadingHistoryMessagesChanged()
proc getLoadingHistoryMessages*(self: ChatMessageList): QVariant {.slot.} =
return newQVariant(self.loadingHistoryMessages)
QtProperty[QVariant] loadingHistoryMessages:
read = getLoadingHistoryMessages
notify = loadingHistoryMessagesChanged
proc initialMessagesLoadedChanged*(self: ChatMessageList) {.signal.}
proc setInitialMessagesLoaded*(self: ChatMessageList, value: bool) =
if (value == self.initialMessagesLoaded):
return
self.initialMessagesLoaded = value
self.initialMessagesLoadedChanged()
proc getInitialMessagesLoaded*(self: ChatMessageList): QVariant {.slot.} =
return newQVariant(self.initialMessagesLoaded)
QtProperty[QVariant] initialMessagesLoaded:
read = getInitialMessagesLoaded
notify = initialMessagesLoadedChanged
proc countChanged*(self: ChatMessageList) {.signal.}
proc count*(self: ChatMessageList): int {.slot.} =
self.messages.len
QtProperty[int] count:
read = count
notify = countChanged
proc hasMessage*(self: ChatMessageList, messageId: string): bool =
return self.messageIndex.hasKey(messageId)
proc getMessage*(self: ChatMessageList, messageId: string): Message =
return self.messages[self.messageIndex[messageId]]
proc deleteMessage*(self: ChatMessageList, messageId: string): bool =
if not self.messageIndex.hasKey(messageId):
return false
let messageIndex = self.messageIndex[messageId]
self.beginRemoveRows(newQModelIndex(), messageIndex, messageIndex)
self.messages.delete(messageIndex)
self.messageIndex.del(messageId)
self.messageReactions.del(messageId)
# update indexes
for i in countup(0, self.messages.len - 1):
self.messageIndex[self.messages[i].id] = i
self.endRemoveRows()
self.countChanged()
return true
proc deleteMessagesByChatId*(self: ChatMessageList, chatId: string) =
let messages = self.messages.filter(m => m.chatId == chatId)
for message in messages:
discard self.deleteMessage(message.id)
proc toggleMessage*(self: ChatMessageList, messageId: string, hide: bool) =
let msgIdx = self.messageIndex[messageId]
let topLeft = self.createIndex(msgIdx, 0, nil)
let bottomRight = self.createIndex(msgIdx, 0, nil)
self.messages[msgIdx].hide = hide
self.dataChanged(topLeft, bottomRight, @[ChatMessageRoles.Hide.int])
proc replaceMessage*(self: ChatMessageList, message: Message) =
let msgIdx = self.messageIndex[message.id]
let topLeft = self.createIndex(msgIdx, 0, nil)
let bottomRight = self.createIndex(msgIdx, 0, nil)
self.messages[msgIdx].parsedText = message.parsedText
self.messages[msgIdx].text = message.text
self.dataChanged(topLeft, bottomRight, @[ChatMessageRoles.Message.int, ChatMessageRoles.PlainText.int, ChatMessageRoles.IsEdited.int])
proc resetTimeOut*(self: ChatMessageList, messageId: string) =
if not self.messageIndex.hasKey(messageId): return
let msgIdx = self.messageIndex[messageId]
self.timedoutMessages.excl(messageId)
let topLeft = self.createIndex(msgIdx, 0, nil)
let bottomRight = self.createIndex(msgIdx, 0, nil)
self.dataChanged(topLeft, bottomRight, @[ChatMessageRoles.Timeout.int])
proc checkTimeout*(self: ChatMessageList, messageId: string) =
if not self.messageIndex.hasKey(messageId): return
let msgIdx = self.messageIndex[messageId]
if self.messages[msgIdx].outgoingStatus != "sending": return
self.timedoutMessages.incl(messageId)
let topLeft = self.createIndex(msgIdx, 0, nil)
let bottomRight = self.createIndex(msgIdx, 0, nil)
self.dataChanged(topLeft, bottomRight, @[ChatMessageRoles.Timeout.int])
method rowCount(self: ChatMessageList, index: QModelIndex = nil): int =
return self.messages.len
proc getReactions*(self:ChatMessageList, messageId: string):string =
if not self.messageReactions.hasKey(messageId): return ""
result = self.messageReactions[messageId]
method data(self: ChatMessageList, index: QModelIndex, role: int): QVariant =
if not index.isValid:
return
if index.row < 0 or index.row >= self.messages.len:
return
let message = self.messages[index.row]
let chatMessageRole = role.ChatMessageRoles
let isEdited = if self.isEdited.hasKey(message.id): self.isEdited[message.id] else: false
case chatMessageRole:
of ChatMessageRoles.UserName: result = newQVariant(message.userName)
of ChatMessageRoles.Message: result = newQVariant(renderBlock(message, self.status.chat.getContacts()))
of ChatMessageRoles.PlainText: result = newQVariant(message.text)
of ChatMessageRoles.Timestamp: result = newQVariant(message.timestamp)
of ChatMessageRoles.Clock: result = newQVariant($message.clock)
of ChatMessageRoles.Identicon: result = newQVariant(message.identicon)
of ChatMessageRoles.IsCurrentUser: result = newQVariant(message.isCurrentUser)
of ChatMessageRoles.ContentType: result = newQVariant(message.contentType.int)
of ChatMessageRoles.Sticker: result = newQVariant(message.stickerHash.decodeContentHash())
of ChatMessageRoles.StickerPackId: result = newQVariant(message.stickerPackId)
of ChatMessageRoles.FromAuthor: result = newQVariant(message.fromAuthor)
of ChatMessageRoles.ChatId: result = newQVariant(message.chatId)
of ChatMessageRoles.SectionIdentifier: result = newQVariant(sectionIdentifier(message))
of ChatMessageRoles.Id: result = newQVariant(message.id)
of ChatMessageRoles.OutgoingStatus: result = newQVariant(message.outgoingStatus)
of ChatMessageRoles.ResponseTo: result = newQVariant(message.responseTo)
of ChatMessageRoles.Index: result = newQVariant(index.row)
of ChatMessageRoles.Timeout: result = newQVariant(self.timedoutMessages.contains(message.id))
of ChatMessageRoles.Image: result = newQVariant(message.image)
of ChatMessageRoles.Audio: result = newQVariant(message.audio)
of ChatMessageRoles.AudioDurationMs: result = newQVariant(message.audioDurationMs)
of ChatMessageRoles.EmojiReactions: result = newQVariant(self.getReactions(message.id))
of ChatMessageRoles.LinkUrls: result = newQVariant(message.linkUrls)
of ChatMessageRoles.CommunityId: result = newQVariant(message.communityId)
of ChatMessageRoles.HasMention: result = newQVariant(message.hasMention)
of ChatMessageRoles.IsPinned: result = newQVariant(message.isPinned)
of ChatMessageRoles.PinnedBy: result = newQVariant(message.pinnedBy)
# Pass the command parameters as a JSON string
of ChatMessageRoles.CommandParameters: result = newQVariant($(%*{
"id": message.commandParameters.id,
"fromAddress": message.commandParameters.fromAddress,
"address": message.commandParameters.address,
"contract": message.commandParameters.contract,
"value": message.commandParameters.value,
"transactionHash": message.commandParameters.transactionHash,
"commandState": message.commandParameters.commandState,
"signature": message.commandParameters.signature
}))
of ChatMessageRoles.Alias: result = newQVariant(message.alias)
of ChatMessageRoles.LocalName: result = newQVariant(message.localName)
of ChatMessageRoles.GapFrom: result = newQVariant(message.gapFrom)
of ChatMessageRoles.GapTo: result = newQVariant(message.gapTo)
of ChatMessageRoles.Replace: result = newQVariant(message.replace)
of ChatMessageRoles.IsEdited: result = newQVariant(isEdited)
of ChatMessageRoles.Hide: result = newQVariant(message.hide)
method roleNames(self: ChatMessageList): Table[int, string] =
{
ChatMessageRoles.UserName.int:"userName",
ChatMessageRoles.Message.int:"message",
ChatMessageRoles.PlainText.int:"plainText",
ChatMessageRoles.Timestamp.int:"timestamp",
ChatMessageRoles.Clock.int:"clock",
ChatMessageRoles.Identicon.int:"identicon",
ChatMessageRoles.IsCurrentUser.int:"isCurrentUser",
ChatMessageRoles.ContentType.int:"contentType",
ChatMessageRoles.Sticker.int:"sticker",
ChatMessageRoles.FromAuthor.int:"fromAuthor",
ChatMessageRoles.ChatId.int:"chatId",
ChatMessageRoles.SectionIdentifier.int: "sectionIdentifier",
ChatMessageRoles.Id.int: "messageId",
ChatMessageRoles.OutgoingStatus.int: "outgoingStatus",
ChatMessageRoles.ResponseTo.int: "responseTo",
ChatMessageRoles.Index.int: "index",
ChatMessageRoles.Timeout.int: "timeout",
ChatMessageRoles.Image.int: "image",
ChatMessageRoles.Audio.int: "audio",
ChatMessageRoles.AudioDurationMs.int: "audioDurationMs",
ChatMessageRoles.EmojiReactions.int: "emojiReactions",
ChatMessageRoles.LinkUrls.int: "linkUrls",
ChatMessageRoles.CommandParameters.int: "commandParameters",
ChatMessageRoles.CommunityId.int: "communityId",
ChatMessageRoles.Alias.int:"alias",
ChatMessageRoles.HasMention.int:"hasMention",
ChatMessageRoles.IsPinned.int:"isPinned",
ChatMessageRoles.PinnedBy.int:"pinnedBy",
ChatMessageRoles.LocalName.int:"localName",
ChatMessageRoles.StickerPackId.int:"stickerPackId",
ChatMessageRoles.GapFrom.int:"gapFrom",
ChatMessageRoles.GapTo.int:"gapTo",
ChatMessageRoles.Replace.int:"replaces",
ChatMessageRoles.IsEdited.int:"isEdited",
ChatMessageRoles.Hide.int:"hide"
}.toTable
proc getMessageIndex*(self: ChatMessageList, messageId: string): int {.slot.} =
if not self.messageIndex.hasKey(messageId): return -1
result = self.messageIndex[messageId]
# TODO: see how to use data() instead of this function
proc getMessageData*(self: ChatMessageList, index: int, data: string): string {.slot.} =
if index < 0 or index >= self.messages.len: return ("")
let message = self.messages[index]
case data:
of "userName": result = message.userName
of "publicKey": result = message.fromAuthor
of "alias": result = message.alias
of "localName": result = message.localName
of "ensName": result = message.ensName
of "message": result = (renderBlock(message, self.status.chat.getContacts()))
of "identicon": result = message.identicon
of "timestamp": result = $(message.timestamp)
of "image": result = $(message.image)
of "contentType": result = $(message.contentType.int)
of "sticker": result = $(message.stickerHash.decodeContentHash())
of "isEdited": result = if self.isEdited.hasKey(message.id): $self.isEdited[message.id] else: $false
else: result = ("")
proc contains*(self: ChatMessageList, message: Message):bool =
return self.messageIndex.hasKey(message.id)
proc addChatMembers*(self: ChatMessageList, members: seq[ChatMember]) =
self.userList.add(members)
proc add*(self: ChatMessageList, message: var Message) =
if self.messageIndex.hasKey(message.id) and message.editedAt == "0": return # duplicated msg
# don't show blocked contact messages
if self.blockedContacts.contains(message.fromAuthor):
message.hide = true
if message.editedAt != "0":
self.isEdited[message.id] = true
if self.messageIndex.hasKey(message.id):
self.replaceMessage(message)
return
self.userList.add(message)
self.beginInsertRows(newQModelIndex(), self.messages.len, self.messages.len)
self.messageIndex[message.id] = self.messages.len
self.messages.add(message)
self.endInsertRows()
self.countChanged()
proc add*(self: ChatMessageList, messages: var seq[Message]) =
self.beginInsertRows(newQModelIndex(), self.messages.len, self.messages.len + messages.len - 1)
for message in messages.mitems:
if self.messageIndex.hasKey(message.id): continue
if self.blockedContacts.contains(message.fromAuthor):
message.hide = true
self.messageIndex[message.id] = self.messages.len
self.messages.add(message)
self.userList.add(message)
self.endInsertRows()
self.countChanged()
proc remove*(self: ChatMessageList, messageId: string) =
if not self.messageIndex.hasKey(messageId): return
let index = self.getMessageIndex(messageId)
self.beginRemoveRows(newQModelIndex(), index, index)
self.messages.delete(index)
self.messageIndex.del(messageId)
self.endRemoveRows()
self.countChanged()
proc getMessageById*(self: ChatMessageList, messageId: string): Message =
if (not self.messageIndex.hasKey(messageId)): return
return self.messages[self.messageIndex[messageId]]
proc clear*(self: ChatMessageList, addFakeMessages: bool = true) =
self.beginResetModel()
self.messages = @[]
self.messageIndex.clear
if (addFakeMessages):
self.addFakeMessages()
self.endResetModel()
self.countChanged()
proc setMessageReactions*(self: ChatMessageList, messageId: string, newReactions: string)=
self.messageReactions[messageId] = newReactions
if not self.messageIndex.hasKey(messageId): return
let msgIdx = self.messageIndex[messageId]
let topLeft = self.createIndex(msgIdx, 0, nil)
let bottomRight = self.createIndex(msgIdx, 0, nil)
self.dataChanged(topLeft, bottomRight, @[ChatMessageRoles.EmojiReactions.int])
proc changeMessagePinned*(self: ChatMessageList, messageId: string, pinned: bool, pinnedBy: string): bool {.discardable.} =
if not self.messageIndex.hasKey(messageId): return false
let msgIdx = self.messageIndex[messageId]
if msgIdx < 0: return false
if msgIdx >= self.messages.len: return false
var message = self.messages[msgIdx]
message.isPinned = pinned
message.pinnedBy = pinnedBy
self.messages[msgIdx] = message
let topLeft = self.createIndex(msgIdx, 0, nil)
let bottomRight = self.createIndex(msgIdx, 0, nil)
self.dataChanged(topLeft, bottomRight, @[ChatMessageRoles.IsPinned.int, ChatMessageRoles.PinnedBy.int])
return true
proc markMessageAsSent*(self: ChatMessageList, messageId: string)=
let topLeft = self.createIndex(0, 0, nil)
let bottomRight = self.createIndex(self.messages.len, 0, nil)
for m in self.messages.mitems:
if m.id == messageId:
m.outgoingStatus = "sent"
break
self.dataChanged(topLeft, bottomRight, @[ChatMessageRoles.OutgoingStatus.int])
proc updateUsernames*(self: ChatMessageList, contacts: seq[Profile]) =
let topLeft = self.createIndex(0, 0, nil)
let bottomRight = self.createIndex(self.messages.len, 0, nil)
# TODO: change this once the contact list uses a table
for c in contacts:
for m in self.messages.mitems:
if m.fromAuthor == c.id:
m.userName = userNameOrAlias(c)
if c.alias != "":
m.alias = c.alias
m.localName = c.localNickname
self.userList.updateUsernames(c.id, m.username, m.alias, m.localname)
self.dataChanged(topLeft, bottomRight, @[ChatMessageRoles.Username.int])
proc toggleMessagesFromUser*(self: ChatMessageList, publicKey: string, hide: bool) =
var msgIdxToDelete: seq[string] = @[]
for m in self.messages.mitems:
if m.fromAuthor == publicKey:
m.hide = hide
self.toggleMessage(m.id, hide)
proc blockContact*(self: ChatMessageList, contactId: string) =
self.blockedContacts.add contactId
self.toggleMessagesFromUser contactId, true
proc unblockContact*(self: ChatMessageList, contactId: string) =
self.blockedContacts.keepItIf(it != contactId)
self.toggleMessagesFromUser contactId, false
proc getID*(self: ChatMessageList):string {.slot.} =
self.id
proc getUserList*(self: ChatMessageList): QVariant {.slot.} =
newQVariant(self.userList)
QtProperty[QVariant] userList:
read = getUserList
proc getMessageIdWhichReplacedMessageWithId*(self: ChatMessageList, replacedMessageId: string): string =
## Returns id of the message which replaced a message with a certain id.
## Returns message id as a string or an empty string if there is no such message.
for message in self.messages:
if (message.replace == replacedMessageId):
return message.id

View File

@ -1,308 +0,0 @@
import NimQml
import Tables
import json
import sequtils
import strutils
import status/ens as status_ens
import status/utils as status_utils
import status/[status, settings, wallet]
import status/wallet
import status/types/[setting, transaction, rpc_response]
import ../../core/[main]
import ../../core/tasks/[qt, threadpool]
import sets
import web3/ethtypes
import chronicles
type
EnsRoles {.pure.} = enum
UserName = UserRole + 1
IsPending = UserRole + 2
ValidateTaskArg = ref object of QObjectTaskArg
ens: string
isStatus: bool
usernames: seq[string]
DetailsTaskArg = ref object of QObjectTaskArg
username: string
const validateTask: Task = proc(argEncoded: string) {.gcsafe, nimcall.} =
let
arg = decode[ValidateTaskArg](argEncoded)
var output = status_ens.validateEnsName(arg.ens, arg.isStatus, arg.usernames)
arg.finish(output)
proc validate[T](self: T, slot: string, ens: string, isStatus: bool, usernames: seq[string]) =
let arg = ValidateTaskArg(
tptr: cast[ByteAddress](validateTask),
vptr: cast[ByteAddress](self.vptr),
slot: slot,
ens: ens,
isStatus: isStatus,
usernames: usernames
)
self.statusFoundation.threadpool.start(arg)
const detailsTask: Task = proc(argEncoded: string) {.gcsafe, nimcall.} =
let
arg = decode[DetailsTaskArg](argEncoded)
address = status_ens.address(arg.username)
pubkey = status_ens.pubkey(arg.username)
var isStatus:bool = false
var expirationTime:int = 0
if arg.username.endsWith(domain):
isStatus = true
var success = false
expirationTime = status_ens.getExpirationTime(arg.username.replace(domain, ""), success)
let json = %* {
"ensName": arg.username,
"address": address,
"pubkey": pubkey,
"isStatus": isStatus,
"expirationTime": expirationTime
}
arg.finish(json)
proc details[T](self: T, slot: string, username: string) =
let arg = DetailsTaskArg(
tptr: cast[ByteAddress](detailsTask),
vptr: cast[ByteAddress](self.vptr),
slot: slot,
username: username
)
self.statusFoundation.threadpool.start(arg)
QtObject:
type EnsManager* = ref object of QAbstractListModel
usernames*: seq[string]
pendingUsernames*: HashSet[string]
status: Status
statusFoundation: StatusFoundation
proc setup(self: EnsManager) = self.QAbstractListModel.setup
proc delete(self: EnsManager) =
self.usernames = @[]
self.QAbstractListModel.delete
proc newEnsManager*(status: Status, statusFoundation: StatusFoundation): EnsManager =
new(result, delete)
result.usernames = @[]
result.status = status
result.statusFoundation = statusFoundation
result.pendingUsernames = initHashSet[string]()
result.setup
proc getFirstEnsUsername(self: EnsManager): string {.slot.} =
if self.usernames.len > 0:
return self.usernames[0]
return ""
proc firstEnsUsernameChanged(self: EnsManager) {.signal.}
QtProperty[string] firstEnsUsername:
read = getFirstEnsUsername
notify = firstEnsUsernameChanged
proc init*(self: EnsManager) =
self.usernames = getSetting[seq[string]](self.status.settings, Setting.Usernames, @[])
# Get pending ens names
let pendingTransactions = self.status.wallet.getPendingTransactions()
if (pendingTransactions == ""):
return
for trx in pendingTransactions.parseJson{"result"}.getElems():
if trx["type"].getStr == $PendingTransactionType.RegisterENS or trx["type"].getStr == $PendingTransactionType.SetPubKey:
self.usernames.add trx["additionalData"].getStr
self.pendingUsernames.incl trx["additionalData"].getStr
self.firstEnsUsernameChanged()
proc ensWasResolved*(self: EnsManager, ensResult: string) {.signal.}
proc ensResolved(self: EnsManager, ensResult: string) {.slot.} =
self.ensWasResolved(ensResult)
proc validate*(self: EnsManager, ens: string, isStatus: bool) {.slot.} =
self.validate("ensResolved", ens, isStatus, self.usernames)
proc add*(self: EnsManager, username: string) =
self.beginInsertRows(newQModelIndex(), self.usernames.len, self.usernames.len)
self.usernames.add(username)
self.endInsertRows()
proc remove*(self: EnsManager, username: string) =
var idx = -1
var i = 0
for u in self.usernames:
if u == username:
idx = i
break
i = i + 1
if idx == -1: return
self.beginRemoveRows(newQModelIndex(), idx, idx)
self.usernames.delete(idx)
self.endRemoveRows()
proc getPreferredUsername(self: EnsManager): string {.slot.} =
result = self.status.settings.getSetting[:string](Setting.PreferredUsername, "")
proc preferredUsernameChanged(self: EnsManager) {.signal.}
proc isPending*(self: EnsManager, ensUsername: string): bool {.slot.} =
self.pendingUsernames.contains(ensUsername)
proc pendingLen*(self: EnsManager): int {.slot.} =
self.pendingUsernames.len
proc setPreferredUsername(self: EnsManager, newENS: string) {.slot.} =
if not self.isPending(newENS):
discard self.status.settings.saveSetting(Setting.PreferredUsername, newENS)
self.preferredUsernameChanged()
QtProperty[string] preferredUsername:
read = getPreferredUsername
notify = preferredUsernameChanged
write = setPreferredUsername
proc connect(self: EnsManager, ensUsername: string) =
var usernames = getSetting[seq[string]](self.status.settings, Setting.Usernames, @[])
if usernames.len == 0:
self.setPreferredUsername(ensUsername)
usernames.add ensUsername
discard self.status.settings.saveSetting(Setting.Usernames, %*usernames)
proc loading(self: EnsManager, isLoading: bool) {.signal.}
proc details(self: EnsManager, username: string) {.slot.} =
self.loading(true)
self.details("setDetails", username)
proc detailsObtained(self: EnsManager, ensName: string, address: string, pubkey: string, isStatus: bool, expirationTime: int) {.signal.}
proc setDetails(self: EnsManager, details: string): string {.slot.} =
self.loading(false)
let detailsJson = details.parseJson
self.detailsObtained(detailsJson["ensName"].getStr, detailsJson["address"].getStr, detailsJson["pubkey"].getStr, detailsJson["isStatus"].getBool, detailsJson["expirationTime"].getInt)
method rowCount(self: EnsManager, index: QModelIndex = nil): int =
return self.usernames.len
method data(self: EnsManager, index: QModelIndex, role: int): QVariant =
if not index.isValid:
return
if index.row < 0 or index.row >= self.usernames.len:
return
let username = self.usernames[index.row]
case role.EnsRoles:
of EnsRoles.UserName: result = newQVariant(username)
of EnsRoles.IsPending: result = newQVariant(self.pendingUsernames.contains(username))
method roleNames(self: EnsManager): Table[int, string] =
{
EnsRoles.UserName.int:"username",
EnsRoles.IsPending.int: "isPending"
}.toTable
proc usernameConfirmed(self: EnsManager, username: string) {.signal.}
proc transactionWasSent(self: EnsManager, txResult: string) {.signal.}
proc transactionCompleted(self: EnsManager, success: bool, txHash: string, username: string, trxType: string, revertReason: string) {.signal.}
proc confirm*(self: EnsManager, trxType: PendingTransactionType, ensUsername: string, transactionHash: string) =
self.connect(ensUsername)
self.pendingUsernames.excl ensUsername
let msgIdx = self.usernames.find(ensUsername)
let topLeft = self.createIndex(msgIdx, 0, nil)
let bottomRight = self.createIndex(msgIdx, 0, nil)
self.dataChanged(topLeft, bottomRight, @[EnsRoles.IsPending.int])
self.usernameConfirmed(ensUsername)
self.transactionCompleted(true, transactionHash, ensUsername, $trxType, "")
proc getPrice(self: EnsManager): string {.slot.} =
result = status_utils.wei2Eth(getPrice())
proc getUsernameRegistrar(self: EnsManager): string {.slot.} =
result = statusRegistrarAddress()
proc formatUsername(username: string, isStatus: bool): string =
result = username
if isStatus:
result = result & status_ens.domain
proc connectOwnedUsername(self: EnsManager, username: string, isStatus: bool) {.slot.} =
var ensUsername = formatUsername(username, isStatus)
self.add ensUsername
self.connect(ensUsername)
proc revert*(self: EnsManager, trxType: PendingTransactionType, ensUsername: string, transactionHash: string, revertReason: string) =
self.pendingUsernames.excl ensUsername
let msgIdx = self.usernames.find(ensUsername)
if msgIdx == -1: return
self.beginResetModel()
self.usernames.del(msgIdx)
self.endResetModel()
self.transactionCompleted(false, transactionHash, ensUsername, $trxType, revertReason)
proc registerENSGasEstimate(self: EnsManager, ensUsername: string, address: string): int {.slot.} =
var success: bool
let pubKey = self.status.settings.getSetting[:string](Setting.PublicKey, "0x0")
result = registerUsernameEstimateGas(ensUsername, address, pubKey, success)
if not success:
result = 380000
proc registerENS*(self: EnsManager, username: string, address: string, gas: string, gasPrice: string, maxPriorityFeePerGas: string, maxFeePerGas: string, password: string): string {.slot.} =
let eip1559Enabled = self.status.wallet.isEIP1559Enabled()
var success: bool
let pubKey = self.status.settings.getSetting[:string](Setting.PublicKey, "0x0")
let response = registerUsername(username, pubKey, address, gas, gasPrice, eip1559Enabled, maxPriorityFeePerGas, maxFeePerGas, password, success)
result = $(%* { "result": %response, "success": %success })
if success:
self.transactionWasSent(response)
var ensUsername = formatUsername(username, true)
self.pendingUsernames.incl(ensUsername)
self.add ensUsername
proc releaseEstimate(self: EnsManager, ensUsername: string, address: string): int {.slot.} =
var success: bool
result = releaseEstimateGas(ensUsername, address, success)
if not success:
result = 100000
proc release*(self: EnsManager, username: string, address: string, gas: string, gasPrice: string, password: string): string {.slot.} =
var success: bool
let response = release(username, address, gas, gasPrice, password, success)
result = $(%* { "result": %response, "success": %success })
if success:
self.transactionWasSent(response)
self.pendingUsernames.excl(username)
self.remove(username)
let preferredUsername = self.status.settings.getSetting[:string](Setting.PreferredUsername, "")
if username == preferredUsername:
self.setPreferredUsername("")
proc setPubKeyGasEstimate(self: EnsManager, ensUsername: string, address: string): int {.slot.} =
var success: bool
let pubKey = self.status.settings.getSetting[:string](Setting.PublicKey, "0x0")
result = setPubKeyEstimateGas(ensUsername, address, pubKey, success)
if not success:
result = 80000
proc setPubKey*(self: EnsManager, username: string, address: string, gas: string, gasPrice: string, maxPriorityFeePerGas: string, maxFeePerGas: string, password: string): string {.slot.} =
let eip1559Enabled = self.status.wallet.isEIP1559Enabled()
var success: bool
let pubKey = self.status.settings.getSetting[:string](Setting.PublicKey, "0x0")
let response = setPubKey(username, pubKey, address, gas, gasPrice, eip1559Enabled, maxPriorityFeePerGas, maxFeePerGas, password, success)
result = $(%* { "result": %response, "success": %success })
if success:
self.transactionWasSent(response)
self.pendingUsernames.incl(username)
self.add username