refactor: Remove ChatItem object
This commit is contained in:
parent
152dd102dd
commit
39c494f9d5
|
@ -42,15 +42,14 @@ proc handleChatEvents(self: ChatController) =
|
|||
|
||||
self.status.events.on("channelJoined") do(e: Args):
|
||||
var channel = ChannelArgs(e)
|
||||
let chatItem = newChatItem(id = channel.channel, name = channel.name, chatType = channel.chatTypeInt)
|
||||
discard self.view.chats.addChatItemToList(chatItem)
|
||||
self.status.chat.chatMessages(channel.channel)
|
||||
discard self.view.chats.addChatItemToList(channel.chat)
|
||||
self.status.chat.chatMessages(channel.chat.id)
|
||||
|
||||
self.status.events.on("channelLeft") do(e: Args):
|
||||
discard self.view.chats.removeChatItemFromList(self.view.activeChannel.chatItem.id)
|
||||
|
||||
self.status.events.on("activeChannelChanged") do(e: Args):
|
||||
self.view.setActiveChannel(ChannelArgs(e).channel)
|
||||
self.view.setActiveChannel(ChatIdArg(e).chatId)
|
||||
|
||||
proc handleMailserverEvents(self: ChatController) =
|
||||
self.status.events.on("mailserverTopics") do(e: Args):
|
||||
|
@ -69,8 +68,9 @@ proc init*(self: ChatController) =
|
|||
self.status.chat.init()
|
||||
|
||||
proc handleMessage(self: ChatController, data: MessageSignal) =
|
||||
for c in data.chats:
|
||||
self.view.updateChat(c.toChatItem())
|
||||
for chat in data.chats:
|
||||
var c = chat
|
||||
self.view.updateChat(c)
|
||||
self.view.pushMessages(data.messages)
|
||||
|
||||
proc handleDiscoverySummary(self: ChatController, data: DiscoverySummarySignal) =
|
||||
|
|
|
@ -103,7 +103,7 @@ QtObject:
|
|||
read = getMessageList
|
||||
notify = activeChannelChanged
|
||||
|
||||
proc pushChatItem*(self: ChatsView, chatItem: ChatItem) =
|
||||
proc pushChatItem*(self: ChatsView, chatItem: var Chat) =
|
||||
discard self.chats.addChatItemToList(chatItem)
|
||||
self.messagePushed()
|
||||
|
||||
|
@ -123,5 +123,5 @@ QtObject:
|
|||
proc leaveActiveChat*(self: ChatsView) {.slot.} =
|
||||
self.status.chat.leave(self.activeChannel.id)
|
||||
|
||||
proc updateChat*(self: ChatsView, chat: ChatItem) =
|
||||
proc updateChat*(self: ChatsView, chat: var Chat) =
|
||||
self.chats.updateChat(chat)
|
||||
|
|
|
@ -1,8 +1,6 @@
|
|||
import NimQml, Tables
|
||||
import random
|
||||
import ../../../status/chat
|
||||
|
||||
const channelColors* = ["#fa6565", "#7cda00", "#887af9", "#51d0f0", "#FE8F59", "#d37ef4"]
|
||||
import ../../../signals/types
|
||||
|
||||
type
|
||||
ChannelsRoles {.pure.} = enum
|
||||
|
@ -17,7 +15,7 @@ type
|
|||
QtObject:
|
||||
type
|
||||
ChannelsList* = ref object of QAbstractListModel
|
||||
chats*: seq[ChatItem]
|
||||
chats*: seq[Chat]
|
||||
|
||||
proc setup(self: ChannelsList) = self.QAbstractListModel.setup
|
||||
|
||||
|
@ -41,7 +39,7 @@ QtObject:
|
|||
case chatItemRole:
|
||||
of ChannelsRoles.Name: result = newQVariant(chatItem.name)
|
||||
of ChannelsRoles.Timestamp: result = newQVariant($chatItem.timestamp)
|
||||
of ChannelsRoles.LastMessage: result = newQVariant(chatItem.lastMessage)
|
||||
of ChannelsRoles.LastMessage: result = newQVariant(chatItem.lastMessage.text)
|
||||
of ChannelsRoles.UnreadMessages: result = newQVariant(chatItem.unviewedMessagesCount)
|
||||
of ChannelsRoles.Identicon: result = newQVariant(chatItem.identicon)
|
||||
of ChannelsRoles.ChatType: result = newQVariant(chatItem.chatType.int)
|
||||
|
@ -58,10 +56,7 @@ QtObject:
|
|||
ChannelsRoles.Color.int: "color"
|
||||
}.toTable
|
||||
|
||||
proc addChatItemToList*(self: ChannelsList, channel: ChatItem): int =
|
||||
if channel.color == "":
|
||||
randomize()
|
||||
channel.color = channelColors[rand(channelColors.len - 1)]
|
||||
proc addChatItemToList*(self: ChannelsList, channel: var Chat): int =
|
||||
self.beginInsertRows(newQModelIndex(), 0, 0)
|
||||
self.chats.insert(channel, 0)
|
||||
self.endInsertRows()
|
||||
|
@ -75,9 +70,9 @@ QtObject:
|
|||
|
||||
result = self.chats.len
|
||||
|
||||
proc getChannel*(self: ChannelsList, index: int): ChatItem = self.chats[index]
|
||||
proc getChannel*(self: ChannelsList, index: int): Chat = self.chats[index]
|
||||
|
||||
proc upsertChannel(self: ChannelsList, channel: ChatItem): int =
|
||||
proc upsertChannel(self: ChannelsList, channel: var Chat): int =
|
||||
let idx = self.chats.findById(channel.id)
|
||||
if idx == -1:
|
||||
result = self.addChatItemToList(channel)
|
||||
|
@ -88,9 +83,9 @@ QtObject:
|
|||
for chat in self.chats:
|
||||
if chat.name == name:
|
||||
return chat.color
|
||||
return channelColors[0]
|
||||
return "#fa6565" # TODO determine if it is possible to have a chat without color
|
||||
|
||||
proc updateChat*(self: ChannelsList, channel: ChatItem) =
|
||||
proc updateChat*(self: ChannelsList, channel: var Chat) =
|
||||
let idx = self.upsertChannel(channel)
|
||||
let topLeft = self.createIndex(0, 0, nil)
|
||||
let bottomRight = self.createIndex(self.chats.len, 0, nil)
|
||||
|
@ -102,8 +97,10 @@ QtObject:
|
|||
|
||||
self.dataChanged(topLeft, bottomRight, @[ChannelsRoles.Name.int, ChannelsRoles.LastMessage.int, ChannelsRoles.Timestamp.int, ChannelsRoles.UnreadMessages.int, ChannelsRoles.Identicon.int, ChannelsRoles.ChatType.int, ChannelsRoles.Color.int])
|
||||
|
||||
proc clearUnreadMessagesCount*(self: ChannelsList, channel: ChatItem) =
|
||||
proc clearUnreadMessagesCount*(self: ChannelsList, channel: var Chat) =
|
||||
let idx = self.chats.findById(channel.id)
|
||||
if idx == -1: return
|
||||
|
||||
let topLeft = self.createIndex(0, 0, nil)
|
||||
let bottomRight = self.createIndex(self.chats.len, 0, nil)
|
||||
channel.unviewedMessagesCount = 0
|
||||
|
|
|
@ -1,10 +1,11 @@
|
|||
import NimQml
|
||||
import std/wrapnils
|
||||
import ../../../status/chat
|
||||
import ../../../signals/types
|
||||
|
||||
QtObject:
|
||||
type ChatItemView* = ref object of QObject
|
||||
chatItem*: ChatItem
|
||||
chatItem*: Chat
|
||||
|
||||
proc setup(self: ChatItemView) =
|
||||
self.QObject.setup
|
||||
|
@ -15,9 +16,10 @@ QtObject:
|
|||
proc newChatItemView*(): ChatItemView =
|
||||
new(result, delete)
|
||||
result = ChatItemView()
|
||||
result.chatItem = nil
|
||||
result.setup
|
||||
|
||||
proc setChatItem*(self: ChatItemView, chatItem: ChatItem) =
|
||||
proc setChatItem*(self: ChatItemView, chatItem: Chat) =
|
||||
self.chatItem = chatItem
|
||||
|
||||
proc id*(self: ChatItemView): string {.slot.} = result = ?.self.chatItem.id
|
||||
|
@ -30,6 +32,11 @@ QtObject:
|
|||
QtProperty[string] name:
|
||||
read = name
|
||||
|
||||
proc color*(self: ChatItemView): string {.slot.} = result = ?.self.chatItem.color
|
||||
|
||||
QtProperty[string] color:
|
||||
read = color
|
||||
|
||||
proc identicon*(self: ChatItemView): string {.slot.} = result = ?.self.chatItem.identicon
|
||||
|
||||
QtProperty[string] identicon:
|
||||
|
|
|
@ -1,7 +1,10 @@
|
|||
import json
|
||||
import types
|
||||
import ../status/libstatus/accounts as status_accounts
|
||||
import random
|
||||
|
||||
proc toMessage*(jsonMsg: JsonNode): Message
|
||||
|
||||
proc toChat*(jsonChat: JsonNode): Chat
|
||||
|
||||
proc fromEvent*(event: JsonNode): Signal =
|
||||
|
@ -18,10 +21,41 @@ proc fromEvent*(event: JsonNode): Signal =
|
|||
|
||||
result = signal
|
||||
|
||||
proc toChatMember*(jsonMember: JsonNode): ChatMember =
|
||||
result = ChatMember(
|
||||
admin: jsonMember["admin"].getBool,
|
||||
id: jsonMember["id"].getStr,
|
||||
joined: jsonMember["joined"].getBool
|
||||
)
|
||||
|
||||
|
||||
const channelColors* = ["#fa6565", "#7cda00", "#887af9", "#51d0f0", "#FE8F59", "#d37ef4"]
|
||||
|
||||
proc newChat*(id: string, chatType: ChatType): Chat =
|
||||
randomize()
|
||||
|
||||
result = Chat(
|
||||
id: id,
|
||||
color: channelColors[rand(channelColors.len - 1)],
|
||||
active: true,
|
||||
chatType: chatType,
|
||||
timestamp: 0,
|
||||
lastClockValue: 0,
|
||||
deletedAtClockValue: 0,
|
||||
unviewedMessagesCount: 0
|
||||
)
|
||||
|
||||
if chatType == ChatType.OneToOne:
|
||||
result.identicon = generateIdenticon(id)
|
||||
result.name = generateAlias(id)
|
||||
else:
|
||||
result.name = id
|
||||
|
||||
proc toChat*(jsonChat: JsonNode): Chat =
|
||||
result = Chat(
|
||||
id: jsonChat{"id"}.getStr,
|
||||
name: jsonChat{"name"}.getStr,
|
||||
identicon: "",
|
||||
color: jsonChat{"color"}.getStr,
|
||||
active: jsonChat{"active"}.getBool,
|
||||
chatType: ChatType(jsonChat{"chatType"}.getInt),
|
||||
|
@ -30,8 +64,21 @@ proc toChat*(jsonChat: JsonNode): Chat =
|
|||
deletedAtClockValue: jsonChat{"deletedAtClockValue"}.getBiggestInt,
|
||||
unviewedMessagesCount: jsonChat{"unviewedMessagesCount"}.getInt,
|
||||
)
|
||||
|
||||
if jsonChat["lastMessage"].kind != JNull:
|
||||
result.lastMessage = jsonChat{"lastMessage"}.toMessage
|
||||
if result.chatType == ChatType.OneToOne:
|
||||
result.name = result.lastMessage.alias
|
||||
result.identicon = result.lastMessage.identicon
|
||||
else:
|
||||
if result.chatType == ChatType.OneToOne:
|
||||
result.identicon = generateIdenticon(result.id)
|
||||
result.name = generateAlias(result.id)
|
||||
|
||||
if jsonChat["members"].kind != JNull:
|
||||
result.members = @[]
|
||||
for jsonMember in jsonChat["members"]:
|
||||
result.members.add(jsonMember.toChatMember)
|
||||
|
||||
proc toMessage*(jsonMsg: JsonNode): Message =
|
||||
result = Message(
|
||||
|
@ -56,5 +103,8 @@ proc toMessage*(jsonMsg: JsonNode): Message =
|
|||
isCurrentUser: $jsonMsg{"outgoingStatus"}.getStr == "sending",
|
||||
stickerHash: ""
|
||||
)
|
||||
|
||||
if result.contentType == 2:
|
||||
result.stickerHash = jsonMsg["sticker"]["hash"].getStr
|
||||
|
||||
|
||||
|
|
|
@ -55,10 +55,16 @@ type ChatType* = enum
|
|||
|
||||
proc isOneToOne*(self: ChatType): bool = self == ChatType.OneToOne
|
||||
|
||||
type Chat* = object
|
||||
type ChatMember* = object
|
||||
admin*: bool
|
||||
id*: string
|
||||
joined*: bool
|
||||
|
||||
type Chat* = ref object
|
||||
id*: string # ID is the id of the chat, for public chats it is the name e.g. status, for one-to-one is the hex encoded public key and for group chats is a random uuid appended with the hex encoded pk of the creator of the chat
|
||||
name*: string
|
||||
color*: string
|
||||
identicon*: string
|
||||
active*: bool # indicates whether the chat has been soft deleted
|
||||
chatType*: ChatType
|
||||
timestamp*: int64 # indicates the last time this chat has received/sent a message
|
||||
|
@ -66,8 +72,7 @@ type Chat* = object
|
|||
deletedAtClockValue*: int64 # indicates the clock value at time of deletion, messages with lower clock value of this should be discarded
|
||||
unviewedMessagesCount*: int
|
||||
lastMessage*: Message
|
||||
# Group chat fields
|
||||
# members ?
|
||||
members*: seq[ChatMember]
|
||||
# membershipUpdateEvents # ?
|
||||
|
||||
type MessageSignal* = ref object of Signal
|
||||
|
@ -87,3 +92,15 @@ type WhisperFilterSignal* = ref object of Signal
|
|||
|
||||
type DiscoverySummarySignal* = ref object of Signal
|
||||
enodes*: seq[string]
|
||||
|
||||
|
||||
|
||||
proc findById*(self: seq[Chat], id: string): int =
|
||||
result = -1
|
||||
var idx = -1
|
||||
for item in self:
|
||||
inc idx
|
||||
if(item.id == id):
|
||||
result = idx
|
||||
break
|
||||
|
||||
|
|
|
@ -3,12 +3,12 @@ import sequtils
|
|||
import libstatus/chat as status_chat
|
||||
import chronicles
|
||||
import ../signals/types
|
||||
import chat/chat_item
|
||||
import ../signals/messages
|
||||
import chat/chat_message
|
||||
import tables
|
||||
|
||||
export chat_item
|
||||
export chat_message
|
||||
export Chat
|
||||
|
||||
type
|
||||
MsgArgs* = ref object of Args
|
||||
|
@ -16,10 +16,11 @@ type
|
|||
chatId*: string
|
||||
payload*: JsonNode
|
||||
|
||||
ChatIdArg* = ref object of Args
|
||||
chatId*: string
|
||||
|
||||
ChannelArgs* = ref object of Args
|
||||
channel*: string
|
||||
name*: string
|
||||
chatTypeInt*: ChatType
|
||||
chat*: Chat
|
||||
|
||||
ChatArgs* = ref object of Args
|
||||
chats*: seq[Chat]
|
||||
|
@ -32,14 +33,14 @@ type
|
|||
|
||||
ChatModel* = ref object
|
||||
events*: EventEmitter
|
||||
channels*: HashSet[string]
|
||||
channels*: Table[string, Chat]
|
||||
filters*: Table[string, string]
|
||||
msgCursor*: Table[string, string]
|
||||
|
||||
proc newChatModel*(events: EventEmitter): ChatModel =
|
||||
result = ChatModel()
|
||||
result.events = events
|
||||
result.channels = initHashSet[string]()
|
||||
result.channels = initTable[string, Chat]()
|
||||
result.filters = initTable[string, string]()
|
||||
result.msgCursor = initTable[string, string]()
|
||||
|
||||
|
@ -47,15 +48,17 @@ proc delete*(self: ChatModel) =
|
|||
discard
|
||||
|
||||
proc hasChannel*(self: ChatModel, chatId: string): bool =
|
||||
result = self.channels.contains(chatId)
|
||||
self.channels.hasKey(chatId)
|
||||
|
||||
proc getActiveChannel*(self: ChatModel): string =
|
||||
if (self.channels.len == 0): "" else: self.channels.toSeq[self.channels.len - 1]
|
||||
if (self.channels.len == 0): "" else: toSeq(self.channels.values)[self.channels.len - 1].id
|
||||
|
||||
proc join*(self: ChatModel, chatId: string, chatType: ChatType) =
|
||||
if self.hasChannel(chatId): return
|
||||
self.channels.incl chatId
|
||||
status_chat.saveChat(chatId, chatType.isOneToOne)
|
||||
|
||||
var chat = newChat(chatId, ChatType(chatType))
|
||||
self.channels[chat.id] = chat
|
||||
status_chat.saveChat(chatId, chatType.isOneToOne, true, chat.color)
|
||||
let filterResult = status_chat.loadFilters(@[status_chat.buildFilter(chatId = chatId, oneToOne = chatType.isOneToOne)])
|
||||
|
||||
var topics:seq[string] = @[]
|
||||
|
@ -70,8 +73,8 @@ proc join*(self: ChatModel, chatId: string, chatType: ChatType) =
|
|||
else:
|
||||
self.events.emit("mailserverTopics", TopicArgs(topics: topics));
|
||||
|
||||
self.events.emit("channelJoined", ChannelArgs(channel: chatId, chatTypeInt: chatType, name: chatId))
|
||||
self.events.emit("activeChannelChanged", ChannelArgs(channel: self.getActiveChannel()))
|
||||
self.events.emit("channelJoined", ChannelArgs(chat: chat))
|
||||
self.events.emit("activeChannelChanged", ChatIdArg(chatId: self.getActiveChannel()))
|
||||
|
||||
proc init*(self: ChatModel) =
|
||||
let chatList = status_chat.loadChats()
|
||||
|
@ -80,8 +83,8 @@ proc init*(self: ChatModel) =
|
|||
for chat in chatList:
|
||||
if self.hasChannel(chat.id): continue
|
||||
filters.add status_chat.buildFilter(chatId = chat.id, oneToOne = chat.chatType.isOneToOne)
|
||||
self.channels.incl chat.id
|
||||
self.events.emit("channelJoined", ChannelArgs(channel: chat.id, chatTypeInt: chat.chatType, name: chat.name))
|
||||
self.channels[chat.id] = chat
|
||||
self.events.emit("channelJoined", ChannelArgs(chat: chat))
|
||||
|
||||
if filters.len == 0: return
|
||||
|
||||
|
@ -105,14 +108,14 @@ proc leave*(self: ChatModel, chatId: string) =
|
|||
status_chat.deactivateChat(chatId)
|
||||
# TODO: REMOVE MAILSERVER TOPIC
|
||||
# TODO: REMOVE HISTORY
|
||||
|
||||
self.filters.del(chatId)
|
||||
self.channels.excl(chatId)
|
||||
self.events.emit("channelLeft", ChannelArgs(channel: chatId))
|
||||
self.events.emit("activeChannelChanged", ChannelArgs(channel: self.getActiveChannel()))
|
||||
self.channels.del(chatId)
|
||||
self.events.emit("channelLeft", ChatIdArg(chatId: chatId))
|
||||
self.events.emit("activeChannelChanged", ChatIdArg(chatId: self.getActiveChannel()))
|
||||
|
||||
|
||||
proc setActiveChannel*(self: ChatModel, chatId: string) =
|
||||
self.events.emit("activeChannelChanged", ChannelArgs(channel: chatId))
|
||||
self.events.emit("activeChannelChanged", ChatIdArg(chatId: chatId))
|
||||
|
||||
proc sendMessage*(self: ChatModel, chatId: string, msg: string): string =
|
||||
var sentMessage = status_chat.sendChatMessage(chatId, msg)
|
||||
|
|
|
@ -1,58 +0,0 @@
|
|||
import ../../signals/types
|
||||
import ../libstatus/accounts as status_accounts
|
||||
|
||||
type ChatItem* = ref object
|
||||
id*: string
|
||||
name*: string
|
||||
chatType*: ChatType
|
||||
lastMessage*: string
|
||||
timestamp*: int64
|
||||
unviewedMessagesCount*: int
|
||||
color*: string
|
||||
identicon*: string
|
||||
|
||||
proc newChatItem*(id: string, name: string, chatType: ChatType, lastMessage: string = "", timestamp: int64 = 0, unviewedMessagesCount: int = 0, color: string = "", identicon: string = ""): ChatItem =
|
||||
new(result)
|
||||
result.id = id
|
||||
result.name = case chatType
|
||||
of ChatType.Public: name
|
||||
of ChatType.OneToOne: generateAlias(id)
|
||||
of ChatType.PrivateGroupChat: name
|
||||
of ChatType.Unknown: "Unknown: " & id
|
||||
result.chatType = chatType
|
||||
result.lastMessage = lastMessage
|
||||
result.timestamp = timestamp
|
||||
result.unviewedMessagesCount = unviewedMessagesCount
|
||||
result.color = color
|
||||
result.identicon = if identicon == "" and chatType == ChatType.OneToOne:
|
||||
generateIdenticon(id)
|
||||
else:
|
||||
identicon
|
||||
|
||||
proc findById*(self: seq[ChatItem], id: string): int =
|
||||
result = -1
|
||||
var idx = -1
|
||||
for item in self:
|
||||
inc idx
|
||||
if(item.id == id):
|
||||
result = idx
|
||||
break
|
||||
|
||||
proc chatName(chat: Chat): string =
|
||||
case chat.chatType
|
||||
of ChatType.OneToOne: result = chat.lastMessage.alias
|
||||
of ChatType.Public: result = chat.name
|
||||
of ChatType.PrivateGroupChat: result = chat.name
|
||||
of ChatType.Unknown: result = "Unknown"
|
||||
|
||||
proc toChatItem*(chat: Chat): ChatItem =
|
||||
result = ChatItem(
|
||||
id: chat.id,
|
||||
name: chatName(chat),
|
||||
color: chat.color,
|
||||
chatType: chat.chatType,
|
||||
lastMessage: chat.lastMessage.text,
|
||||
timestamp: chat.timestamp,
|
||||
identicon: chat.lastMessage.identicon,
|
||||
unviewedMessagesCount: chat.unviewedMessagesCount
|
||||
)
|
|
@ -32,17 +32,16 @@ proc removeFilters*(chatId: string, filterId: string) =
|
|||
}]
|
||||
])
|
||||
|
||||
proc saveChat*(chatId: string, oneToOne: bool = false, active: bool = true) =
|
||||
proc saveChat*(chatId: string, oneToOne: bool = false, active: bool = true, color: string = "#51d0f0") =
|
||||
discard callPrivateRPC("saveChat".prefix, %* [
|
||||
{
|
||||
"lastClockValue": 0, # TODO:
|
||||
"color": "#51d0f0", # TODO:
|
||||
"color": color,
|
||||
"name": chatId,
|
||||
"lastMessage": nil, # TODO:
|
||||
"active": active,
|
||||
"id": chatId,
|
||||
"unviewedMessagesCount": 0, # TODO:
|
||||
# TODO use constants for those too or use the Date
|
||||
"chatType": if oneToOne: 1 else: 2, # TODO: use constants
|
||||
"timestamp": 1588940692659 # TODO:
|
||||
}
|
||||
|
|
|
@ -51,11 +51,10 @@ Item {
|
|||
border.width: chatsModel.activeChannel.chatType == Constants.chatTypeOneToOne ? 2 : 0
|
||||
border.color: Theme.grey
|
||||
color: {
|
||||
const color = chatsModel.getChannelColor(chatId)
|
||||
if (chatsModel.activeChannel.chatType == Constants.chatTypeOneToOne || !color) {
|
||||
if (chatsModel.activeChannel.chatType == Constants.chatTypeOneToOne) {
|
||||
return Theme.transparent
|
||||
}
|
||||
return color
|
||||
return chatsModel.activeChannel.color
|
||||
}
|
||||
|
||||
Image {
|
||||
|
|
|
@ -20,7 +20,7 @@ Rectangle {
|
|||
|
||||
ChannelIcon {
|
||||
id: channelIcon
|
||||
channelName: chatsModel.activeChannel.id
|
||||
channelName: chatsModel.activeChannel.name
|
||||
channelType: chatsModel.activeChannel.chatType
|
||||
channelIdenticon: chatsModel.activeChannel.identicon
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue