2021-09-08 18:05:39 +00:00
{. used . }
import strutils , random , strformat , json
2021-09-11 21:50:36 +00:00
import .. / statusgo_backend / accounts as status_accounts
2021-09-08 18:05:39 +00:00
import message
include chat_member
include chat_membership_event
type ChatType * {. pure . } = enum
Unknown = 0 ,
OneToOne = 1 ,
Public = 2 ,
PrivateGroupChat = 3 ,
Profile = 4 ,
2021-12-03 17:55:34 +00:00
Timeline = 5 ,
2021-09-08 18:05:39 +00:00
CommunityChat = 6
proc isOneToOne * ( self : ChatType ) : bool = self = = ChatType . OneToOne
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
communityId * : string
private * : bool
categoryId * : string
name * : string
description * : string
color * : string
identicon * : string
isActive * : bool # indicates whether the chat has been soft deleted
chatType * : ChatType
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
deletedAtClockValue * : int64 # indicates the clock value at time of deletion, messages with lower clock value of this should be discarded
unviewedMessagesCount * : int
unviewedMentionsCount * : int
lastMessage * : Message
members * : seq [ ChatMember ]
membershipUpdateEvents * : seq [ ChatMembershipEvent ]
mentionsCount * : int # Using this is not a good approach, we should instead use unviewedMentionsCount and refer to it always.
muted * : bool
canPost * : bool
ensName * : string
position * : int
2021-12-01 20:17:47 +00:00
syncedFrom * : int64
syncedTo * : int64
2021-09-08 18:05:39 +00:00
proc `$` * ( self : Chat ) : string =
result = fmt" Chat(id:{self.id}, name:{self.name}, active:{self.isActive}, type:{self.chatType}) "
proc toJsonNode * ( self : Chat ) : JsonNode =
result = % * {
" active " : self . isActive ,
" chatType " : self . chatType . int ,
" color " : self . color ,
" deletedAtClockValue " : self . deletedAtClockValue ,
" id " : self . id ,
2021-09-20 21:22:55 +00:00
" communityId " : self . communityId ,
2021-09-08 18:05:39 +00:00
" lastClockValue " : self . lastClockValue ,
" lastMessage " : nil ,
" members " : self . members . toJsonNode ,
" membershipUpdateEvents " : self . membershipUpdateEvents . toJsonNode ,
" name " : ( if self . ensName ! = " " : self . ensName else : self . name ) ,
" timestamp " : self . timestamp ,
" unviewedMessagesCount " : self . unviewedMessagesCount ,
" joined " : self . joined ,
2021-12-01 20:17:47 +00:00
" position " : self . position ,
" syncedFrom " : self . syncedFrom ,
" syncedTo " : self . syncedTo ,
2021-09-08 18:05:39 +00:00
}
proc toChatMember * ( jsonMember : JsonNode ) : ChatMember =
let pubkey = jsonMember [ " id " ] . getStr
result = ChatMember (
admin : jsonMember [ " admin " ] . getBool ,
id : pubkey ,
joined : jsonMember [ " joined " ] . getBool ,
identicon : generateIdenticon ( pubkey ) ,
userName : generateAlias ( pubkey )
)
proc toChatMembershipEvent * ( jsonMembership : JsonNode ) : ChatMembershipEvent =
result = ChatMembershipEvent (
chatId : jsonMembership [ " chatId " ] . getStr ,
clockValue : jsonMembership [ " clockValue " ] . getBiggestInt ,
fromKey : jsonMembership [ " from " ] . getStr ,
rawPayload : jsonMembership [ " rawPayload " ] . getStr ,
signature : jsonMembership [ " signature " ] . getStr ,
eventType : jsonMembership [ " type " ] . getInt ,
name : jsonMembership { " name " } . getStr ,
members : @ [ ]
)
if jsonMembership { " members " } ! = nil :
for member in jsonMembership [ " members " ] :
result . members . add ( member . getStr )
proc toChat * ( jsonChat : JsonNode ) : Chat =
let chatTypeInt = jsonChat { " chatType " } . getInt
let chatType : ChatType = if chatTypeInt > = ord ( low ( ChatType ) ) or chatTypeInt < = ord ( high ( ChatType ) ) : ChatType ( chatTypeInt ) else : ChatType . Unknown
result = Chat (
id : jsonChat { " id " } . getStr ,
communityId : jsonChat { " communityId " } . getStr ,
name : jsonChat { " name " } . getStr ,
description : jsonChat { " description " } . getStr ,
identicon : " " ,
color : jsonChat { " color " } . getStr ,
isActive : jsonChat { " active " } . getBool ,
chatType : chatType ,
timestamp : jsonChat { " timestamp " } . getBiggestInt ,
lastClockValue : jsonChat { " lastClockValue " } . getBiggestInt ,
deletedAtClockValue : jsonChat { " deletedAtClockValue " } . getBiggestInt ,
unviewedMessagesCount : jsonChat { " unviewedMessagesCount " } . getInt ,
unviewedMentionsCount : jsonChat { " unviewedMentionsCount " } . getInt ,
mentionsCount : 0 ,
muted : false ,
ensName : " " ,
joined : 0 ,
2021-12-01 20:17:47 +00:00
private : jsonChat { " private " } . getBool ,
syncedFrom : jsonChat { " syncedFrom " } . getBiggestInt ,
syncedTo : jsonChat { " syncedTo " } . getBiggestInt ,
2021-09-08 18:05:39 +00:00
)
if jsonChat . hasKey ( " muted " ) and jsonChat [ " muted " ] . kind ! = JNull :
result . muted = jsonChat [ " muted " ] . getBool
if jsonChat [ " lastMessage " ] . kind ! = JNull :
result . lastMessage = jsonChat { " lastMessage " } . toMessage ( )
if jsonChat . hasKey ( " joined " ) and jsonChat [ " joined " ] . kind ! = JNull :
result . joined = jsonChat { " joined " } . getInt
if result . chatType = = ChatType . OneToOne :
result . identicon = generateIdenticon ( result . id )
if result . name . endsWith ( " .eth " ) :
result . ensName = result . name
if result . name = = " " :
result . name = generateAlias ( result . id )
if jsonChat [ " members " ] . kind ! = JNull :
result . members = @ [ ]
for jsonMember in jsonChat [ " members " ] :
result . members . add ( jsonMember . toChatMember )
if jsonChat [ " membershipUpdateEvents " ] . kind ! = JNull :
result . membershipUpdateEvents = @ [ ]
for jsonMember in jsonChat [ " membershipUpdateEvents " ] :
result . membershipUpdateEvents . add ( jsonMember . toChatMembershipEvent )
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 ) ] ,
isActive : true ,
chatType : chatType ,
timestamp : 0 ,
lastClockValue : 0 ,
deletedAtClockValue : 0 ,
unviewedMessagesCount : 0 ,
mentionsCount : 0 ,
members : @ [ ]
)
if chatType = = ChatType . OneToOne :
result . identicon = generateIdenticon ( id )
result . name = generateAlias ( id )
else :
2021-12-03 17:55:34 +00:00
result . name = id