core: add FromJSON instance to ChatResponse (#3129)

* Start adding FromJSON instances to ChatResponse

* progress

* FromJSON instance for ChatResponse compiles

* restore removed encodings

* remove comment

* diff

* update simplexmq, use TH for JSON

---------

Co-authored-by: Evgeny Poberezkin <2769109+epoberezkin@users.noreply.github.com>
This commit is contained in:
Alexander Bondarenko
2023-10-05 21:49:20 +03:00
committed by GitHub
parent 27e8a81c9f
commit fc9db9c381
18 changed files with 483 additions and 209 deletions
+204 -39
View File
@@ -17,7 +17,7 @@
module Simplex.Chat.Messages where
import Control.Applicative ((<|>))
import Data.Aeson (FromJSON, ToJSON)
import Data.Aeson (FromJSON, ToJSON, (.:))
import qualified Data.Aeson as J
import qualified Data.Aeson.Encoding as JE
import qualified Data.Attoparsec.ByteString.Char8 as A
@@ -66,6 +66,9 @@ chatNameStr (ChatName cType name) = chatTypeStr cType <> T.unpack name
data ChatRef = ChatRef ChatType Int64
deriving (Eq, Show, Ord)
instance FromJSON ChatType where
parseJSON = J.genericParseJSON . sumTypeJSON $ dropPrefix "CT"
instance ToJSON ChatType where
toJSON = J.genericToJSON . enumJSON $ dropPrefix "CT"
toEncoding = J.genericToEncoding . enumJSON $ dropPrefix "CT"
@@ -110,10 +113,16 @@ data JSONChatInfo
| JCInfoContactConnection {contactConnection :: PendingContactConnection}
deriving (Generic)
instance FromJSON JSONChatInfo where
parseJSON = J.genericParseJSON . sumTypeJSON $ dropPrefix "JCInfo"
instance ToJSON JSONChatInfo where
toJSON = J.genericToJSON . sumTypeJSON $ dropPrefix "JCInfo"
toEncoding = J.genericToEncoding . sumTypeJSON $ dropPrefix "JCInfo"
instance ChatTypeI c => FromJSON (ChatInfo c) where
parseJSON v = (\(AChatInfo _ c) -> checkChatType c) <$?> J.parseJSON v
instance ToJSON (ChatInfo c) where
toJSON = J.toJSON . jsonChatInfo
toEncoding = J.toEncoding . jsonChatInfo
@@ -125,10 +134,20 @@ jsonChatInfo = \case
ContactRequest g -> JCInfoContactRequest g
ContactConnection c -> JCInfoContactConnection c
data AChatInfo = forall c. AChatInfo (SChatType c) (ChatInfo c)
data AChatInfo = forall c. ChatTypeI c => AChatInfo (SChatType c) (ChatInfo c)
deriving instance Show AChatInfo
jsonAChatInfo :: JSONChatInfo -> AChatInfo
jsonAChatInfo = \case
JCInfoDirect c -> AChatInfo SCTDirect $ DirectChat c
JCInfoGroup g -> AChatInfo SCTGroup $ GroupChat g
JCInfoContactRequest g -> AChatInfo SCTContactRequest $ ContactRequest g
JCInfoContactConnection c -> AChatInfo SCTContactConnection $ ContactConnection c
instance FromJSON AChatInfo where
parseJSON v = jsonAChatInfo <$> J.parseJSON v
instance ToJSON AChatInfo where
toJSON (AChatInfo _ c) = J.toJSON c
toEncoding (AChatInfo _ c) = J.toEncoding c
@@ -144,7 +163,10 @@ data ChatItem (c :: ChatType) (d :: MsgDirection) = ChatItem
}
deriving (Show, Generic)
instance MsgDirectionI d => ToJSON (ChatItem c d) where
instance (ChatTypeI c, MsgDirectionI d) => FromJSON (ChatItem c d) where
parseJSON = J.genericParseJSON J.defaultOptions
instance (ChatTypeI c, MsgDirectionI d) => ToJSON (ChatItem c d) where
toJSON = J.genericToJSON J.defaultOptions {J.omitNothingFields = True}
toEncoding = J.genericToEncoding J.defaultOptions {J.omitNothingFields = True}
@@ -156,6 +178,16 @@ data CIDirection (c :: ChatType) (d :: MsgDirection) where
deriving instance Show (CIDirection c d)
data CCIDirection c = forall d. MsgDirectionI d => CCID (SMsgDirection d) (CIDirection c d)
instance ChatTypeI c => FromJSON (CCIDirection c) where
parseJSON v = (\(ACID _ d x) -> checkChatType (CCID d x)) <$?> J.parseJSON v
data ACIDirection = forall c d. (ChatTypeI c, MsgDirectionI d) => ACID (SChatType c) (SMsgDirection d) (CIDirection c d)
instance FromJSON ACIDirection where
parseJSON v = jsonACIDirection <$> J.parseJSON v
data JSONCIDirection
= JCIDirectSnd
| JCIDirectRcv
@@ -163,10 +195,16 @@ data JSONCIDirection
| JCIGroupRcv {groupMember :: GroupMember}
deriving (Generic, Show)
instance FromJSON JSONCIDirection where
parseJSON = J.genericParseJSON . sumTypeJSON $ dropPrefix "JCI"
instance ToJSON JSONCIDirection where
toJSON = J.genericToJSON . sumTypeJSON $ dropPrefix "JCI"
toEncoding = J.genericToEncoding . sumTypeJSON $ dropPrefix "JCI"
instance (ChatTypeI c, MsgDirectionI d) => FromJSON (CIDirection c d) where
parseJSON v = (\(CCID _ x') -> checkDirection x') <$?> J.parseJSON v
instance ToJSON (CIDirection c d) where
toJSON = J.toJSON . jsonCIDirection
toEncoding = J.toEncoding . jsonCIDirection
@@ -178,8 +216,15 @@ jsonCIDirection = \case
CIGroupSnd -> JCIGroupSnd
CIGroupRcv m -> JCIGroupRcv m
jsonACIDirection :: JSONCIDirection -> ACIDirection
jsonACIDirection = \case
JCIDirectSnd -> ACID SCTDirect SMDSnd CIDirectSnd
JCIDirectRcv -> ACID SCTDirect SMDRcv CIDirectRcv
JCIGroupSnd -> ACID SCTGroup SMDSnd CIGroupSnd
JCIGroupRcv m -> ACID SCTGroup SMDRcv $ CIGroupRcv m
data CIReactionCount = CIReactionCount {reaction :: MsgReaction, userReacted :: Bool, totalReacted :: Int}
deriving (Show, Generic)
deriving (Show, Generic, FromJSON)
instance ToJSON CIReactionCount where toEncoding = J.genericToEncoding J.defaultOptions
@@ -187,7 +232,15 @@ data CChatItem c = forall d. MsgDirectionI d => CChatItem (SMsgDirection d) (Cha
deriving instance Show (CChatItem c)
instance ToJSON (CChatItem c) where
instance forall c. ChatTypeI c => FromJSON (CChatItem c) where
parseJSON v = J.withObject "CChatItem" parse v
where
parse o = do
CCID d (_ :: CIDirection c d) <- o .: "chatDir"
ci <- J.parseJSON @(ChatItem c d) v
pure $ CChatItem d ci
instance ChatTypeI c => ToJSON (CChatItem c) where
toJSON (CChatItem _ ci) = J.toJSON ci
toEncoding (CChatItem _ ci) = J.toEncoding ci
@@ -279,14 +332,19 @@ data Chat c = Chat
}
deriving (Show, Generic)
instance ToJSON (Chat c) where
toJSON = J.genericToJSON J.defaultOptions
toEncoding = J.genericToEncoding J.defaultOptions
instance ChatTypeI c => ToJSON (Chat c) where toEncoding = J.genericToEncoding J.defaultOptions
data AChat = forall c. AChat (SChatType c) (Chat c)
data AChat = forall c. ChatTypeI c => AChat (SChatType c) (Chat c)
deriving instance Show AChat
instance FromJSON AChat where
parseJSON = J.withObject "AChat" $ \o -> do
AChatInfo c chatInfo <- o .: "chatInfo"
chatItems <- o .: "chatItems"
chatStats <- o .: "chatStats"
pure $ AChat c Chat {chatInfo, chatItems, chatStats}
instance ToJSON AChat where
toJSON (AChat _ c) = J.toJSON c
toEncoding (AChat _ c) = J.toEncoding c
@@ -296,17 +354,21 @@ data ChatStats = ChatStats
minUnreadItemId :: ChatItemId,
unreadChat :: Bool
}
deriving (Show, Generic)
deriving (Show, Generic, FromJSON)
instance ToJSON ChatStats where
toJSON = J.genericToJSON J.defaultOptions
toEncoding = J.genericToEncoding J.defaultOptions
instance ToJSON ChatStats where toEncoding = J.genericToEncoding J.defaultOptions
-- | type to show a mix of messages from multiple chats
data AChatItem = forall c d. MsgDirectionI d => AChatItem (SChatType c) (SMsgDirection d) (ChatInfo c) (ChatItem c d)
data AChatItem = forall c d. (ChatTypeI c, MsgDirectionI d) => AChatItem (SChatType c) (SMsgDirection d) (ChatInfo c) (ChatItem c d)
deriving instance Show AChatItem
instance FromJSON AChatItem where
parseJSON = J.withObject "AChatItem" $ \o -> do
AChatInfo c chatInfo <- o .: "chatInfo"
CChatItem d chatItem <- o .: "chatItem"
pure $ AChatItem c d chatInfo chatItem
instance ToJSON AChatItem where
toJSON (AChatItem _ _ chat item) = J.toJSON $ JSONAnyChatItem chat item
toEncoding (AChatItem _ _ chat item) = J.toEncoding $ JSONAnyChatItem chat item
@@ -330,7 +392,7 @@ updateFileStatus ci@ChatItem {file} status = case file of
Just f -> ci {file = Just (f :: CIFile d) {fileStatus = status}}
Nothing -> ci
instance MsgDirectionI d => ToJSON (JSONAnyChatItem c d) where
instance (ChatTypeI c, MsgDirectionI d) => ToJSON (JSONAnyChatItem c d) where
toJSON = J.genericToJSON J.defaultOptions
toEncoding = J.genericToEncoding J.defaultOptions
@@ -349,7 +411,7 @@ data CIMeta (c :: ChatType) (d :: MsgDirection) = CIMeta
createdAt :: UTCTime,
updatedAt :: UTCTime
}
deriving (Show, Generic)
deriving (Show, Generic, FromJSON)
mkCIMeta :: ChatItemId -> CIContent d -> Text -> CIStatus d -> Maybe SharedMsgId -> Maybe (CIDeleted c) -> Bool -> Maybe CITimed -> Maybe Bool -> UTCTime -> ChatItemTs -> UTCTime -> UTCTime -> CIMeta c d
mkCIMeta itemId itemContent itemText itemStatus itemSharedMsgId itemDeleted itemEdited itemTimed itemLive currentTs itemTs createdAt updatedAt =
@@ -358,13 +420,13 @@ mkCIMeta itemId itemContent itemText itemStatus itemSharedMsgId itemDeleted item
_ -> False
in CIMeta {itemId, itemTs, itemText, itemStatus, itemSharedMsgId, itemDeleted, itemEdited, itemTimed, itemLive, editable, createdAt, updatedAt}
instance ToJSON (CIMeta c d) where toEncoding = J.genericToEncoding J.defaultOptions
instance ChatTypeI c => ToJSON (CIMeta c d) where toEncoding = J.genericToEncoding J.defaultOptions
data CITimed = CITimed
{ ttl :: Int, -- seconds
deleteAt :: Maybe UTCTime -- this is initially Nothing for received items, the timer starts when they are read
}
deriving (Show, Generic)
deriving (Show, Generic, FromJSON)
instance ToJSON CITimed where toEncoding = J.genericToEncoding J.defaultOptions
@@ -402,6 +464,9 @@ data CIQuote (c :: ChatType) = CIQuote
}
deriving (Show, Generic)
instance ChatTypeI c => FromJSON (CIQuote c) where
parseJSON = J.genericParseJSON J.defaultOptions
instance ToJSON (CIQuote c) where
toJSON = J.genericToJSON J.defaultOptions {J.omitNothingFields = True}
toEncoding = J.genericToEncoding J.defaultOptions {J.omitNothingFields = True}
@@ -414,24 +479,39 @@ data CIReaction (c :: ChatType) (d :: MsgDirection) = CIReaction
}
deriving (Show, Generic)
instance ToJSON (CIReaction c d) where
toJSON = J.genericToJSON J.defaultOptions {J.omitNothingFields = True}
toEncoding = J.genericToEncoding J.defaultOptions {J.omitNothingFields = True}
instance (ChatTypeI c, MsgDirectionI d) => FromJSON (CIReaction c d) where
parseJSON = J.genericParseJSON J.defaultOptions
data ACIReaction = forall c d. ACIReaction (SChatType c) (SMsgDirection d) (ChatInfo c) (CIReaction c d)
instance ChatTypeI c => ToJSON (CIReaction c d) where
toEncoding = J.genericToEncoding J.defaultOptions
data AnyCIReaction = forall c d. ChatTypeI c => ACIR (SChatType c) (SMsgDirection d) (CIReaction c d)
instance FromJSON AnyCIReaction where
parseJSON v = J.withObject "AnyCIReaction" parse v
where
parse o = do
ACID c d (_ :: CIDirection c d) <- o .: "chatDir"
ACIR c d <$> J.parseJSON @(CIReaction c d) v
data ACIReaction = forall c d. ChatTypeI c => ACIReaction (SChatType c) (SMsgDirection d) (ChatInfo c) (CIReaction c d)
deriving instance Show ACIReaction
instance FromJSON ACIReaction where
parseJSON = J.withObject "ACIReaction" $ \o -> do
ACIR c d reaction <- o .: "chatReaction"
cInfo <- o .: "chatInfo"
pure $ ACIReaction c d cInfo reaction
instance ToJSON ACIReaction where
toJSON (ACIReaction _ _ chat reaction) = J.toJSON $ JSONCIReaction chat reaction
toEncoding (ACIReaction _ _ chat reaction) = J.toEncoding $ JSONCIReaction chat reaction
toJSON (ACIReaction _ _ cInfo reaction) = J.toJSON $ JSONCIReaction cInfo reaction
toEncoding (ACIReaction _ _ cInfo reaction) = J.toEncoding $ JSONCIReaction cInfo reaction
data JSONCIReaction c d = JSONCIReaction {chatInfo :: ChatInfo c, chatReaction :: CIReaction c d}
deriving (Generic)
instance ToJSON (JSONCIReaction c d) where
toJSON = J.genericToJSON J.defaultOptions
toEncoding = J.genericToEncoding J.defaultOptions
instance ChatTypeI c => ToJSON (JSONCIReaction c d) where toEncoding = J.genericToEncoding J.defaultOptions
data CIQDirection (c :: ChatType) where
CIQDirectSnd :: CIQDirection 'CTDirect
@@ -441,6 +521,11 @@ data CIQDirection (c :: ChatType) where
deriving instance Show (CIQDirection c)
data ACIQDirection = forall c. ChatTypeI c => ACIQDirection (SChatType c) (CIQDirection c)
instance ChatTypeI c => FromJSON (CIQDirection c) where
parseJSON v = (\(ACIQDirection _ x) -> checkChatType x) . jsonACIQDirection <$?> J.parseJSON v
instance ToJSON (CIQDirection c) where
toJSON = J.toJSON . jsonCIQDirection
toEncoding = J.toEncoding . jsonCIQDirection
@@ -453,6 +538,14 @@ jsonCIQDirection = \case
CIQGroupRcv (Just m) -> Just $ JCIGroupRcv m
CIQGroupRcv Nothing -> Nothing
jsonACIQDirection :: Maybe JSONCIDirection -> ACIQDirection
jsonACIQDirection = \case
Just JCIDirectSnd -> ACIQDirection SCTDirect CIQDirectSnd
Just JCIDirectRcv -> ACIQDirection SCTDirect CIQDirectRcv
Just JCIGroupSnd -> ACIQDirection SCTGroup CIQGroupSnd
Just (JCIGroupRcv m) -> ACIQDirection SCTGroup $ CIQGroupRcv (Just m)
Nothing -> ACIQDirection SCTGroup $ CIQGroupRcv Nothing
quoteMsgDirection :: CIQDirection c -> MsgDirection
quoteMsgDirection = \case
CIQDirectSnd -> MDSnd
@@ -470,6 +563,9 @@ data CIFile (d :: MsgDirection) = CIFile
}
deriving (Show, Generic)
instance MsgDirectionI d => FromJSON (CIFile d) where
parseJSON = J.genericParseJSON J.defaultOptions
instance MsgDirectionI d => ToJSON (CIFile d) where
toJSON = J.genericToJSON J.defaultOptions {J.omitNothingFields = True}
toEncoding = J.genericToEncoding J.defaultOptions {J.omitNothingFields = True}
@@ -481,6 +577,9 @@ instance FromField FileProtocol where fromField = fromTextField_ textDecode
instance ToField FileProtocol where toField = toField . textEncode
instance FromJSON FileProtocol where
parseJSON = textParseJSON "FileProtocol"
instance ToJSON FileProtocol where
toJSON = J.String . textEncode
toEncoding = JE.text . textEncode
@@ -527,6 +626,9 @@ ciFileEnded = \case
CIFSRcvError -> True
CIFSInvalid {} -> True
instance MsgDirectionI d => FromJSON (CIFileStatus d) where
parseJSON v = (\(AFS _ s) -> checkDirection s) . aciFileStatusJSON <$?> J.parseJSON v
instance ToJSON (CIFileStatus d) where
toJSON = J.toJSON . jsonCIFileStatus
toEncoding = J.toEncoding . jsonCIFileStatus
@@ -594,6 +696,9 @@ data JSONCIFileStatus
| JCIFSInvalid {text :: Text}
deriving (Generic)
instance FromJSON JSONCIFileStatus where
parseJSON = J.genericParseJSON . sumTypeJSON $ dropPrefix "JCIFS"
instance ToJSON JSONCIFileStatus where
toJSON = J.genericToJSON . sumTypeJSON $ dropPrefix "JCIFS"
toEncoding = J.genericToEncoding . sumTypeJSON $ dropPrefix "JCIFS"
@@ -658,6 +763,9 @@ deriving instance Eq (CIStatus d)
deriving instance Show (CIStatus d)
instance MsgDirectionI d => FromJSON (CIStatus d) where
parseJSON v = (\(ACIStatus _ s) -> checkDirection s) . jsonACIStatus <$?> J.parseJSON v
instance ToJSON (CIStatus d) where
toJSON = J.toJSON . jsonCIStatus
toEncoding = J.toEncoding . jsonCIStatus
@@ -712,6 +820,9 @@ data JSONCIStatus
| JCISInvalid {text :: Text}
deriving (Show, Generic)
instance FromJSON JSONCIStatus where
parseJSON = J.genericParseJSON . sumTypeJSON $ dropPrefix "JCIS"
instance ToJSON JSONCIStatus where
toJSON = J.genericToJSON . sumTypeJSON $ dropPrefix "JCIS"
toEncoding = J.genericToEncoding . sumTypeJSON $ dropPrefix "JCIS"
@@ -727,6 +838,17 @@ jsonCIStatus = \case
CISRcvRead -> JCISRcvRead
CISInvalid text -> JCISInvalid text
jsonACIStatus :: JSONCIStatus -> ACIStatus
jsonACIStatus = \case
JCISSndNew -> ACIStatus SMDSnd CISSndNew
JCISSndSent sndProgress -> ACIStatus SMDSnd $ CISSndSent sndProgress
JCISSndRcvd msgRcptStatus sndProgress -> ACIStatus SMDSnd $ CISSndRcvd msgRcptStatus sndProgress
JCISSndErrorAuth -> ACIStatus SMDSnd CISSndErrorAuth
JCISSndError e -> ACIStatus SMDSnd $ CISSndError e
JCISRcvNew -> ACIStatus SMDRcv CISRcvNew
JCISRcvRead -> ACIStatus SMDRcv CISRcvRead
JCISInvalid text -> ACIStatus SMDSnd $ CISInvalid text
ciStatusNew :: forall d. MsgDirectionI d => CIStatus d
ciStatusNew = case msgDirection @d of
SMDSnd -> CISSndNew
@@ -757,6 +879,9 @@ data SndCIStatusProgress
| SSPComplete
deriving (Eq, Show, Generic)
instance FromJSON SndCIStatusProgress where
parseJSON = J.genericParseJSON . sumTypeJSON $ dropPrefix "SSP"
instance ToJSON SndCIStatusProgress where
toJSON = J.genericToJSON . enumJSON $ dropPrefix "SSP"
toEncoding = J.genericToEncoding . enumJSON $ dropPrefix "SSP"
@@ -796,6 +921,8 @@ instance TestEquality SChatType where
testEquality SCTContactConnection SCTContactConnection = Just Refl
testEquality _ _ = Nothing
data AChatType = forall c. ChatTypeI c => ACT (SChatType c)
class ChatTypeI (c :: ChatType) where
chatTypeI :: SChatType c
@@ -803,6 +930,36 @@ instance ChatTypeI 'CTDirect where chatTypeI = SCTDirect
instance ChatTypeI 'CTGroup where chatTypeI = SCTGroup
instance ChatTypeI 'CTContactRequest where chatTypeI = SCTContactRequest
instance ChatTypeI 'CTContactConnection where chatTypeI = SCTContactConnection
instance ChatTypeI c => FromJSON (SChatType c) where
parseJSON v = (\(ACT t) -> checkChatType t) . aChatType <$?> J.parseJSON v
instance ToJSON (SChatType c) where
toJSON = J.toJSON . toChatType
toEncoding = J.toEncoding . toChatType
toChatType :: SChatType c -> ChatType
toChatType = \case
SCTDirect -> CTDirect
SCTGroup -> CTGroup
SCTContactRequest -> CTContactRequest
SCTContactConnection -> CTContactConnection
aChatType :: ChatType -> AChatType
aChatType = \case
CTDirect -> ACT SCTDirect
CTGroup -> ACT SCTGroup
CTContactRequest -> ACT SCTContactRequest
CTContactConnection -> ACT SCTContactConnection
checkChatType :: forall t c c'. (ChatTypeI c, ChatTypeI c') => t c' -> Either String (t c)
checkChatType x = case testEquality (chatTypeI @c) (chatTypeI @c') of
Just Refl -> Right x
Nothing -> Left "bad chat type"
data NewMessage e = NewMessage
{ chatMsgEvent :: ChatMsgEvent e,
msgBody :: MsgBody
@@ -920,35 +1077,43 @@ msgDeliveryStatusT' s =
Just Refl -> Just st
_ -> Nothing
checkDirection :: forall t d d'. (MsgDirectionI d, MsgDirectionI d') => t d' -> Either String (t d)
checkDirection x = case testEquality (msgDirection @d) (msgDirection @d') of
Just Refl -> Right x
Nothing -> Left "bad direction"
data CIDeleted (c :: ChatType) where
CIDeleted :: Maybe UTCTime -> CIDeleted c
CIModerated :: Maybe UTCTime -> GroupMember -> CIDeleted 'CTGroup
deriving instance Show (CIDeleted c)
instance ToJSON (CIDeleted d) where
data ACIDeleted = forall c. ChatTypeI c => ACIDeleted (SChatType c) (CIDeleted c)
instance ChatTypeI c => FromJSON (CIDeleted c) where
parseJSON v = (\(ACIDeleted _ x) -> checkChatType x) . jsonACIDeleted <$?> J.parseJSON v
instance ChatTypeI c => ToJSON (CIDeleted c) where
toJSON = J.toJSON . jsonCIDeleted
toEncoding = J.toEncoding . jsonCIDeleted
data JSONCIDeleted
= JCIDDeleted {deletedTs :: Maybe UTCTime}
= JCIDDeleted {deletedTs :: Maybe UTCTime, chatType :: ChatType}
| JCIDModerated {deletedTs :: Maybe UTCTime, byGroupMember :: GroupMember}
deriving (Show, Generic)
instance FromJSON JSONCIDeleted where
parseJSON = J.genericParseJSON . sumTypeJSON $ dropPrefix "JCID"
instance ToJSON JSONCIDeleted where
toJSON = J.genericToJSON . sumTypeJSON $ dropPrefix "JCID"
toEncoding = J.genericToEncoding . sumTypeJSON $ dropPrefix "JCID"
jsonCIDeleted :: CIDeleted d -> JSONCIDeleted
jsonCIDeleted :: forall d. ChatTypeI d => CIDeleted d -> JSONCIDeleted
jsonCIDeleted = \case
CIDeleted ts -> JCIDDeleted ts
CIDeleted ts -> JCIDDeleted ts (toChatType $ chatTypeI @d)
CIModerated ts m -> JCIDModerated ts m
jsonACIDeleted :: JSONCIDeleted -> ACIDeleted
jsonACIDeleted = \case
JCIDDeleted ts cType -> case aChatType cType of ACT c -> ACIDeleted c $ CIDeleted ts
JCIDModerated ts m -> ACIDeleted SCTGroup (CIModerated ts m)
itemDeletedTs :: CIDeleted d -> Maybe UTCTime
itemDeletedTs = \case
CIDeleted ts -> ts
@@ -958,7 +1123,7 @@ data ChatItemInfo = ChatItemInfo
{ itemVersions :: [ChatItemVersion],
memberDeliveryStatuses :: Maybe [MemberDeliveryStatus]
}
deriving (Eq, Show, Generic)
deriving (Eq, Show, Generic, FromJSON)
instance ToJSON ChatItemInfo where toEncoding = J.genericToEncoding J.defaultOptions
@@ -969,7 +1134,7 @@ data ChatItemVersion = ChatItemVersion
itemVersionTs :: UTCTime,
createdAt :: UTCTime
}
deriving (Eq, Show, Generic)
deriving (Eq, Show, Generic, FromJSON)
instance ToJSON ChatItemVersion where toEncoding = J.genericToEncoding J.defaultOptions
@@ -990,7 +1155,7 @@ data MemberDeliveryStatus = MemberDeliveryStatus
{ groupMemberId :: GroupMemberId,
memberDeliveryStatus :: CIStatus 'MDSnd
}
deriving (Eq, Show, Generic)
deriving (Eq, Show, Generic, FromJSON)
instance ToJSON MemberDeliveryStatus where toEncoding = J.genericToEncoding J.defaultOptions