fix(Chat): honor joined date when preserving channel order

Prior to this commit, loaded channels and chats would always be
sorted by date of last message received, with the latest one being
moved to the top of the list.

When new channels or chats are joined, they are added on top of the
list as well, however, when the application is restarted,
those new joined chats would not necessarily show up at the top anymore
becaue nothing keeps track of when a channel was joined, which should
be taken into account when preserving the order.

The changes introduced in this commit solve this by introducing a
new `joined` property on the `Chat` type which gets updated with
the current timestamp whenever a channel is joined.

It also depends on the changes made to the `status-go` client, which
have to land first: https://github.com/status-im/status-go/pull/2158

Closes: #1832
This commit is contained in:
Pascal Precht 2021-02-26 10:03:49 +01:00 committed by Iuri Matias
parent 64b4db1940
commit 923350a46f
5 changed files with 25 additions and 9 deletions

View File

@ -133,7 +133,8 @@ proc join*(self: ChatModel, chatId: string, chatType: ChatType, ensName: string
var chat = newChat(chatId, ChatType(chatType)) var chat = newChat(chatId, ChatType(chatType))
self.channels[chat.id] = chat self.channels[chat.id] = chat
status_chat.saveChat(chatId, chatType, color=chat.color, ensName=ensName, profile=pubKey) let joined = times.toUnix(times.getTime()) * 1000
status_chat.saveChat(chatId, chatType, color=chat.color, ensName=ensName, profile=pubKey, joined=joined)
if ensName != "": if ensName != "":
chat.name = ensName chat.name = ensName
chat.ensName = ensName chat.ensName = ensName

View File

@ -67,6 +67,7 @@ type Chat* = ref object
isActive*: bool # indicates whether the chat has been soft deleted isActive*: bool # indicates whether the chat has been soft deleted
chatType*: ChatType chatType*: ChatType
timestamp*: int64 # indicates the last time this chat has received/sent a message timestamp*: int64 # indicates the last time this chat has received/sent a message
joined*: int64 # indicates when the user joined the chat last time
lastClockValue*: int64 # indicates the last clock value to be used when sending messages lastClockValue*: int64 # indicates the last clock value to be used when sending messages
deletedAtClockValue*: int64 # indicates the clock value at time of deletion, messages with lower clock value of this should be discarded deletedAtClockValue*: int64 # indicates the clock value at time of deletion, messages with lower clock value of this should be discarded
unviewedMessagesCount*: int unviewedMessagesCount*: int
@ -132,7 +133,8 @@ proc toJsonNode*(self: Chat): JsonNode =
"membershipUpdateEvents": self.membershipUpdateEvents.toJsonNode, "membershipUpdateEvents": self.membershipUpdateEvents.toJsonNode,
"name": (if self.ensName != "": self.ensName else: self.name), "name": (if self.ensName != "": self.ensName else: self.name),
"timestamp": self.timestamp, "timestamp": self.timestamp,
"unviewedMessagesCount": self.unviewedMessagesCount "unviewedMessagesCount": self.unviewedMessagesCount,
"joined": self.joined
} }
proc findIndexById*(self: seq[Chat], id: string): int = proc findIndexById*(self: seq[Chat], id: string): int =

View File

@ -18,7 +18,7 @@ proc removeFilters*(chatId: string, filterId: string) =
[{ "ChatID": chatId, "FilterID": filterId }] [{ "ChatID": chatId, "FilterID": filterId }]
]) ])
proc saveChat*(chatId: string, chatType: ChatType, active: bool = true, color: string = "#000000", ensName: string = "", profile: string = "") = proc saveChat*(chatId: string, chatType: ChatType, active: bool = true, color: string = "#000000", ensName: string = "", profile: string = "", joined: int64 = 0) =
# TODO: ideally status-go/stimbus should handle some of these fields instead of having the client # TODO: ideally status-go/stimbus should handle some of these fields instead of having the client
# send them: lastMessage, unviewedMEssagesCount, timestamp, lastClockValue, name? # send them: lastMessage, unviewedMEssagesCount, timestamp, lastClockValue, name?
discard callPrivateRPC("saveChat".prefix, %* [ discard callPrivateRPC("saveChat".prefix, %* [
@ -32,7 +32,8 @@ proc saveChat*(chatId: string, chatType: ChatType, active: bool = true, color: s
"id": chatId, "id": chatId,
"unviewedMessagesCount": 0, # TODO: "unviewedMessagesCount": 0, # TODO:
"chatType": chatType.int, "chatType": chatType.int,
"timestamp": 1588940692659 # TODO: "timestamp": 1588940692659, # TODO:
"joined": joined
} }
]) ])
@ -41,8 +42,16 @@ proc deactivateChat*(chat: Chat) =
discard callPrivateRPC("saveChat".prefix, %* [chat.toJsonNode]) discard callPrivateRPC("saveChat".prefix, %* [chat.toJsonNode])
proc sortChats(x, y: Chat): int = proc sortChats(x, y: Chat): int =
if x.lastMessage.whisperTimestamp > y.lastMessage.whisperTimestamp: 1 var t1 = x.lastMessage.whisperTimestamp
elif x.lastMessage.whisperTimestamp == y.lastMessage.whisperTimestamp: 0 var t2 = y.lastMessage.whisperTimestamp
if t1 <= $x.joined:
t1 = $x.joined
if t2 <= $y.joined:
t2 = $y.joined
if t1 > t2: 1
elif t1 == t2: 0
else: -1 else: -1
proc loadChats*(): seq[Chat] = proc loadChats*(): seq[Chat] =

View File

@ -141,7 +141,8 @@ proc toChat*(jsonChat: JsonNode): Chat =
unviewedMessagesCount: jsonChat{"unviewedMessagesCount"}.getInt, unviewedMessagesCount: jsonChat{"unviewedMessagesCount"}.getInt,
hasMentions: false, hasMentions: false,
muted: false, muted: false,
ensName: "" ensName: "",
joined: 0
) )
if jsonChat.hasKey("muted") and jsonChat["muted"].kind != JNull: if jsonChat.hasKey("muted") and jsonChat["muted"].kind != JNull:
@ -150,6 +151,9 @@ proc toChat*(jsonChat: JsonNode): Chat =
if jsonChat["lastMessage"].kind != JNull: if jsonChat["lastMessage"].kind != JNull:
result.lastMessage = jsonChat{"lastMessage"}.toMessage(pk) result.lastMessage = jsonChat{"lastMessage"}.toMessage(pk)
if jsonChat.hasKey("joined") and jsonChat["joined"].kind != JNull:
result.joined = jsonChat{"joined"}.getInt
if result.chatType == ChatType.OneToOne: if result.chatType == ChatType.OneToOne:
result.identicon = generateIdenticon(result.id) result.identicon = generateIdenticon(result.id)
if result.name.endsWith(".eth"): if result.name.endsWith(".eth"):

2
vendor/status-go vendored

@ -1 +1 @@
Subproject commit 6037570901233477cbef85d5494b257076a3acd9 Subproject commit dd49e604d49a2906dfad6ac1e459b72de014e2c0