{-# LANGUAGE DataKinds #-}
{-# LANGUAGE DeriveAnyClass #-}
{-# LANGUAGE DuplicateRecordFields #-}
{-# LANGUAGE GADTs #-}
{-# LANGUAGE KindSignatures #-}
{-# LANGUAGE LambdaCase #-}
{-# LANGUAGE NamedFieldPuns #-}
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE PatternSynonyms #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE StandaloneDeriving #-}
{-# LANGUAGE TemplateHaskell #-}
{-# LANGUAGE TypeApplications #-}

module Simplex.Chat.Messages.CIContent where

import Control.Applicative ((<|>))
import Data.Aeson (FromJSON, ToJSON)
import qualified Data.Aeson as J
import qualified Data.Aeson.TH as JQ
import qualified Data.Attoparsec.ByteString.Char8 as A
import qualified Data.ByteString.Lazy as LB
import Data.Int (Int64)
import Data.Text (Text)
import Data.Text.Encoding (decodeLatin1, encodeUtf8)
import Data.Type.Equality
import Data.Word (Word32)
import Simplex.Chat.Messages.CIContent.Events
import Simplex.Chat.Options.DB (FromField (..), ToField (..))
import Simplex.Chat.Protocol
import Simplex.Chat.Types
import Simplex.Chat.Types.Preferences
import Simplex.Chat.Types.Shared
import Simplex.Messaging.Agent.Protocol (MsgErrorType (..), RatchetSyncState (..), SwitchPhase (..))
import Simplex.Messaging.Crypto.Ratchet (PQEncryption, pattern PQEncOff, pattern PQEncOn)
import Simplex.Messaging.Encoding.String
import Simplex.Messaging.Parsers (defaultJSON, dropPrefix, enumJSON, fstToLower, singleFieldJSON, sumTypeJSON)
import Simplex.Messaging.Util (encodeJSON, safeDecodeUtf8, tshow, (<$?>))

data MsgDirection = MDRcv | MDSnd
  deriving (MsgDirection -> MsgDirection -> Bool
(MsgDirection -> MsgDirection -> Bool)
-> (MsgDirection -> MsgDirection -> Bool) -> Eq MsgDirection
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: MsgDirection -> MsgDirection -> Bool
== :: MsgDirection -> MsgDirection -> Bool
$c/= :: MsgDirection -> MsgDirection -> Bool
/= :: MsgDirection -> MsgDirection -> Bool
Eq, Int -> MsgDirection -> ShowS
[MsgDirection] -> ShowS
MsgDirection -> String
(Int -> MsgDirection -> ShowS)
-> (MsgDirection -> String)
-> ([MsgDirection] -> ShowS)
-> Show MsgDirection
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> MsgDirection -> ShowS
showsPrec :: Int -> MsgDirection -> ShowS
$cshow :: MsgDirection -> String
show :: MsgDirection -> String
$cshowList :: [MsgDirection] -> ShowS
showList :: [MsgDirection] -> ShowS
Show)

$(JQ.deriveJSON (enumJSON $ dropPrefix "MD") ''MsgDirection)

instance FromField AMsgDirection where fromField :: FieldParser AMsgDirection
fromField = (AgentMsgId -> Maybe AMsgDirection) -> FieldParser AMsgDirection
forall a. Typeable a => (AgentMsgId -> Maybe a) -> FieldParser a
fromIntField_ ((AgentMsgId -> Maybe AMsgDirection) -> FieldParser AMsgDirection)
-> (AgentMsgId -> Maybe AMsgDirection) -> FieldParser AMsgDirection
forall a b. (a -> b) -> a -> b
$ (MsgDirection -> AMsgDirection)
-> Maybe MsgDirection -> Maybe AMsgDirection
forall a b. (a -> b) -> Maybe a -> Maybe b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap MsgDirection -> AMsgDirection
fromMsgDirection (Maybe MsgDirection -> Maybe AMsgDirection)
-> (AgentMsgId -> Maybe MsgDirection)
-> AgentMsgId
-> Maybe AMsgDirection
forall b c a. (b -> c) -> (a -> b) -> a -> c
. AgentMsgId -> Maybe MsgDirection
msgDirectionIntP

instance FromField MsgDirection where fromField :: FieldParser MsgDirection
fromField = (AgentMsgId -> Maybe MsgDirection) -> FieldParser MsgDirection
forall a. Typeable a => (AgentMsgId -> Maybe a) -> FieldParser a
fromIntField_ AgentMsgId -> Maybe MsgDirection
msgDirectionIntP

instance ToField MsgDirection where toField :: MsgDirection -> SQLData
toField = Int -> SQLData
forall a. ToField a => a -> SQLData
toField (Int -> SQLData)
-> (MsgDirection -> Int) -> MsgDirection -> SQLData
forall b c a. (b -> c) -> (a -> b) -> a -> c
. MsgDirection -> Int
msgDirectionInt

data SMsgDirection (d :: MsgDirection) where
  SMDRcv :: SMsgDirection 'MDRcv
  SMDSnd :: SMsgDirection 'MDSnd

deriving instance Show (SMsgDirection d)

instance TestEquality SMsgDirection where
  testEquality :: forall (a :: MsgDirection) (b :: MsgDirection).
SMsgDirection a -> SMsgDirection b -> Maybe (a :~: b)
testEquality SMsgDirection a
SMDRcv SMsgDirection b
SMDRcv = (a :~: b) -> Maybe (a :~: b)
forall a. a -> Maybe a
Just a :~: a
a :~: b
forall {k} (a :: k). a :~: a
Refl
  testEquality SMsgDirection a
SMDSnd SMsgDirection b
SMDSnd = (a :~: b) -> Maybe (a :~: b)
forall a. a -> Maybe a
Just a :~: a
a :~: b
forall {k} (a :: k). a :~: a
Refl
  testEquality SMsgDirection a
_ SMsgDirection b
_ = Maybe (a :~: b)
forall a. Maybe a
Nothing

instance MsgDirectionI d => FromJSON (SMsgDirection d) where
  parseJSON :: Value -> Parser (SMsgDirection d)
parseJSON Value
v = (\(AMsgDirection SMsgDirection d
d) -> SMsgDirection d -> Either String (SMsgDirection d)
forall (t :: MsgDirection -> *) (d :: MsgDirection)
       (d' :: MsgDirection).
(MsgDirectionI d, MsgDirectionI d') =>
t d' -> Either String (t d)
checkDirection SMsgDirection d
d) (AMsgDirection -> Either String (SMsgDirection d))
-> (MsgDirection -> AMsgDirection)
-> MsgDirection
-> Either String (SMsgDirection d)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. MsgDirection -> AMsgDirection
fromMsgDirection (MsgDirection -> Either String (SMsgDirection d))
-> Parser MsgDirection -> Parser (SMsgDirection d)
forall (m :: * -> *) a b.
MonadFail m =>
(a -> Either String b) -> m a -> m b
<$?> Value -> Parser MsgDirection
forall a. FromJSON a => Value -> Parser a
J.parseJSON Value
v

instance ToJSON (SMsgDirection d) where
  toJSON :: SMsgDirection d -> Value
toJSON = MsgDirection -> Value
forall a. ToJSON a => a -> Value
J.toJSON (MsgDirection -> Value)
-> (SMsgDirection d -> MsgDirection) -> SMsgDirection d -> Value
forall b c a. (b -> c) -> (a -> b) -> a -> c
. SMsgDirection d -> MsgDirection
forall (d :: MsgDirection). SMsgDirection d -> MsgDirection
toMsgDirection
  toEncoding :: SMsgDirection d -> Encoding
toEncoding = MsgDirection -> Encoding
forall a. ToJSON a => a -> Encoding
J.toEncoding (MsgDirection -> Encoding)
-> (SMsgDirection d -> MsgDirection) -> SMsgDirection d -> Encoding
forall b c a. (b -> c) -> (a -> b) -> a -> c
. SMsgDirection d -> MsgDirection
forall (d :: MsgDirection). SMsgDirection d -> MsgDirection
toMsgDirection

instance ToField (SMsgDirection d) where toField :: SMsgDirection d -> SQLData
toField = Int -> SQLData
forall a. ToField a => a -> SQLData
toField (Int -> SQLData)
-> (SMsgDirection d -> Int) -> SMsgDirection d -> SQLData
forall b c a. (b -> c) -> (a -> b) -> a -> c
. MsgDirection -> Int
msgDirectionInt (MsgDirection -> Int)
-> (SMsgDirection d -> MsgDirection) -> SMsgDirection d -> Int
forall b c a. (b -> c) -> (a -> b) -> a -> c
. SMsgDirection d -> MsgDirection
forall (d :: MsgDirection). SMsgDirection d -> MsgDirection
toMsgDirection

data AMsgDirection = forall d. MsgDirectionI d => AMsgDirection (SMsgDirection d)

deriving instance Show AMsgDirection

toMsgDirection :: SMsgDirection d -> MsgDirection
toMsgDirection :: forall (d :: MsgDirection). SMsgDirection d -> MsgDirection
toMsgDirection = \case
  SMsgDirection d
SMDRcv -> MsgDirection
MDRcv
  SMsgDirection d
SMDSnd -> MsgDirection
MDSnd

fromMsgDirection :: MsgDirection -> AMsgDirection
fromMsgDirection :: MsgDirection -> AMsgDirection
fromMsgDirection = \case
  MsgDirection
MDRcv -> SMsgDirection 'MDRcv -> AMsgDirection
forall (d :: MsgDirection).
MsgDirectionI d =>
SMsgDirection d -> AMsgDirection
AMsgDirection SMsgDirection 'MDRcv
SMDRcv
  MsgDirection
MDSnd -> SMsgDirection 'MDSnd -> AMsgDirection
forall (d :: MsgDirection).
MsgDirectionI d =>
SMsgDirection d -> AMsgDirection
AMsgDirection SMsgDirection 'MDSnd
SMDSnd

class MsgDirectionI (d :: MsgDirection) where
  msgDirection :: SMsgDirection d

instance MsgDirectionI 'MDRcv where msgDirection :: SMsgDirection 'MDRcv
msgDirection = SMsgDirection 'MDRcv
SMDRcv

instance MsgDirectionI 'MDSnd where msgDirection :: SMsgDirection 'MDSnd
msgDirection = SMsgDirection 'MDSnd
SMDSnd

checkDirection :: forall t d d'. (MsgDirectionI d, MsgDirectionI d') => t d' -> Either String (t d)
checkDirection :: forall (t :: MsgDirection -> *) (d :: MsgDirection)
       (d' :: MsgDirection).
(MsgDirectionI d, MsgDirectionI d') =>
t d' -> Either String (t d)
checkDirection t d'
x = case SMsgDirection d -> SMsgDirection d' -> Maybe (d :~: d')
forall {k} (f :: k -> *) (a :: k) (b :: k).
TestEquality f =>
f a -> f b -> Maybe (a :~: b)
forall (a :: MsgDirection) (b :: MsgDirection).
SMsgDirection a -> SMsgDirection b -> Maybe (a :~: b)
testEquality (forall (d :: MsgDirection). MsgDirectionI d => SMsgDirection d
msgDirection @d) (forall (d :: MsgDirection). MsgDirectionI d => SMsgDirection d
msgDirection @d') of
  Just d :~: d'
Refl -> t d -> Either String (t d)
forall a b. b -> Either a b
Right t d
t d'
x
  Maybe (d :~: d')
Nothing -> String -> Either String (t d)
forall a b. a -> Either a b
Left String
"bad direction"

msgDirectionInt :: MsgDirection -> Int
msgDirectionInt :: MsgDirection -> Int
msgDirectionInt = \case
  MsgDirection
MDRcv -> Int
0
  MsgDirection
MDSnd -> Int
1

msgDirectionIntP :: Int64 -> Maybe MsgDirection
msgDirectionIntP :: AgentMsgId -> Maybe MsgDirection
msgDirectionIntP = \case
  AgentMsgId
0 -> MsgDirection -> Maybe MsgDirection
forall a. a -> Maybe a
Just MsgDirection
MDRcv
  AgentMsgId
1 -> MsgDirection -> Maybe MsgDirection
forall a. a -> Maybe a
Just MsgDirection
MDSnd
  AgentMsgId
_ -> Maybe MsgDirection
forall a. Maybe a
Nothing

data CIDeleteMode = CIDMBroadcast | CIDMInternal | CIDMInternalMark
  deriving (Int -> CIDeleteMode -> ShowS
[CIDeleteMode] -> ShowS
CIDeleteMode -> String
(Int -> CIDeleteMode -> ShowS)
-> (CIDeleteMode -> String)
-> ([CIDeleteMode] -> ShowS)
-> Show CIDeleteMode
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> CIDeleteMode -> ShowS
showsPrec :: Int -> CIDeleteMode -> ShowS
$cshow :: CIDeleteMode -> String
show :: CIDeleteMode -> String
$cshowList :: [CIDeleteMode] -> ShowS
showList :: [CIDeleteMode] -> ShowS
Show)

instance StrEncoding CIDeleteMode where
  strEncode :: CIDeleteMode -> ByteString
strEncode = \case
    CIDeleteMode
CIDMBroadcast -> ByteString
"broadcast"
    CIDeleteMode
CIDMInternal -> ByteString
"internal"
    CIDeleteMode
CIDMInternalMark -> ByteString
"internalMark"
  strP :: Parser CIDeleteMode
strP =
    (Char -> Bool) -> Parser ByteString
A.takeTill (Char -> Char -> Bool
forall a. Eq a => a -> a -> Bool
== Char
' ') Parser ByteString
-> (ByteString -> Parser CIDeleteMode) -> Parser CIDeleteMode
forall a b.
Parser ByteString a
-> (a -> Parser ByteString b) -> Parser ByteString b
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= \case
      ByteString
"broadcast" -> CIDeleteMode -> Parser CIDeleteMode
forall a. a -> Parser ByteString a
forall (f :: * -> *) a. Applicative f => a -> f a
pure CIDeleteMode
CIDMBroadcast
      ByteString
"internal" -> CIDeleteMode -> Parser CIDeleteMode
forall a. a -> Parser ByteString a
forall (f :: * -> *) a. Applicative f => a -> f a
pure CIDeleteMode
CIDMInternal
      ByteString
"internalMark" -> CIDeleteMode -> Parser CIDeleteMode
forall a. a -> Parser ByteString a
forall (f :: * -> *) a. Applicative f => a -> f a
pure CIDeleteMode
CIDMInternalMark
      ByteString
_ -> String -> Parser CIDeleteMode
forall a. String -> Parser ByteString a
forall (m :: * -> *) a. MonadFail m => String -> m a
fail String
"bad CIDeleteMode"

instance ToJSON CIDeleteMode where
  toJSON :: CIDeleteMode -> Value
toJSON = CIDeleteMode -> Value
forall a. StrEncoding a => a -> Value
strToJSON
  toEncoding :: CIDeleteMode -> Encoding
toEncoding = CIDeleteMode -> Encoding
forall a. StrEncoding a => a -> Encoding
strToJEncoding

instance FromJSON CIDeleteMode where
  parseJSON :: Value -> Parser CIDeleteMode
parseJSON = String -> Value -> Parser CIDeleteMode
forall a. StrEncoding a => String -> Value -> Parser a
strParseJSON String
"CIDeleteMode"

ciDeleteModeToText :: CIDeleteMode -> Text
ciDeleteModeToText :: CIDeleteMode -> Text
ciDeleteModeToText = \case
  CIDeleteMode
CIDMBroadcast -> Text
"this item is deleted (broadcast)"
  CIDeleteMode
CIDMInternal -> Text
"this item is deleted (locally)"
  CIDeleteMode
CIDMInternalMark -> Text
"this item is deleted (locally)"

-- This type is used both in API and in DB, so we use different JSON encodings for the database and for the API
-- ! Nested sum types also have to use different encodings for database and API
-- ! to avoid breaking cross-platform compatibility, see RcvGroupEvent and SndGroupEvent
data CIContent (d :: MsgDirection) where
  CISndMsgContent :: MsgContent -> CIContent 'MDSnd
  CIRcvMsgContent :: MsgContent -> CIContent 'MDRcv
  CISndDeleted :: CIDeleteMode -> CIContent 'MDSnd -- legacy - since v4.3.0 item_deleted field is used
  CIRcvDeleted :: CIDeleteMode -> CIContent 'MDRcv -- legacy - since v4.3.0 item_deleted field is used
  CISndCall :: CICallStatus -> Int -> CIContent 'MDSnd
  CIRcvCall :: CICallStatus -> Int -> CIContent 'MDRcv
  CIRcvIntegrityError :: MsgErrorType -> CIContent 'MDRcv
  CIRcvDecryptionError :: MsgDecryptError -> Word32 -> CIContent 'MDRcv
  CIRcvGroupInvitation :: CIGroupInvitation -> GroupMemberRole -> CIContent 'MDRcv
  CISndGroupInvitation :: CIGroupInvitation -> GroupMemberRole -> CIContent 'MDSnd
  CIRcvDirectEvent :: RcvDirectEvent -> CIContent 'MDRcv
  CIRcvGroupEvent :: RcvGroupEvent -> CIContent 'MDRcv
  CISndGroupEvent :: SndGroupEvent -> CIContent 'MDSnd
  CIRcvConnEvent :: RcvConnEvent -> CIContent 'MDRcv
  CISndConnEvent :: SndConnEvent -> CIContent 'MDSnd
  CIRcvChatFeature :: ChatFeature -> PrefEnabled -> Maybe Int -> CIContent 'MDRcv
  CISndChatFeature :: ChatFeature -> PrefEnabled -> Maybe Int -> CIContent 'MDSnd
  CIRcvChatPreference :: ChatFeature -> FeatureAllowed -> Maybe Int -> CIContent 'MDRcv
  CISndChatPreference :: ChatFeature -> FeatureAllowed -> Maybe Int -> CIContent 'MDSnd
  CIRcvGroupFeature :: GroupFeature -> GroupPreference -> Maybe Int -> Maybe GroupMemberRole -> CIContent 'MDRcv
  CISndGroupFeature :: GroupFeature -> GroupPreference -> Maybe Int -> Maybe GroupMemberRole -> CIContent 'MDSnd
  CIRcvChatFeatureRejected :: ChatFeature -> CIContent 'MDRcv
  CIRcvGroupFeatureRejected :: GroupFeature -> CIContent 'MDRcv
  CISndModerated :: CIContent 'MDSnd
  CIRcvModerated :: CIContent 'MDRcv
  CIRcvBlocked :: CIContent 'MDRcv
  CISndDirectE2EEInfo :: E2EInfo -> CIContent 'MDSnd
  CIRcvDirectE2EEInfo :: E2EInfo -> CIContent 'MDRcv
  CISndGroupE2EEInfo :: E2EInfo -> CIContent 'MDSnd -- when new group is created
  CIRcvGroupE2EEInfo :: E2EInfo -> CIContent 'MDRcv -- when enabled with some member
  CIChatBanner :: CIContent 'MDSnd
  CIInvalidJSON :: Text -> CIContent d -- this is also used for logical database errors, e.g. SEBadChatItem

-- ^ This type is used both in API and in DB, so we use different JSON encodings for the database and for the API
-- ! ^ Nested sum types also have to use different encodings for database and API
-- ! ^ to avoid breaking cross-platform compatibility, see RcvGroupEvent and SndGroupEvent

deriving instance Show (CIContent d)

data E2EInfo = E2EInfo {E2EInfo -> Maybe PQEncryption
pqEnabled :: Maybe PQEncryption}
  deriving (E2EInfo -> E2EInfo -> Bool
(E2EInfo -> E2EInfo -> Bool)
-> (E2EInfo -> E2EInfo -> Bool) -> Eq E2EInfo
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: E2EInfo -> E2EInfo -> Bool
== :: E2EInfo -> E2EInfo -> Bool
$c/= :: E2EInfo -> E2EInfo -> Bool
/= :: E2EInfo -> E2EInfo -> Bool
Eq, Int -> E2EInfo -> ShowS
[E2EInfo] -> ShowS
E2EInfo -> String
(Int -> E2EInfo -> ShowS)
-> (E2EInfo -> String) -> ([E2EInfo] -> ShowS) -> Show E2EInfo
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> E2EInfo -> ShowS
showsPrec :: Int -> E2EInfo -> ShowS
$cshow :: E2EInfo -> String
show :: E2EInfo -> String
$cshowList :: [E2EInfo] -> ShowS
showList :: [E2EInfo] -> ShowS
Show)

ciMsgContent :: CIContent d -> Maybe MsgContent
ciMsgContent :: forall (d :: MsgDirection). CIContent d -> Maybe MsgContent
ciMsgContent = \case
  CISndMsgContent MsgContent
mc -> MsgContent -> Maybe MsgContent
forall a. a -> Maybe a
Just MsgContent
mc
  CIRcvMsgContent MsgContent
mc -> MsgContent -> Maybe MsgContent
forall a. a -> Maybe a
Just MsgContent
mc
  CIContent d
_ -> Maybe MsgContent
forall a. Maybe a
Nothing

isCIReport :: CIContent d -> Bool
isCIReport :: forall (d :: MsgDirection). CIContent d -> Bool
isCIReport = Bool -> (MsgContent -> Bool) -> Maybe MsgContent -> Bool
forall b a. b -> (a -> b) -> Maybe a -> b
maybe Bool
False MsgContent -> Bool
isReport (Maybe MsgContent -> Bool)
-> (CIContent d -> Maybe MsgContent) -> CIContent d -> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. CIContent d -> Maybe MsgContent
forall (d :: MsgDirection). CIContent d -> Maybe MsgContent
ciMsgContent

data MsgDecryptError
  = MDERatchetHeader
  | MDETooManySkipped
  | MDERatchetEarlier
  | MDEOther
  | MDERatchetSync
  deriving (MsgDecryptError -> MsgDecryptError -> Bool
(MsgDecryptError -> MsgDecryptError -> Bool)
-> (MsgDecryptError -> MsgDecryptError -> Bool)
-> Eq MsgDecryptError
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: MsgDecryptError -> MsgDecryptError -> Bool
== :: MsgDecryptError -> MsgDecryptError -> Bool
$c/= :: MsgDecryptError -> MsgDecryptError -> Bool
/= :: MsgDecryptError -> MsgDecryptError -> Bool
Eq, Int -> MsgDecryptError -> ShowS
[MsgDecryptError] -> ShowS
MsgDecryptError -> String
(Int -> MsgDecryptError -> ShowS)
-> (MsgDecryptError -> String)
-> ([MsgDecryptError] -> ShowS)
-> Show MsgDecryptError
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> MsgDecryptError -> ShowS
showsPrec :: Int -> MsgDecryptError -> ShowS
$cshow :: MsgDecryptError -> String
show :: MsgDecryptError -> String
$cshowList :: [MsgDecryptError] -> ShowS
showList :: [MsgDecryptError] -> ShowS
Show)

ciRequiresAttention :: forall d. MsgDirectionI d => CIContent d -> Bool
ciRequiresAttention :: forall (d :: MsgDirection). MsgDirectionI d => CIContent d -> Bool
ciRequiresAttention CIContent d
content = case forall (d :: MsgDirection). MsgDirectionI d => SMsgDirection d
msgDirection @d of
  SMsgDirection d
SMDSnd -> Bool
True
  SMsgDirection d
SMDRcv -> case CIContent d
content of
    CIRcvMsgContent MsgContent
_ -> Bool
True
    CIRcvDeleted CIDeleteMode
_ -> Bool
True
    CIRcvCall {} -> Bool
True
    CIRcvIntegrityError MsgErrorType
_ -> Bool
True
    CIRcvDecryptionError {} -> Bool
True
    CIRcvGroupInvitation {} -> Bool
True
    CIRcvDirectEvent RcvDirectEvent
rde -> case RcvDirectEvent
rde of
      RcvDirectEvent
RDEContactDeleted -> Bool
False
      RDEProfileUpdated {} -> Bool
False
      RDEGroupInvLinkReceived GroupProfile
_ -> Bool
True
    CIRcvGroupEvent RcvGroupEvent
rge -> case RcvGroupEvent
rge of
      RGEMemberAdded {} -> Bool
False
      RcvGroupEvent
RGEMemberConnected -> Bool
False
      RGEMemberAccepted {} -> Bool
False
      RcvGroupEvent
RGEUserAccepted -> Bool
False
      RcvGroupEvent
RGEMemberLeft -> Bool
False
      RGEMemberRole {} -> Bool
False
      RGEMemberBlocked {} -> Bool
False
      RGEUserRole GroupMemberRole
_ -> Bool
True
      RGEMemberDeleted {} -> Bool
False
      RcvGroupEvent
RGEUserDeleted -> Bool
True
      RcvGroupEvent
RGEGroupDeleted -> Bool
True
      RGEGroupUpdated GroupProfile
_ -> Bool
False
      RcvGroupEvent
RGEInvitedViaGroupLink -> Bool
False
      RcvGroupEvent
RGEMemberCreatedContact -> Bool
False
      RGEMemberProfileUpdated {} -> Bool
False
      RcvGroupEvent
RGENewMemberPendingReview -> Bool
True
    CIRcvConnEvent RcvConnEvent
_ -> Bool
True
    CIRcvChatFeature {} -> Bool
False
    CIRcvChatPreference {} -> Bool
False
    CIRcvGroupFeature {} -> Bool
False
    CIRcvChatFeatureRejected ChatFeature
_ -> Bool
True
    CIRcvGroupFeatureRejected GroupFeature
_ -> Bool
True
    CIContent d
CIRcvModerated -> Bool
True
    CIContent d
CIRcvBlocked -> Bool
False
    CIRcvDirectE2EEInfo E2EInfo
_ -> Bool
False
    CIRcvGroupE2EEInfo E2EInfo
_ -> Bool
False
    CIInvalidJSON Text
_ -> Bool
False

newtype DBMsgErrorType = DBME MsgErrorType

instance FromJSON DBMsgErrorType where
  parseJSON :: Value -> Parser DBMsgErrorType
parseJSON Value
v = MsgErrorType -> DBMsgErrorType
DBME (MsgErrorType -> DBMsgErrorType)
-> Parser MsgErrorType -> Parser DBMsgErrorType
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> $(JQ.mkParseJSON (singleFieldJSON fstToLower) ''MsgErrorType) Value
v

instance ToJSON DBMsgErrorType where
  toJSON :: DBMsgErrorType -> Value
toJSON (DBME MsgErrorType
v) = $(JQ.mkToJSON (singleFieldJSON fstToLower) ''MsgErrorType) MsgErrorType
v
  toEncoding :: DBMsgErrorType -> Encoding
toEncoding (DBME MsgErrorType
v) = $(JQ.mkToEncoding (singleFieldJSON fstToLower) ''MsgErrorType) MsgErrorType
v

data CIGroupInvitation = CIGroupInvitation
  { CIGroupInvitation -> AgentMsgId
groupId :: GroupId,
    CIGroupInvitation -> AgentMsgId
groupMemberId :: GroupMemberId,
    CIGroupInvitation -> Text
localDisplayName :: GroupName,
    CIGroupInvitation -> GroupProfile
groupProfile :: GroupProfile,
    CIGroupInvitation -> CIGroupInvitationStatus
status :: CIGroupInvitationStatus
  }
  deriving (CIGroupInvitation -> CIGroupInvitation -> Bool
(CIGroupInvitation -> CIGroupInvitation -> Bool)
-> (CIGroupInvitation -> CIGroupInvitation -> Bool)
-> Eq CIGroupInvitation
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: CIGroupInvitation -> CIGroupInvitation -> Bool
== :: CIGroupInvitation -> CIGroupInvitation -> Bool
$c/= :: CIGroupInvitation -> CIGroupInvitation -> Bool
/= :: CIGroupInvitation -> CIGroupInvitation -> Bool
Eq, Int -> CIGroupInvitation -> ShowS
[CIGroupInvitation] -> ShowS
CIGroupInvitation -> String
(Int -> CIGroupInvitation -> ShowS)
-> (CIGroupInvitation -> String)
-> ([CIGroupInvitation] -> ShowS)
-> Show CIGroupInvitation
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> CIGroupInvitation -> ShowS
showsPrec :: Int -> CIGroupInvitation -> ShowS
$cshow :: CIGroupInvitation -> String
show :: CIGroupInvitation -> String
$cshowList :: [CIGroupInvitation] -> ShowS
showList :: [CIGroupInvitation] -> ShowS
Show)

data CIGroupInvitationStatus
  = CIGISPending
  | CIGISAccepted
  | CIGISRejected
  | CIGISExpired
  deriving (CIGroupInvitationStatus -> CIGroupInvitationStatus -> Bool
(CIGroupInvitationStatus -> CIGroupInvitationStatus -> Bool)
-> (CIGroupInvitationStatus -> CIGroupInvitationStatus -> Bool)
-> Eq CIGroupInvitationStatus
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: CIGroupInvitationStatus -> CIGroupInvitationStatus -> Bool
== :: CIGroupInvitationStatus -> CIGroupInvitationStatus -> Bool
$c/= :: CIGroupInvitationStatus -> CIGroupInvitationStatus -> Bool
/= :: CIGroupInvitationStatus -> CIGroupInvitationStatus -> Bool
Eq, Int -> CIGroupInvitationStatus -> ShowS
[CIGroupInvitationStatus] -> ShowS
CIGroupInvitationStatus -> String
(Int -> CIGroupInvitationStatus -> ShowS)
-> (CIGroupInvitationStatus -> String)
-> ([CIGroupInvitationStatus] -> ShowS)
-> Show CIGroupInvitationStatus
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> CIGroupInvitationStatus -> ShowS
showsPrec :: Int -> CIGroupInvitationStatus -> ShowS
$cshow :: CIGroupInvitationStatus -> String
show :: CIGroupInvitationStatus -> String
$cshowList :: [CIGroupInvitationStatus] -> ShowS
showList :: [CIGroupInvitationStatus] -> ShowS
Show)

ciContentToText :: CIContent d -> Text
ciContentToText :: forall (d :: MsgDirection). CIContent d -> Text
ciContentToText = \case
  CISndMsgContent MsgContent
mc -> MsgContent -> Text
msgContentText MsgContent
mc
  CIRcvMsgContent MsgContent
mc -> MsgContent -> Text
msgContentText MsgContent
mc
  CISndDeleted CIDeleteMode
cidm -> CIDeleteMode -> Text
ciDeleteModeToText CIDeleteMode
cidm
  CIRcvDeleted CIDeleteMode
cidm -> CIDeleteMode -> Text
ciDeleteModeToText CIDeleteMode
cidm
  CISndCall CICallStatus
status Int
duration -> Text
"outgoing call: " Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> CICallStatus -> Int -> Text
ciCallInfoText CICallStatus
status Int
duration
  CIRcvCall CICallStatus
status Int
duration -> Text
"incoming call: " Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> CICallStatus -> Int -> Text
ciCallInfoText CICallStatus
status Int
duration
  CIRcvIntegrityError MsgErrorType
err -> MsgErrorType -> Text
msgIntegrityError MsgErrorType
err
  CIRcvDecryptionError MsgDecryptError
err Word32
n -> MsgDecryptError -> Word32 -> Text
msgDecryptErrorText MsgDecryptError
err Word32
n
  CIRcvGroupInvitation CIGroupInvitation
groupInvitation GroupMemberRole
memberRole -> Text
"received " Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> CIGroupInvitation -> GroupMemberRole -> Text
ciGroupInvitationToText CIGroupInvitation
groupInvitation GroupMemberRole
memberRole
  CISndGroupInvitation CIGroupInvitation
groupInvitation GroupMemberRole
memberRole -> Text
"sent " Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> CIGroupInvitation -> GroupMemberRole -> Text
ciGroupInvitationToText CIGroupInvitation
groupInvitation GroupMemberRole
memberRole
  CIRcvDirectEvent RcvDirectEvent
event -> RcvDirectEvent -> Text
rcvDirectEventToText RcvDirectEvent
event
  CIRcvGroupEvent RcvGroupEvent
event -> RcvGroupEvent -> Text
rcvGroupEventToText RcvGroupEvent
event
  CISndGroupEvent SndGroupEvent
event -> SndGroupEvent -> Text
sndGroupEventToText SndGroupEvent
event
  CIRcvConnEvent RcvConnEvent
event -> RcvConnEvent -> Text
rcvConnEventToText RcvConnEvent
event
  CISndConnEvent SndConnEvent
event -> SndConnEvent -> Text
sndConnEventToText SndConnEvent
event
  CIRcvChatFeature ChatFeature
feature PrefEnabled
enabled Maybe Int
param -> ChatFeature -> PrefEnabled -> Maybe Int -> Text
featureStateText ChatFeature
feature PrefEnabled
enabled Maybe Int
param
  CISndChatFeature ChatFeature
feature PrefEnabled
enabled Maybe Int
param -> ChatFeature -> PrefEnabled -> Maybe Int -> Text
featureStateText ChatFeature
feature PrefEnabled
enabled Maybe Int
param
  CIRcvChatPreference ChatFeature
feature FeatureAllowed
allowed Maybe Int
param -> ChatFeature -> FeatureAllowed -> Maybe Int -> Text
prefStateText ChatFeature
feature FeatureAllowed
allowed Maybe Int
param
  CISndChatPreference ChatFeature
feature FeatureAllowed
allowed Maybe Int
param -> Text
"you " Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> ChatFeature -> FeatureAllowed -> Maybe Int -> Text
prefStateText ChatFeature
feature FeatureAllowed
allowed Maybe Int
param
  CIRcvGroupFeature GroupFeature
feature GroupPreference
pref Maybe Int
param Maybe GroupMemberRole
role -> GroupFeature
-> GroupPreference -> Maybe Int -> Maybe GroupMemberRole -> Text
forall p.
HasField "enable" p GroupFeatureEnabled =>
GroupFeature -> p -> Maybe Int -> Maybe GroupMemberRole -> Text
groupPrefStateText GroupFeature
feature GroupPreference
pref Maybe Int
param Maybe GroupMemberRole
role
  CISndGroupFeature GroupFeature
feature GroupPreference
pref Maybe Int
param Maybe GroupMemberRole
role -> GroupFeature
-> GroupPreference -> Maybe Int -> Maybe GroupMemberRole -> Text
forall p.
HasField "enable" p GroupFeatureEnabled =>
GroupFeature -> p -> Maybe Int -> Maybe GroupMemberRole -> Text
groupPrefStateText GroupFeature
feature GroupPreference
pref Maybe Int
param Maybe GroupMemberRole
role
  CIRcvChatFeatureRejected ChatFeature
feature -> ChatFeature -> Text
chatFeatureNameText ChatFeature
feature Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
": received, prohibited"
  CIRcvGroupFeatureRejected GroupFeature
feature -> GroupFeature -> Text
groupFeatureNameText GroupFeature
feature Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
": received, prohibited"
  CIContent d
CISndModerated -> Text
ciModeratedText
  CIContent d
CIRcvModerated -> Text
ciModeratedText
  CIContent d
CIRcvBlocked -> Text
"blocked"
  CISndDirectE2EEInfo E2EInfo
e2eeInfo -> E2EInfo -> Text
directE2EInfoToText E2EInfo
e2eeInfo
  CIRcvDirectE2EEInfo E2EInfo
e2eeInfo -> E2EInfo -> Text
directE2EInfoToText E2EInfo
e2eeInfo
  CISndGroupE2EEInfo E2EInfo
e2eeInfo -> E2EInfo -> Text
groupE2EInfoToText E2EInfo
e2eeInfo
  CIRcvGroupE2EEInfo E2EInfo
e2eeInfo -> E2EInfo -> Text
groupE2EInfoToText E2EInfo
e2eeInfo
  CIContent d
CIChatBanner -> Text
"chat banner"
  CIInvalidJSON Text
_ -> Text
"invalid content JSON"

directE2EInfoToText :: E2EInfo -> Text
directE2EInfoToText :: E2EInfo -> Text
directE2EInfoToText E2EInfo {Maybe PQEncryption
pqEnabled :: E2EInfo -> Maybe PQEncryption
pqEnabled :: Maybe PQEncryption
pqEnabled} = case Maybe PQEncryption
pqEnabled of
  Just PQEncryption
PQEncOn -> Text
e2eInfoPQText
  Just PQEncryption
PQEncOff -> Text
e2eInfoNoPQText
  Maybe PQEncryption
Nothing -> Text
simpleE2EText

groupE2EInfoToText :: E2EInfo -> Text
groupE2EInfoToText :: E2EInfo -> Text
groupE2EInfoToText E2EInfo {Maybe PQEncryption
pqEnabled :: E2EInfo -> Maybe PQEncryption
pqEnabled :: Maybe PQEncryption
pqEnabled} = case Maybe PQEncryption
pqEnabled of
  Just PQEncryption
_ -> Text
e2eInfoNoPQText
  Maybe PQEncryption
Nothing -> Text
simpleE2EText

simpleE2EText :: Text
simpleE2EText :: Text
simpleE2EText = Text
"This conversation is protected by end-to-end encryption"

e2eInfoNoPQText :: Text
e2eInfoNoPQText :: Text
e2eInfoNoPQText =
  Text
"This conversation is protected by end-to-end encryption with perfect forward secrecy, repudiation and break-in recovery."

e2eInfoPQText :: Text
e2eInfoPQText :: Text
e2eInfoPQText =
  Text
"This conversation is protected by quantum resistant end-to-end encryption. It has perfect forward secrecy, repudiation and quantum resistant break-in recovery."

ciGroupInvitationToText :: CIGroupInvitation -> GroupMemberRole -> Text
ciGroupInvitationToText :: CIGroupInvitation -> GroupMemberRole -> Text
ciGroupInvitationToText CIGroupInvitation {groupProfile :: CIGroupInvitation -> GroupProfile
groupProfile = GroupProfile {Text
displayName :: Text
displayName :: GroupProfile -> Text
displayName, Text
fullName :: Text
fullName :: GroupProfile -> Text
fullName}} GroupMemberRole
role =
  Text
"invitation to join group " Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
displayName Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text -> Text -> Maybe Text -> Text
optionalFullName Text
displayName Text
fullName Maybe Text
forall a. Maybe a
Nothing Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
" as " Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> (ByteString -> Text
decodeLatin1 (ByteString -> Text)
-> (GroupMemberRole -> ByteString) -> GroupMemberRole -> Text
forall b c a. (b -> c) -> (a -> b) -> a -> c
. GroupMemberRole -> ByteString
forall a. StrEncoding a => a -> ByteString
strEncode (GroupMemberRole -> Text) -> GroupMemberRole -> Text
forall a b. (a -> b) -> a -> b
$ GroupMemberRole
role)

rcvDirectEventToText :: RcvDirectEvent -> Text
rcvDirectEventToText :: RcvDirectEvent -> Text
rcvDirectEventToText = \case
  RcvDirectEvent
RDEContactDeleted -> Text
"contact deleted"
  RDEProfileUpdated {} -> Text
"updated profile"
  RDEGroupInvLinkReceived GroupProfile {Text
displayName :: GroupProfile -> Text
displayName :: Text
displayName} -> Text
"requested connection from group " Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
displayName

rcvGroupEventToText :: RcvGroupEvent -> Text
rcvGroupEventToText :: RcvGroupEvent -> Text
rcvGroupEventToText = \case
  RGEMemberAdded AgentMsgId
_ Profile
p -> Text
"added " Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Profile -> Text
profileToText Profile
p
  RcvGroupEvent
RGEMemberConnected -> Text
"connected"
  RGEMemberAccepted AgentMsgId
_ Profile
p -> Text
"accepted " Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Profile -> Text
profileToText Profile
p
  RcvGroupEvent
RGEUserAccepted -> Text
"accepted you"
  RcvGroupEvent
RGEMemberLeft -> Text
"left"
  RGEMemberRole AgentMsgId
_ Profile
p GroupMemberRole
r -> Text
"changed role of " Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Profile -> Text
profileToText Profile
p Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
" to " Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> ByteString -> Text
safeDecodeUtf8 (GroupMemberRole -> ByteString
forall a. StrEncoding a => a -> ByteString
strEncode GroupMemberRole
r)
  RGEMemberBlocked AgentMsgId
_ Profile
p Bool
blocked -> (if Bool
blocked then Text
"blocked" else Text
"unblocked") Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
" " Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Profile -> Text
profileToText Profile
p
  RGEUserRole GroupMemberRole
r -> Text
"changed your role to " Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> ByteString -> Text
safeDecodeUtf8 (GroupMemberRole -> ByteString
forall a. StrEncoding a => a -> ByteString
strEncode GroupMemberRole
r)
  RGEMemberDeleted AgentMsgId
_ Profile
p -> Text
"removed " Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Profile -> Text
profileToText Profile
p
  RcvGroupEvent
RGEUserDeleted -> Text
"removed you"
  RcvGroupEvent
RGEGroupDeleted -> Text
"deleted group"
  RGEGroupUpdated GroupProfile
_ -> Text
"group profile updated"
  RcvGroupEvent
RGEInvitedViaGroupLink -> Text
"invited via your group link"
  RcvGroupEvent
RGEMemberCreatedContact -> Text
"started direct connection with you"
  RGEMemberProfileUpdated {} -> Text
"updated profile"
  RcvGroupEvent
RGENewMemberPendingReview -> Text
"new member wants to join the group"

sndGroupEventToText :: SndGroupEvent -> Text
sndGroupEventToText :: SndGroupEvent -> Text
sndGroupEventToText = \case
  SGEMemberRole AgentMsgId
_ Profile
p GroupMemberRole
r -> Text
"changed role of " Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Profile -> Text
profileToText Profile
p Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
" to " Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> ByteString -> Text
safeDecodeUtf8 (GroupMemberRole -> ByteString
forall a. StrEncoding a => a -> ByteString
strEncode GroupMemberRole
r)
  SGEMemberBlocked AgentMsgId
_ Profile
p Bool
blocked -> (if Bool
blocked then Text
"blocked" else Text
"unblocked") Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
" " Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Profile -> Text
profileToText Profile
p
  SGEUserRole GroupMemberRole
r -> Text
"changed role for yourself to " Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> ByteString -> Text
safeDecodeUtf8 (GroupMemberRole -> ByteString
forall a. StrEncoding a => a -> ByteString
strEncode GroupMemberRole
r)
  SGEMemberDeleted AgentMsgId
_ Profile
p -> Text
"removed " Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Profile -> Text
profileToText Profile
p
  SndGroupEvent
SGEUserLeft -> Text
"left"
  SGEGroupUpdated GroupProfile
_ -> Text
"group profile updated"
  SGEMemberAccepted AgentMsgId
_ Profile
_p -> Text
"you accepted this member"
  SndGroupEvent
SGEUserPendingReview -> Text
"please wait for group moderators to review your request to join the group"

-- used to send to members with old version
pendingReviewMessage :: Text
pendingReviewMessage :: Text
pendingReviewMessage =
  Text
"Please wait for group moderators to review your request to join the group."

-- used to send to members with old version
acceptedToGroupMessage :: Text
acceptedToGroupMessage :: Text
acceptedToGroupMessage =
  Text
"You are accepted to the group."

rcvConnEventToText :: RcvConnEvent -> Text
rcvConnEventToText :: RcvConnEvent -> Text
rcvConnEventToText = \case
  RCESwitchQueue SwitchPhase
phase -> case SwitchPhase
phase of
    SwitchPhase
SPStarted -> Text
"started changing address for you..."
    SwitchPhase
SPConfirmed -> Text
"confirmed changing address for you..."
    SwitchPhase
SPSecured -> Text
"secured new address for you..."
    SwitchPhase
SPCompleted -> Text
"changed address for you"
  RCERatchetSync RatchetSyncState
syncStatus -> RatchetSyncState -> Text
ratchetSyncStatusToText RatchetSyncState
syncStatus
  RcvConnEvent
RCEVerificationCodeReset -> Text
"security code changed"
  RCEPqEnabled PQEncryption
pqEnc -> case PQEncryption
pqEnc of
    PQEncryption
PQEncOn -> Text
"quantum resistant e2e encryption"
    PQEncryption
PQEncOff -> Text
"standard end-to-end encryption"

ratchetSyncStatusToText :: RatchetSyncState -> Text
ratchetSyncStatusToText :: RatchetSyncState -> Text
ratchetSyncStatusToText = \case
  RatchetSyncState
RSOk -> Text
"connection synchronized"
  RatchetSyncState
RSAllowed -> Text
"decryption error (connection may be out of sync), synchronization allowed"
  RatchetSyncState
RSRequired -> Text
"decryption error (connection out of sync), synchronization required"
  RatchetSyncState
RSStarted -> Text
"connection synchronization started"
  RatchetSyncState
RSAgreed -> Text
"connection synchronization agreed"

sndConnEventToText :: SndConnEvent -> Text
sndConnEventToText :: SndConnEvent -> Text
sndConnEventToText = \case
  SCESwitchQueue SwitchPhase
phase Maybe GroupMemberRef
m -> case SwitchPhase
phase of
    SwitchPhase
SPStarted -> Text
"started changing address" Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Maybe GroupMemberRef -> Text
forMember Maybe GroupMemberRef
m Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
"..."
    SwitchPhase
SPConfirmed -> Text
"confirmed changing address" Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Maybe GroupMemberRef -> Text
forMember Maybe GroupMemberRef
m Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
"..."
    SwitchPhase
SPSecured -> Text
"secured new address" Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Maybe GroupMemberRef -> Text
forMember Maybe GroupMemberRef
m Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
"..."
    SwitchPhase
SPCompleted -> Text
"you changed address" Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Maybe GroupMemberRef -> Text
forMember Maybe GroupMemberRef
m
  SCERatchetSync RatchetSyncState
syncStatus Maybe GroupMemberRef
m -> RatchetSyncState -> Text
ratchetSyncStatusToText RatchetSyncState
syncStatus Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Maybe GroupMemberRef -> Text
forMember Maybe GroupMemberRef
m
  SCEPqEnabled PQEncryption
pqEnc -> case PQEncryption
pqEnc of
    PQEncryption
PQEncOn -> Text
"quantum resistant e2e encryption"
    PQEncryption
PQEncOff -> Text
"standard end-to-end encryption"
  where
    forMember :: Maybe GroupMemberRef -> Text
forMember Maybe GroupMemberRef
member_ =
      Text -> (GroupMemberRef -> Text) -> Maybe GroupMemberRef -> Text
forall b a. b -> (a -> b) -> Maybe a -> b
maybe Text
"" (\GroupMemberRef {profile :: GroupMemberRef -> Profile
profile = Profile {Text
displayName :: Text
displayName :: Profile -> Text
displayName}} -> Text
" for " Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
displayName) Maybe GroupMemberRef
member_

profileToText :: Profile -> Text
profileToText :: Profile -> Text
profileToText Profile {Text
displayName :: Profile -> Text
displayName :: Text
displayName, Text
fullName :: Text
fullName :: Profile -> Text
fullName} = Text
displayName Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text -> Text -> Maybe Text -> Text
optionalFullName Text
displayName Text
fullName Maybe Text
forall a. Maybe a
Nothing

msgIntegrityError :: MsgErrorType -> Text
msgIntegrityError :: MsgErrorType -> Text
msgIntegrityError = \case
  MsgSkipped AgentMsgId
fromId AgentMsgId
toId ->
    (Text
"skipped message ID " Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> AgentMsgId -> Text
forall a. Show a => a -> Text
tshow AgentMsgId
fromId)
      Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> if AgentMsgId
fromId AgentMsgId -> AgentMsgId -> Bool
forall a. Eq a => a -> a -> Bool
== AgentMsgId
toId then Text
"" else Text
".." Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> AgentMsgId -> Text
forall a. Show a => a -> Text
tshow AgentMsgId
toId
  MsgBadId AgentMsgId
msgId -> Text
"unexpected message ID " Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> AgentMsgId -> Text
forall a. Show a => a -> Text
tshow AgentMsgId
msgId
  MsgErrorType
MsgBadHash -> Text
"incorrect message hash"
  MsgErrorType
MsgDuplicate -> Text
"duplicate message ID"

msgDecryptErrorText :: MsgDecryptError -> Word32 -> Text
msgDecryptErrorText :: MsgDecryptError -> Word32 -> Text
msgDecryptErrorText MsgDecryptError
err Word32
n =
  Text
"decryption error, possibly due to the device change"
    Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text -> (Text -> Text) -> Maybe Text -> Text
forall b a. b -> (a -> b) -> Maybe a -> b
maybe Text
"" (\Text
ed -> Text
" (" Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
ed Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
")") Maybe Text
errDesc
  where
    errDesc :: Maybe Text
errDesc = case MsgDecryptError
err of
      MsgDecryptError
MDERatchetHeader -> Text -> Maybe Text
forall a. a -> Maybe a
Just (Text -> Maybe Text) -> Text -> Maybe Text
forall a b. (a -> b) -> a -> b
$ Text
"header" Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
counter
      MsgDecryptError
MDETooManySkipped -> Text -> Maybe Text
forall a. a -> Maybe a
Just (Text -> Maybe Text) -> Text -> Maybe Text
forall a b. (a -> b) -> a -> b
$ Text
"too many skipped messages" Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
counter
      MsgDecryptError
MDERatchetEarlier -> Text -> Maybe Text
forall a. a -> Maybe a
Just (Text -> Maybe Text) -> Text -> Maybe Text
forall a b. (a -> b) -> a -> b
$ Text
"earlier message" Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
counter
      MsgDecryptError
MDEOther -> Maybe Text
counter_
      MsgDecryptError
MDERatchetSync -> Text -> Maybe Text
forall a. a -> Maybe a
Just Text
"synchronization error"
    counter_ :: Maybe Text
counter_ = if Word32
n Word32 -> Word32 -> Bool
forall a. Eq a => a -> a -> Bool
== Word32
1 then Maybe Text
forall a. Maybe a
Nothing else Text -> Maybe Text
forall a. a -> Maybe a
Just (Text -> Maybe Text) -> Text -> Maybe Text
forall a b. (a -> b) -> a -> b
$ Word32 -> Text
forall a. Show a => a -> Text
tshow Word32
n Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
" messages"
    counter :: Text
counter = Text -> (Text -> Text) -> Maybe Text -> Text
forall b a. b -> (a -> b) -> Maybe a -> b
maybe Text
"" (Text
", " Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<>) Maybe Text
counter_

msgDirToModeratedContent_ :: SMsgDirection d -> CIContent d
msgDirToModeratedContent_ :: forall (d :: MsgDirection). SMsgDirection d -> CIContent d
msgDirToModeratedContent_ = \case
  SMsgDirection d
SMDRcv -> CIContent d
CIContent 'MDRcv
CIRcvModerated
  SMsgDirection d
SMDSnd -> CIContent d
CIContent 'MDSnd
CISndModerated

ciModeratedText :: Text
ciModeratedText :: Text
ciModeratedText = Text
"moderated"

data ACIContent = forall d. MsgDirectionI d => ACIContent (SMsgDirection d) (CIContent d)

deriving instance Show ACIContent

-- platform specific
data JSONCIContent
  = JCISndMsgContent {JSONCIContent -> MsgContent
msgContent :: MsgContent}
  | JCIRcvMsgContent {msgContent :: MsgContent}
  | JCISndDeleted {JSONCIContent -> CIDeleteMode
deleteMode :: CIDeleteMode}
  | JCIRcvDeleted {deleteMode :: CIDeleteMode}
  | JCISndCall {JSONCIContent -> CICallStatus
status :: CICallStatus, JSONCIContent -> Int
duration :: Int} -- duration in seconds
  | JCIRcvCall {status :: CICallStatus, duration :: Int}
  | JCIRcvIntegrityError {JSONCIContent -> MsgErrorType
msgError :: MsgErrorType}
  | JCIRcvDecryptionError {JSONCIContent -> MsgDecryptError
msgDecryptError :: MsgDecryptError, JSONCIContent -> Word32
msgCount :: Word32}
  | JCIRcvGroupInvitation {JSONCIContent -> CIGroupInvitation
groupInvitation :: CIGroupInvitation, JSONCIContent -> GroupMemberRole
memberRole :: GroupMemberRole}
  | JCISndGroupInvitation {groupInvitation :: CIGroupInvitation, memberRole :: GroupMemberRole}
  | JCIRcvDirectEvent {JSONCIContent -> RcvDirectEvent
rcvDirectEvent :: RcvDirectEvent}
  | JCIRcvGroupEvent {JSONCIContent -> RcvGroupEvent
rcvGroupEvent :: RcvGroupEvent}
  | JCISndGroupEvent {JSONCIContent -> SndGroupEvent
sndGroupEvent :: SndGroupEvent}
  | JCIRcvConnEvent {JSONCIContent -> RcvConnEvent
rcvConnEvent :: RcvConnEvent}
  | JCISndConnEvent {JSONCIContent -> SndConnEvent
sndConnEvent :: SndConnEvent}
  | JCIRcvChatFeature {JSONCIContent -> ChatFeature
feature :: ChatFeature, JSONCIContent -> PrefEnabled
enabled :: PrefEnabled, JSONCIContent -> Maybe Int
param :: Maybe Int}
  | JCISndChatFeature {feature :: ChatFeature, enabled :: PrefEnabled, param :: Maybe Int}
  | JCIRcvChatPreference {feature :: ChatFeature, JSONCIContent -> FeatureAllowed
allowed :: FeatureAllowed, param :: Maybe Int}
  | JCISndChatPreference {feature :: ChatFeature, allowed :: FeatureAllowed, param :: Maybe Int}
  | JCIRcvGroupFeature {JSONCIContent -> GroupFeature
groupFeature :: GroupFeature, JSONCIContent -> GroupPreference
preference :: GroupPreference, param :: Maybe Int, JSONCIContent -> Maybe GroupMemberRole
memberRole_ :: Maybe GroupMemberRole}
  | JCISndGroupFeature {groupFeature :: GroupFeature, preference :: GroupPreference, param :: Maybe Int, memberRole_ :: Maybe GroupMemberRole}
  | JCIRcvChatFeatureRejected {feature :: ChatFeature}
  | JCIRcvGroupFeatureRejected {groupFeature :: GroupFeature}
  | JCISndModerated
  | JCIRcvModerated
  | JCIRcvBlocked
  | JCISndDirectE2EEInfo {JSONCIContent -> E2EInfo
e2eeInfo :: E2EInfo}
  | JCIRcvDirectE2EEInfo {e2eeInfo :: E2EInfo}
  | JCISndGroupE2EEInfo {e2eeInfo :: E2EInfo}
  | JCIRcvGroupE2EEInfo {e2eeInfo :: E2EInfo}
  | JCIChatBanner
  | JCIInvalidJSON {JSONCIContent -> MsgDirection
direction :: MsgDirection, JSONCIContent -> Text
json :: Text}

jsonCIContent :: forall d. MsgDirectionI d => CIContent d -> JSONCIContent
jsonCIContent :: forall (d :: MsgDirection).
MsgDirectionI d =>
CIContent d -> JSONCIContent
jsonCIContent = \case
  CISndMsgContent MsgContent
mc -> MsgContent -> JSONCIContent
JCISndMsgContent MsgContent
mc
  CIRcvMsgContent MsgContent
mc -> MsgContent -> JSONCIContent
JCIRcvMsgContent MsgContent
mc
  CISndDeleted CIDeleteMode
cidm -> CIDeleteMode -> JSONCIContent
JCISndDeleted CIDeleteMode
cidm
  CIRcvDeleted CIDeleteMode
cidm -> CIDeleteMode -> JSONCIContent
JCIRcvDeleted CIDeleteMode
cidm
  CISndCall CICallStatus
status Int
duration -> JCISndCall {CICallStatus
status :: CICallStatus
status :: CICallStatus
status, Int
duration :: Int
duration :: Int
duration}
  CIRcvCall CICallStatus
status Int
duration -> JCIRcvCall {CICallStatus
status :: CICallStatus
status :: CICallStatus
status, Int
duration :: Int
duration :: Int
duration}
  CIRcvIntegrityError MsgErrorType
err -> MsgErrorType -> JSONCIContent
JCIRcvIntegrityError MsgErrorType
err
  CIRcvDecryptionError MsgDecryptError
err Word32
n -> MsgDecryptError -> Word32 -> JSONCIContent
JCIRcvDecryptionError MsgDecryptError
err Word32
n
  CIRcvGroupInvitation CIGroupInvitation
groupInvitation GroupMemberRole
memberRole -> JCIRcvGroupInvitation {CIGroupInvitation
groupInvitation :: CIGroupInvitation
groupInvitation :: CIGroupInvitation
groupInvitation, GroupMemberRole
memberRole :: GroupMemberRole
memberRole :: GroupMemberRole
memberRole}
  CISndGroupInvitation CIGroupInvitation
groupInvitation GroupMemberRole
memberRole -> JCISndGroupInvitation {CIGroupInvitation
groupInvitation :: CIGroupInvitation
groupInvitation :: CIGroupInvitation
groupInvitation, GroupMemberRole
memberRole :: GroupMemberRole
memberRole :: GroupMemberRole
memberRole}
  CIRcvDirectEvent RcvDirectEvent
rcvDirectEvent -> JCIRcvDirectEvent {RcvDirectEvent
rcvDirectEvent :: RcvDirectEvent
rcvDirectEvent :: RcvDirectEvent
rcvDirectEvent}
  CIRcvGroupEvent RcvGroupEvent
rcvGroupEvent -> JCIRcvGroupEvent {RcvGroupEvent
rcvGroupEvent :: RcvGroupEvent
rcvGroupEvent :: RcvGroupEvent
rcvGroupEvent}
  CISndGroupEvent SndGroupEvent
sndGroupEvent -> JCISndGroupEvent {SndGroupEvent
sndGroupEvent :: SndGroupEvent
sndGroupEvent :: SndGroupEvent
sndGroupEvent}
  CIRcvConnEvent RcvConnEvent
rcvConnEvent -> JCIRcvConnEvent {RcvConnEvent
rcvConnEvent :: RcvConnEvent
rcvConnEvent :: RcvConnEvent
rcvConnEvent}
  CISndConnEvent SndConnEvent
sndConnEvent -> JCISndConnEvent {SndConnEvent
sndConnEvent :: SndConnEvent
sndConnEvent :: SndConnEvent
sndConnEvent}
  CIRcvChatFeature ChatFeature
feature PrefEnabled
enabled Maybe Int
param -> JCIRcvChatFeature {ChatFeature
feature :: ChatFeature
feature :: ChatFeature
feature, PrefEnabled
enabled :: PrefEnabled
enabled :: PrefEnabled
enabled, Maybe Int
param :: Maybe Int
param :: Maybe Int
param}
  CISndChatFeature ChatFeature
feature PrefEnabled
enabled Maybe Int
param -> JCISndChatFeature {ChatFeature
feature :: ChatFeature
feature :: ChatFeature
feature, PrefEnabled
enabled :: PrefEnabled
enabled :: PrefEnabled
enabled, Maybe Int
param :: Maybe Int
param :: Maybe Int
param}
  CIRcvChatPreference ChatFeature
feature FeatureAllowed
allowed Maybe Int
param -> JCIRcvChatPreference {ChatFeature
feature :: ChatFeature
feature :: ChatFeature
feature, FeatureAllowed
allowed :: FeatureAllowed
allowed :: FeatureAllowed
allowed, Maybe Int
param :: Maybe Int
param :: Maybe Int
param}
  CISndChatPreference ChatFeature
feature FeatureAllowed
allowed Maybe Int
param -> JCISndChatPreference {ChatFeature
feature :: ChatFeature
feature :: ChatFeature
feature, FeatureAllowed
allowed :: FeatureAllowed
allowed :: FeatureAllowed
allowed, Maybe Int
param :: Maybe Int
param :: Maybe Int
param}
  CIRcvGroupFeature GroupFeature
groupFeature GroupPreference
preference Maybe Int
param Maybe GroupMemberRole
memberRole_ -> JCIRcvGroupFeature {GroupFeature
groupFeature :: GroupFeature
groupFeature :: GroupFeature
groupFeature, GroupPreference
preference :: GroupPreference
preference :: GroupPreference
preference, Maybe Int
param :: Maybe Int
param :: Maybe Int
param, Maybe GroupMemberRole
memberRole_ :: Maybe GroupMemberRole
memberRole_ :: Maybe GroupMemberRole
memberRole_}
  CISndGroupFeature GroupFeature
groupFeature GroupPreference
preference Maybe Int
param Maybe GroupMemberRole
memberRole_ -> JCISndGroupFeature {GroupFeature
groupFeature :: GroupFeature
groupFeature :: GroupFeature
groupFeature, GroupPreference
preference :: GroupPreference
preference :: GroupPreference
preference, Maybe Int
param :: Maybe Int
param :: Maybe Int
param, Maybe GroupMemberRole
memberRole_ :: Maybe GroupMemberRole
memberRole_ :: Maybe GroupMemberRole
memberRole_}
  CIRcvChatFeatureRejected ChatFeature
feature -> JCIRcvChatFeatureRejected {ChatFeature
feature :: ChatFeature
feature :: ChatFeature
feature}
  CIRcvGroupFeatureRejected GroupFeature
groupFeature -> JCIRcvGroupFeatureRejected {GroupFeature
groupFeature :: GroupFeature
groupFeature :: GroupFeature
groupFeature}
  CIContent d
CISndModerated -> JSONCIContent
JCISndModerated
  CIContent d
CIRcvModerated -> JSONCIContent
JCIRcvModerated
  CIContent d
CIRcvBlocked -> JSONCIContent
JCIRcvBlocked
  CISndDirectE2EEInfo E2EInfo
e2eeInfo -> E2EInfo -> JSONCIContent
JCISndDirectE2EEInfo E2EInfo
e2eeInfo
  CIRcvDirectE2EEInfo E2EInfo
e2eeInfo -> E2EInfo -> JSONCIContent
JCIRcvDirectE2EEInfo E2EInfo
e2eeInfo
  CISndGroupE2EEInfo E2EInfo
e2eeInfo -> E2EInfo -> JSONCIContent
JCISndGroupE2EEInfo E2EInfo
e2eeInfo
  CIRcvGroupE2EEInfo E2EInfo
e2eeInfo -> E2EInfo -> JSONCIContent
JCIRcvGroupE2EEInfo E2EInfo
e2eeInfo
  CIContent d
CIChatBanner -> JSONCIContent
JCIChatBanner
  CIInvalidJSON Text
json -> MsgDirection -> Text -> JSONCIContent
JCIInvalidJSON (SMsgDirection d -> MsgDirection
forall (d :: MsgDirection). SMsgDirection d -> MsgDirection
toMsgDirection (SMsgDirection d -> MsgDirection)
-> SMsgDirection d -> MsgDirection
forall a b. (a -> b) -> a -> b
$ forall (d :: MsgDirection). MsgDirectionI d => SMsgDirection d
msgDirection @d) Text
json

aciContentJSON :: JSONCIContent -> ACIContent
aciContentJSON :: JSONCIContent -> ACIContent
aciContentJSON = \case
  JCISndMsgContent MsgContent
mc -> SMsgDirection 'MDSnd -> CIContent 'MDSnd -> ACIContent
forall (d :: MsgDirection).
MsgDirectionI d =>
SMsgDirection d -> CIContent d -> ACIContent
ACIContent SMsgDirection 'MDSnd
SMDSnd (CIContent 'MDSnd -> ACIContent) -> CIContent 'MDSnd -> ACIContent
forall a b. (a -> b) -> a -> b
$ MsgContent -> CIContent 'MDSnd
CISndMsgContent MsgContent
mc
  JCIRcvMsgContent MsgContent
mc -> SMsgDirection 'MDRcv -> CIContent 'MDRcv -> ACIContent
forall (d :: MsgDirection).
MsgDirectionI d =>
SMsgDirection d -> CIContent d -> ACIContent
ACIContent SMsgDirection 'MDRcv
SMDRcv (CIContent 'MDRcv -> ACIContent) -> CIContent 'MDRcv -> ACIContent
forall a b. (a -> b) -> a -> b
$ MsgContent -> CIContent 'MDRcv
CIRcvMsgContent MsgContent
mc
  JCISndDeleted CIDeleteMode
cidm -> SMsgDirection 'MDSnd -> CIContent 'MDSnd -> ACIContent
forall (d :: MsgDirection).
MsgDirectionI d =>
SMsgDirection d -> CIContent d -> ACIContent
ACIContent SMsgDirection 'MDSnd
SMDSnd (CIContent 'MDSnd -> ACIContent) -> CIContent 'MDSnd -> ACIContent
forall a b. (a -> b) -> a -> b
$ CIDeleteMode -> CIContent 'MDSnd
CISndDeleted CIDeleteMode
cidm
  JCIRcvDeleted CIDeleteMode
cidm -> SMsgDirection 'MDRcv -> CIContent 'MDRcv -> ACIContent
forall (d :: MsgDirection).
MsgDirectionI d =>
SMsgDirection d -> CIContent d -> ACIContent
ACIContent SMsgDirection 'MDRcv
SMDRcv (CIContent 'MDRcv -> ACIContent) -> CIContent 'MDRcv -> ACIContent
forall a b. (a -> b) -> a -> b
$ CIDeleteMode -> CIContent 'MDRcv
CIRcvDeleted CIDeleteMode
cidm
  JCISndCall {CICallStatus
status :: JSONCIContent -> CICallStatus
status :: CICallStatus
status, Int
duration :: JSONCIContent -> Int
duration :: Int
duration} -> SMsgDirection 'MDSnd -> CIContent 'MDSnd -> ACIContent
forall (d :: MsgDirection).
MsgDirectionI d =>
SMsgDirection d -> CIContent d -> ACIContent
ACIContent SMsgDirection 'MDSnd
SMDSnd (CIContent 'MDSnd -> ACIContent) -> CIContent 'MDSnd -> ACIContent
forall a b. (a -> b) -> a -> b
$ CICallStatus -> Int -> CIContent 'MDSnd
CISndCall CICallStatus
status Int
duration
  JCIRcvCall {CICallStatus
status :: JSONCIContent -> CICallStatus
status :: CICallStatus
status, Int
duration :: JSONCIContent -> Int
duration :: Int
duration} -> SMsgDirection 'MDRcv -> CIContent 'MDRcv -> ACIContent
forall (d :: MsgDirection).
MsgDirectionI d =>
SMsgDirection d -> CIContent d -> ACIContent
ACIContent SMsgDirection 'MDRcv
SMDRcv (CIContent 'MDRcv -> ACIContent) -> CIContent 'MDRcv -> ACIContent
forall a b. (a -> b) -> a -> b
$ CICallStatus -> Int -> CIContent 'MDRcv
CIRcvCall CICallStatus
status Int
duration
  JCIRcvIntegrityError MsgErrorType
err -> SMsgDirection 'MDRcv -> CIContent 'MDRcv -> ACIContent
forall (d :: MsgDirection).
MsgDirectionI d =>
SMsgDirection d -> CIContent d -> ACIContent
ACIContent SMsgDirection 'MDRcv
SMDRcv (CIContent 'MDRcv -> ACIContent) -> CIContent 'MDRcv -> ACIContent
forall a b. (a -> b) -> a -> b
$ MsgErrorType -> CIContent 'MDRcv
CIRcvIntegrityError MsgErrorType
err
  JCIRcvDecryptionError MsgDecryptError
err Word32
n -> SMsgDirection 'MDRcv -> CIContent 'MDRcv -> ACIContent
forall (d :: MsgDirection).
MsgDirectionI d =>
SMsgDirection d -> CIContent d -> ACIContent
ACIContent SMsgDirection 'MDRcv
SMDRcv (CIContent 'MDRcv -> ACIContent) -> CIContent 'MDRcv -> ACIContent
forall a b. (a -> b) -> a -> b
$ MsgDecryptError -> Word32 -> CIContent 'MDRcv
CIRcvDecryptionError MsgDecryptError
err Word32
n
  JCIRcvGroupInvitation {CIGroupInvitation
groupInvitation :: JSONCIContent -> CIGroupInvitation
groupInvitation :: CIGroupInvitation
groupInvitation, GroupMemberRole
memberRole :: JSONCIContent -> GroupMemberRole
memberRole :: GroupMemberRole
memberRole} -> SMsgDirection 'MDRcv -> CIContent 'MDRcv -> ACIContent
forall (d :: MsgDirection).
MsgDirectionI d =>
SMsgDirection d -> CIContent d -> ACIContent
ACIContent SMsgDirection 'MDRcv
SMDRcv (CIContent 'MDRcv -> ACIContent) -> CIContent 'MDRcv -> ACIContent
forall a b. (a -> b) -> a -> b
$ CIGroupInvitation -> GroupMemberRole -> CIContent 'MDRcv
CIRcvGroupInvitation CIGroupInvitation
groupInvitation GroupMemberRole
memberRole
  JCISndGroupInvitation {CIGroupInvitation
groupInvitation :: JSONCIContent -> CIGroupInvitation
groupInvitation :: CIGroupInvitation
groupInvitation, GroupMemberRole
memberRole :: JSONCIContent -> GroupMemberRole
memberRole :: GroupMemberRole
memberRole} -> SMsgDirection 'MDSnd -> CIContent 'MDSnd -> ACIContent
forall (d :: MsgDirection).
MsgDirectionI d =>
SMsgDirection d -> CIContent d -> ACIContent
ACIContent SMsgDirection 'MDSnd
SMDSnd (CIContent 'MDSnd -> ACIContent) -> CIContent 'MDSnd -> ACIContent
forall a b. (a -> b) -> a -> b
$ CIGroupInvitation -> GroupMemberRole -> CIContent 'MDSnd
CISndGroupInvitation CIGroupInvitation
groupInvitation GroupMemberRole
memberRole
  JCIRcvDirectEvent {RcvDirectEvent
rcvDirectEvent :: JSONCIContent -> RcvDirectEvent
rcvDirectEvent :: RcvDirectEvent
rcvDirectEvent} -> SMsgDirection 'MDRcv -> CIContent 'MDRcv -> ACIContent
forall (d :: MsgDirection).
MsgDirectionI d =>
SMsgDirection d -> CIContent d -> ACIContent
ACIContent SMsgDirection 'MDRcv
SMDRcv (CIContent 'MDRcv -> ACIContent) -> CIContent 'MDRcv -> ACIContent
forall a b. (a -> b) -> a -> b
$ RcvDirectEvent -> CIContent 'MDRcv
CIRcvDirectEvent RcvDirectEvent
rcvDirectEvent
  JCIRcvGroupEvent {RcvGroupEvent
rcvGroupEvent :: JSONCIContent -> RcvGroupEvent
rcvGroupEvent :: RcvGroupEvent
rcvGroupEvent} -> SMsgDirection 'MDRcv -> CIContent 'MDRcv -> ACIContent
forall (d :: MsgDirection).
MsgDirectionI d =>
SMsgDirection d -> CIContent d -> ACIContent
ACIContent SMsgDirection 'MDRcv
SMDRcv (CIContent 'MDRcv -> ACIContent) -> CIContent 'MDRcv -> ACIContent
forall a b. (a -> b) -> a -> b
$ RcvGroupEvent -> CIContent 'MDRcv
CIRcvGroupEvent RcvGroupEvent
rcvGroupEvent
  JCISndGroupEvent {SndGroupEvent
sndGroupEvent :: JSONCIContent -> SndGroupEvent
sndGroupEvent :: SndGroupEvent
sndGroupEvent} -> SMsgDirection 'MDSnd -> CIContent 'MDSnd -> ACIContent
forall (d :: MsgDirection).
MsgDirectionI d =>
SMsgDirection d -> CIContent d -> ACIContent
ACIContent SMsgDirection 'MDSnd
SMDSnd (CIContent 'MDSnd -> ACIContent) -> CIContent 'MDSnd -> ACIContent
forall a b. (a -> b) -> a -> b
$ SndGroupEvent -> CIContent 'MDSnd
CISndGroupEvent SndGroupEvent
sndGroupEvent
  JCIRcvConnEvent {RcvConnEvent
rcvConnEvent :: JSONCIContent -> RcvConnEvent
rcvConnEvent :: RcvConnEvent
rcvConnEvent} -> SMsgDirection 'MDRcv -> CIContent 'MDRcv -> ACIContent
forall (d :: MsgDirection).
MsgDirectionI d =>
SMsgDirection d -> CIContent d -> ACIContent
ACIContent SMsgDirection 'MDRcv
SMDRcv (CIContent 'MDRcv -> ACIContent) -> CIContent 'MDRcv -> ACIContent
forall a b. (a -> b) -> a -> b
$ RcvConnEvent -> CIContent 'MDRcv
CIRcvConnEvent RcvConnEvent
rcvConnEvent
  JCISndConnEvent {SndConnEvent
sndConnEvent :: JSONCIContent -> SndConnEvent
sndConnEvent :: SndConnEvent
sndConnEvent} -> SMsgDirection 'MDSnd -> CIContent 'MDSnd -> ACIContent
forall (d :: MsgDirection).
MsgDirectionI d =>
SMsgDirection d -> CIContent d -> ACIContent
ACIContent SMsgDirection 'MDSnd
SMDSnd (CIContent 'MDSnd -> ACIContent) -> CIContent 'MDSnd -> ACIContent
forall a b. (a -> b) -> a -> b
$ SndConnEvent -> CIContent 'MDSnd
CISndConnEvent SndConnEvent
sndConnEvent
  JCIRcvChatFeature {ChatFeature
feature :: JSONCIContent -> ChatFeature
feature :: ChatFeature
feature, PrefEnabled
enabled :: JSONCIContent -> PrefEnabled
enabled :: PrefEnabled
enabled, Maybe Int
param :: JSONCIContent -> Maybe Int
param :: Maybe Int
param} -> SMsgDirection 'MDRcv -> CIContent 'MDRcv -> ACIContent
forall (d :: MsgDirection).
MsgDirectionI d =>
SMsgDirection d -> CIContent d -> ACIContent
ACIContent SMsgDirection 'MDRcv
SMDRcv (CIContent 'MDRcv -> ACIContent) -> CIContent 'MDRcv -> ACIContent
forall a b. (a -> b) -> a -> b
$ ChatFeature -> PrefEnabled -> Maybe Int -> CIContent 'MDRcv
CIRcvChatFeature ChatFeature
feature PrefEnabled
enabled Maybe Int
param
  JCISndChatFeature {ChatFeature
feature :: JSONCIContent -> ChatFeature
feature :: ChatFeature
feature, PrefEnabled
enabled :: JSONCIContent -> PrefEnabled
enabled :: PrefEnabled
enabled, Maybe Int
param :: JSONCIContent -> Maybe Int
param :: Maybe Int
param} -> SMsgDirection 'MDSnd -> CIContent 'MDSnd -> ACIContent
forall (d :: MsgDirection).
MsgDirectionI d =>
SMsgDirection d -> CIContent d -> ACIContent
ACIContent SMsgDirection 'MDSnd
SMDSnd (CIContent 'MDSnd -> ACIContent) -> CIContent 'MDSnd -> ACIContent
forall a b. (a -> b) -> a -> b
$ ChatFeature -> PrefEnabled -> Maybe Int -> CIContent 'MDSnd
CISndChatFeature ChatFeature
feature PrefEnabled
enabled Maybe Int
param
  JCIRcvChatPreference {ChatFeature
feature :: JSONCIContent -> ChatFeature
feature :: ChatFeature
feature, FeatureAllowed
allowed :: JSONCIContent -> FeatureAllowed
allowed :: FeatureAllowed
allowed, Maybe Int
param :: JSONCIContent -> Maybe Int
param :: Maybe Int
param} -> SMsgDirection 'MDRcv -> CIContent 'MDRcv -> ACIContent
forall (d :: MsgDirection).
MsgDirectionI d =>
SMsgDirection d -> CIContent d -> ACIContent
ACIContent SMsgDirection 'MDRcv
SMDRcv (CIContent 'MDRcv -> ACIContent) -> CIContent 'MDRcv -> ACIContent
forall a b. (a -> b) -> a -> b
$ ChatFeature -> FeatureAllowed -> Maybe Int -> CIContent 'MDRcv
CIRcvChatPreference ChatFeature
feature FeatureAllowed
allowed Maybe Int
param
  JCISndChatPreference {ChatFeature
feature :: JSONCIContent -> ChatFeature
feature :: ChatFeature
feature, FeatureAllowed
allowed :: JSONCIContent -> FeatureAllowed
allowed :: FeatureAllowed
allowed, Maybe Int
param :: JSONCIContent -> Maybe Int
param :: Maybe Int
param} -> SMsgDirection 'MDSnd -> CIContent 'MDSnd -> ACIContent
forall (d :: MsgDirection).
MsgDirectionI d =>
SMsgDirection d -> CIContent d -> ACIContent
ACIContent SMsgDirection 'MDSnd
SMDSnd (CIContent 'MDSnd -> ACIContent) -> CIContent 'MDSnd -> ACIContent
forall a b. (a -> b) -> a -> b
$ ChatFeature -> FeatureAllowed -> Maybe Int -> CIContent 'MDSnd
CISndChatPreference ChatFeature
feature FeatureAllowed
allowed Maybe Int
param
  JCIRcvGroupFeature {GroupFeature
groupFeature :: JSONCIContent -> GroupFeature
groupFeature :: GroupFeature
groupFeature, GroupPreference
preference :: JSONCIContent -> GroupPreference
preference :: GroupPreference
preference, Maybe Int
param :: JSONCIContent -> Maybe Int
param :: Maybe Int
param, Maybe GroupMemberRole
memberRole_ :: JSONCIContent -> Maybe GroupMemberRole
memberRole_ :: Maybe GroupMemberRole
memberRole_} -> SMsgDirection 'MDRcv -> CIContent 'MDRcv -> ACIContent
forall (d :: MsgDirection).
MsgDirectionI d =>
SMsgDirection d -> CIContent d -> ACIContent
ACIContent SMsgDirection 'MDRcv
SMDRcv (CIContent 'MDRcv -> ACIContent) -> CIContent 'MDRcv -> ACIContent
forall a b. (a -> b) -> a -> b
$ GroupFeature
-> GroupPreference
-> Maybe Int
-> Maybe GroupMemberRole
-> CIContent 'MDRcv
CIRcvGroupFeature GroupFeature
groupFeature GroupPreference
preference Maybe Int
param Maybe GroupMemberRole
memberRole_
  JCISndGroupFeature {GroupFeature
groupFeature :: JSONCIContent -> GroupFeature
groupFeature :: GroupFeature
groupFeature, GroupPreference
preference :: JSONCIContent -> GroupPreference
preference :: GroupPreference
preference, Maybe Int
param :: JSONCIContent -> Maybe Int
param :: Maybe Int
param, Maybe GroupMemberRole
memberRole_ :: JSONCIContent -> Maybe GroupMemberRole
memberRole_ :: Maybe GroupMemberRole
memberRole_} -> SMsgDirection 'MDSnd -> CIContent 'MDSnd -> ACIContent
forall (d :: MsgDirection).
MsgDirectionI d =>
SMsgDirection d -> CIContent d -> ACIContent
ACIContent SMsgDirection 'MDSnd
SMDSnd (CIContent 'MDSnd -> ACIContent) -> CIContent 'MDSnd -> ACIContent
forall a b. (a -> b) -> a -> b
$ GroupFeature
-> GroupPreference
-> Maybe Int
-> Maybe GroupMemberRole
-> CIContent 'MDSnd
CISndGroupFeature GroupFeature
groupFeature GroupPreference
preference Maybe Int
param Maybe GroupMemberRole
memberRole_
  JCIRcvChatFeatureRejected {ChatFeature
feature :: JSONCIContent -> ChatFeature
feature :: ChatFeature
feature} -> SMsgDirection 'MDRcv -> CIContent 'MDRcv -> ACIContent
forall (d :: MsgDirection).
MsgDirectionI d =>
SMsgDirection d -> CIContent d -> ACIContent
ACIContent SMsgDirection 'MDRcv
SMDRcv (CIContent 'MDRcv -> ACIContent) -> CIContent 'MDRcv -> ACIContent
forall a b. (a -> b) -> a -> b
$ ChatFeature -> CIContent 'MDRcv
CIRcvChatFeatureRejected ChatFeature
feature
  JCIRcvGroupFeatureRejected {GroupFeature
groupFeature :: JSONCIContent -> GroupFeature
groupFeature :: GroupFeature
groupFeature} -> SMsgDirection 'MDRcv -> CIContent 'MDRcv -> ACIContent
forall (d :: MsgDirection).
MsgDirectionI d =>
SMsgDirection d -> CIContent d -> ACIContent
ACIContent SMsgDirection 'MDRcv
SMDRcv (CIContent 'MDRcv -> ACIContent) -> CIContent 'MDRcv -> ACIContent
forall a b. (a -> b) -> a -> b
$ GroupFeature -> CIContent 'MDRcv
CIRcvGroupFeatureRejected GroupFeature
groupFeature
  JSONCIContent
JCISndModerated -> SMsgDirection 'MDSnd -> CIContent 'MDSnd -> ACIContent
forall (d :: MsgDirection).
MsgDirectionI d =>
SMsgDirection d -> CIContent d -> ACIContent
ACIContent SMsgDirection 'MDSnd
SMDSnd CIContent 'MDSnd
CISndModerated
  JSONCIContent
JCIRcvModerated -> SMsgDirection 'MDRcv -> CIContent 'MDRcv -> ACIContent
forall (d :: MsgDirection).
MsgDirectionI d =>
SMsgDirection d -> CIContent d -> ACIContent
ACIContent SMsgDirection 'MDRcv
SMDRcv CIContent 'MDRcv
CIRcvModerated
  JSONCIContent
JCIRcvBlocked -> SMsgDirection 'MDRcv -> CIContent 'MDRcv -> ACIContent
forall (d :: MsgDirection).
MsgDirectionI d =>
SMsgDirection d -> CIContent d -> ACIContent
ACIContent SMsgDirection 'MDRcv
SMDRcv CIContent 'MDRcv
CIRcvBlocked
  JCISndDirectE2EEInfo {E2EInfo
e2eeInfo :: JSONCIContent -> E2EInfo
e2eeInfo :: E2EInfo
e2eeInfo} -> SMsgDirection 'MDSnd -> CIContent 'MDSnd -> ACIContent
forall (d :: MsgDirection).
MsgDirectionI d =>
SMsgDirection d -> CIContent d -> ACIContent
ACIContent SMsgDirection 'MDSnd
SMDSnd (CIContent 'MDSnd -> ACIContent) -> CIContent 'MDSnd -> ACIContent
forall a b. (a -> b) -> a -> b
$ E2EInfo -> CIContent 'MDSnd
CISndDirectE2EEInfo E2EInfo
e2eeInfo
  JCIRcvDirectE2EEInfo {E2EInfo
e2eeInfo :: JSONCIContent -> E2EInfo
e2eeInfo :: E2EInfo
e2eeInfo} -> SMsgDirection 'MDRcv -> CIContent 'MDRcv -> ACIContent
forall (d :: MsgDirection).
MsgDirectionI d =>
SMsgDirection d -> CIContent d -> ACIContent
ACIContent SMsgDirection 'MDRcv
SMDRcv (CIContent 'MDRcv -> ACIContent) -> CIContent 'MDRcv -> ACIContent
forall a b. (a -> b) -> a -> b
$ E2EInfo -> CIContent 'MDRcv
CIRcvDirectE2EEInfo E2EInfo
e2eeInfo
  JCISndGroupE2EEInfo {E2EInfo
e2eeInfo :: JSONCIContent -> E2EInfo
e2eeInfo :: E2EInfo
e2eeInfo} -> SMsgDirection 'MDSnd -> CIContent 'MDSnd -> ACIContent
forall (d :: MsgDirection).
MsgDirectionI d =>
SMsgDirection d -> CIContent d -> ACIContent
ACIContent SMsgDirection 'MDSnd
SMDSnd (CIContent 'MDSnd -> ACIContent) -> CIContent 'MDSnd -> ACIContent
forall a b. (a -> b) -> a -> b
$ E2EInfo -> CIContent 'MDSnd
CISndGroupE2EEInfo E2EInfo
e2eeInfo
  JCIRcvGroupE2EEInfo {E2EInfo
e2eeInfo :: JSONCIContent -> E2EInfo
e2eeInfo :: E2EInfo
e2eeInfo} -> SMsgDirection 'MDRcv -> CIContent 'MDRcv -> ACIContent
forall (d :: MsgDirection).
MsgDirectionI d =>
SMsgDirection d -> CIContent d -> ACIContent
ACIContent SMsgDirection 'MDRcv
SMDRcv (CIContent 'MDRcv -> ACIContent) -> CIContent 'MDRcv -> ACIContent
forall a b. (a -> b) -> a -> b
$ E2EInfo -> CIContent 'MDRcv
CIRcvGroupE2EEInfo E2EInfo
e2eeInfo
  JSONCIContent
JCIChatBanner -> SMsgDirection 'MDSnd -> CIContent 'MDSnd -> ACIContent
forall (d :: MsgDirection).
MsgDirectionI d =>
SMsgDirection d -> CIContent d -> ACIContent
ACIContent SMsgDirection 'MDSnd
SMDSnd CIContent 'MDSnd
CIChatBanner
  JCIInvalidJSON MsgDirection
dir Text
json -> case MsgDirection -> AMsgDirection
fromMsgDirection MsgDirection
dir of
    AMsgDirection SMsgDirection d
d -> SMsgDirection d -> CIContent d -> ACIContent
forall (d :: MsgDirection).
MsgDirectionI d =>
SMsgDirection d -> CIContent d -> ACIContent
ACIContent SMsgDirection d
d (CIContent d -> ACIContent) -> CIContent d -> ACIContent
forall a b. (a -> b) -> a -> b
$ Text -> CIContent d
forall (d :: MsgDirection). Text -> CIContent d
CIInvalidJSON Text
json

-- platform independent
data DBJSONCIContent
  = DBJCISndMsgContent {DBJSONCIContent -> MsgContent
msgContent :: MsgContent}
  | DBJCIRcvMsgContent {msgContent :: MsgContent}
  | DBJCISndDeleted {DBJSONCIContent -> CIDeleteMode
deleteMode :: CIDeleteMode}
  | DBJCIRcvDeleted {deleteMode :: CIDeleteMode}
  | DBJCISndCall {DBJSONCIContent -> CICallStatus
status :: CICallStatus, DBJSONCIContent -> Int
duration :: Int}
  | DBJCIRcvCall {status :: CICallStatus, duration :: Int}
  | DBJCIRcvIntegrityError {DBJSONCIContent -> DBMsgErrorType
msgError :: DBMsgErrorType}
  | DBJCIRcvDecryptionError {DBJSONCIContent -> MsgDecryptError
msgDecryptError :: MsgDecryptError, DBJSONCIContent -> Word32
msgCount :: Word32}
  | DBJCIRcvGroupInvitation {DBJSONCIContent -> CIGroupInvitation
groupInvitation :: CIGroupInvitation, DBJSONCIContent -> GroupMemberRole
memberRole :: GroupMemberRole}
  | DBJCISndGroupInvitation {groupInvitation :: CIGroupInvitation, memberRole :: GroupMemberRole}
  | DBJCIRcvDirectEvent {DBJSONCIContent -> DBRcvDirectEvent
rcvDirectEvent :: DBRcvDirectEvent}
  | DBJCIRcvGroupEvent {DBJSONCIContent -> DBRcvGroupEvent
rcvGroupEvent :: DBRcvGroupEvent}
  | DBJCISndGroupEvent {DBJSONCIContent -> DBSndGroupEvent
sndGroupEvent :: DBSndGroupEvent}
  | DBJCIRcvConnEvent {DBJSONCIContent -> DBRcvConnEvent
rcvConnEvent :: DBRcvConnEvent}
  | DBJCISndConnEvent {DBJSONCIContent -> DBSndConnEvent
sndConnEvent :: DBSndConnEvent}
  | DBJCIRcvChatFeature {DBJSONCIContent -> ChatFeature
feature :: ChatFeature, DBJSONCIContent -> PrefEnabled
enabled :: PrefEnabled, DBJSONCIContent -> Maybe Int
param :: Maybe Int}
  | DBJCISndChatFeature {feature :: ChatFeature, enabled :: PrefEnabled, param :: Maybe Int}
  | DBJCIRcvChatPreference {feature :: ChatFeature, DBJSONCIContent -> FeatureAllowed
allowed :: FeatureAllowed, param :: Maybe Int}
  | DBJCISndChatPreference {feature :: ChatFeature, allowed :: FeatureAllowed, param :: Maybe Int}
  | DBJCIRcvGroupFeature {DBJSONCIContent -> GroupFeature
groupFeature :: GroupFeature, DBJSONCIContent -> GroupPreference
preference :: GroupPreference, param :: Maybe Int, DBJSONCIContent -> Maybe GroupMemberRole
memberRole_ :: Maybe GroupMemberRole}
  | DBJCISndGroupFeature {groupFeature :: GroupFeature, preference :: GroupPreference, param :: Maybe Int, memberRole_ :: Maybe GroupMemberRole}
  | DBJCIRcvChatFeatureRejected {feature :: ChatFeature}
  | DBJCIRcvGroupFeatureRejected {groupFeature :: GroupFeature}
  | DBJCISndModerated
  | DBJCIRcvModerated
  | DBJCIRcvBlocked
  | DBJCISndDirectE2EEInfo {DBJSONCIContent -> E2EInfo
e2eeInfo :: E2EInfo}
  | DBJCIRcvDirectE2EEInfo {e2eeInfo :: E2EInfo}
  | DBJCISndGroupE2EEInfo {e2eeInfo :: E2EInfo}
  | DBJCIRcvGroupE2EEInfo {e2eeInfo :: E2EInfo}
  | DBJCIChatBanner
  | DBJCIInvalidJSON {DBJSONCIContent -> MsgDirection
direction :: MsgDirection, DBJSONCIContent -> Text
json :: Text}

dbJsonCIContent :: forall d. MsgDirectionI d => CIContent d -> DBJSONCIContent
dbJsonCIContent :: forall (d :: MsgDirection).
MsgDirectionI d =>
CIContent d -> DBJSONCIContent
dbJsonCIContent = \case
  CISndMsgContent MsgContent
mc -> MsgContent -> DBJSONCIContent
DBJCISndMsgContent MsgContent
mc
  CIRcvMsgContent MsgContent
mc -> MsgContent -> DBJSONCIContent
DBJCIRcvMsgContent MsgContent
mc
  CISndDeleted CIDeleteMode
cidm -> CIDeleteMode -> DBJSONCIContent
DBJCISndDeleted CIDeleteMode
cidm
  CIRcvDeleted CIDeleteMode
cidm -> CIDeleteMode -> DBJSONCIContent
DBJCIRcvDeleted CIDeleteMode
cidm
  CISndCall CICallStatus
status Int
duration -> DBJCISndCall {CICallStatus
status :: CICallStatus
status :: CICallStatus
status, Int
duration :: Int
duration :: Int
duration}
  CIRcvCall CICallStatus
status Int
duration -> DBJCIRcvCall {CICallStatus
status :: CICallStatus
status :: CICallStatus
status, Int
duration :: Int
duration :: Int
duration}
  CIRcvIntegrityError MsgErrorType
err -> DBMsgErrorType -> DBJSONCIContent
DBJCIRcvIntegrityError (DBMsgErrorType -> DBJSONCIContent)
-> DBMsgErrorType -> DBJSONCIContent
forall a b. (a -> b) -> a -> b
$ MsgErrorType -> DBMsgErrorType
DBME MsgErrorType
err
  CIRcvDecryptionError MsgDecryptError
err Word32
n -> MsgDecryptError -> Word32 -> DBJSONCIContent
DBJCIRcvDecryptionError MsgDecryptError
err Word32
n
  CIRcvGroupInvitation CIGroupInvitation
groupInvitation GroupMemberRole
memberRole -> DBJCIRcvGroupInvitation {CIGroupInvitation
groupInvitation :: CIGroupInvitation
groupInvitation :: CIGroupInvitation
groupInvitation, GroupMemberRole
memberRole :: GroupMemberRole
memberRole :: GroupMemberRole
memberRole}
  CISndGroupInvitation CIGroupInvitation
groupInvitation GroupMemberRole
memberRole -> DBJCISndGroupInvitation {CIGroupInvitation
groupInvitation :: CIGroupInvitation
groupInvitation :: CIGroupInvitation
groupInvitation, GroupMemberRole
memberRole :: GroupMemberRole
memberRole :: GroupMemberRole
memberRole}
  CIRcvDirectEvent RcvDirectEvent
rde -> DBRcvDirectEvent -> DBJSONCIContent
DBJCIRcvDirectEvent (DBRcvDirectEvent -> DBJSONCIContent)
-> DBRcvDirectEvent -> DBJSONCIContent
forall a b. (a -> b) -> a -> b
$ RcvDirectEvent -> DBRcvDirectEvent
RDE RcvDirectEvent
rde
  CIRcvGroupEvent RcvGroupEvent
rge -> DBRcvGroupEvent -> DBJSONCIContent
DBJCIRcvGroupEvent (DBRcvGroupEvent -> DBJSONCIContent)
-> DBRcvGroupEvent -> DBJSONCIContent
forall a b. (a -> b) -> a -> b
$ RcvGroupEvent -> DBRcvGroupEvent
RGE RcvGroupEvent
rge
  CISndGroupEvent SndGroupEvent
sge -> DBSndGroupEvent -> DBJSONCIContent
DBJCISndGroupEvent (DBSndGroupEvent -> DBJSONCIContent)
-> DBSndGroupEvent -> DBJSONCIContent
forall a b. (a -> b) -> a -> b
$ SndGroupEvent -> DBSndGroupEvent
SGE SndGroupEvent
sge
  CIRcvConnEvent RcvConnEvent
rce -> DBRcvConnEvent -> DBJSONCIContent
DBJCIRcvConnEvent (DBRcvConnEvent -> DBJSONCIContent)
-> DBRcvConnEvent -> DBJSONCIContent
forall a b. (a -> b) -> a -> b
$ RcvConnEvent -> DBRcvConnEvent
RCE RcvConnEvent
rce
  CISndConnEvent SndConnEvent
sce -> DBSndConnEvent -> DBJSONCIContent
DBJCISndConnEvent (DBSndConnEvent -> DBJSONCIContent)
-> DBSndConnEvent -> DBJSONCIContent
forall a b. (a -> b) -> a -> b
$ SndConnEvent -> DBSndConnEvent
SCE SndConnEvent
sce
  CIRcvChatFeature ChatFeature
feature PrefEnabled
enabled Maybe Int
param -> DBJCIRcvChatFeature {ChatFeature
feature :: ChatFeature
feature :: ChatFeature
feature, PrefEnabled
enabled :: PrefEnabled
enabled :: PrefEnabled
enabled, Maybe Int
param :: Maybe Int
param :: Maybe Int
param}
  CISndChatFeature ChatFeature
feature PrefEnabled
enabled Maybe Int
param -> DBJCISndChatFeature {ChatFeature
feature :: ChatFeature
feature :: ChatFeature
feature, PrefEnabled
enabled :: PrefEnabled
enabled :: PrefEnabled
enabled, Maybe Int
param :: Maybe Int
param :: Maybe Int
param}
  CIRcvChatPreference ChatFeature
feature FeatureAllowed
allowed Maybe Int
param -> DBJCIRcvChatPreference {ChatFeature
feature :: ChatFeature
feature :: ChatFeature
feature, FeatureAllowed
allowed :: FeatureAllowed
allowed :: FeatureAllowed
allowed, Maybe Int
param :: Maybe Int
param :: Maybe Int
param}
  CISndChatPreference ChatFeature
feature FeatureAllowed
allowed Maybe Int
param -> DBJCISndChatPreference {ChatFeature
feature :: ChatFeature
feature :: ChatFeature
feature, FeatureAllowed
allowed :: FeatureAllowed
allowed :: FeatureAllowed
allowed, Maybe Int
param :: Maybe Int
param :: Maybe Int
param}
  CIRcvGroupFeature GroupFeature
groupFeature GroupPreference
preference Maybe Int
param Maybe GroupMemberRole
memberRole_ -> DBJCIRcvGroupFeature {GroupFeature
groupFeature :: GroupFeature
groupFeature :: GroupFeature
groupFeature, GroupPreference
preference :: GroupPreference
preference :: GroupPreference
preference, Maybe Int
param :: Maybe Int
param :: Maybe Int
param, Maybe GroupMemberRole
memberRole_ :: Maybe GroupMemberRole
memberRole_ :: Maybe GroupMemberRole
memberRole_}
  CISndGroupFeature GroupFeature
groupFeature GroupPreference
preference Maybe Int
param Maybe GroupMemberRole
memberRole_ -> DBJCISndGroupFeature {GroupFeature
groupFeature :: GroupFeature
groupFeature :: GroupFeature
groupFeature, GroupPreference
preference :: GroupPreference
preference :: GroupPreference
preference, Maybe Int
param :: Maybe Int
param :: Maybe Int
param, Maybe GroupMemberRole
memberRole_ :: Maybe GroupMemberRole
memberRole_ :: Maybe GroupMemberRole
memberRole_}
  CIRcvChatFeatureRejected ChatFeature
feature -> DBJCIRcvChatFeatureRejected {ChatFeature
feature :: ChatFeature
feature :: ChatFeature
feature}
  CIRcvGroupFeatureRejected GroupFeature
groupFeature -> DBJCIRcvGroupFeatureRejected {GroupFeature
groupFeature :: GroupFeature
groupFeature :: GroupFeature
groupFeature}
  CIContent d
CISndModerated -> DBJSONCIContent
DBJCISndModerated
  CIContent d
CIRcvModerated -> DBJSONCIContent
DBJCIRcvModerated
  CIContent d
CIRcvBlocked -> DBJSONCIContent
DBJCIRcvBlocked
  CISndDirectE2EEInfo E2EInfo
e2eeInfo -> E2EInfo -> DBJSONCIContent
DBJCISndDirectE2EEInfo E2EInfo
e2eeInfo
  CIRcvDirectE2EEInfo E2EInfo
e2eeInfo -> E2EInfo -> DBJSONCIContent
DBJCIRcvDirectE2EEInfo E2EInfo
e2eeInfo
  CISndGroupE2EEInfo E2EInfo
e2eeInfo -> E2EInfo -> DBJSONCIContent
DBJCISndGroupE2EEInfo E2EInfo
e2eeInfo
  CIRcvGroupE2EEInfo E2EInfo
e2eeInfo -> E2EInfo -> DBJSONCIContent
DBJCIRcvGroupE2EEInfo E2EInfo
e2eeInfo
  CIContent d
CIChatBanner -> DBJSONCIContent
DBJCIChatBanner
  CIInvalidJSON Text
json -> MsgDirection -> Text -> DBJSONCIContent
DBJCIInvalidJSON (SMsgDirection d -> MsgDirection
forall (d :: MsgDirection). SMsgDirection d -> MsgDirection
toMsgDirection (SMsgDirection d -> MsgDirection)
-> SMsgDirection d -> MsgDirection
forall a b. (a -> b) -> a -> b
$ forall (d :: MsgDirection). MsgDirectionI d => SMsgDirection d
msgDirection @d) Text
json

aciContentDBJSON :: DBJSONCIContent -> ACIContent
aciContentDBJSON :: DBJSONCIContent -> ACIContent
aciContentDBJSON = \case
  DBJCISndMsgContent MsgContent
mc -> SMsgDirection 'MDSnd -> CIContent 'MDSnd -> ACIContent
forall (d :: MsgDirection).
MsgDirectionI d =>
SMsgDirection d -> CIContent d -> ACIContent
ACIContent SMsgDirection 'MDSnd
SMDSnd (CIContent 'MDSnd -> ACIContent) -> CIContent 'MDSnd -> ACIContent
forall a b. (a -> b) -> a -> b
$ MsgContent -> CIContent 'MDSnd
CISndMsgContent MsgContent
mc
  DBJCIRcvMsgContent MsgContent
mc -> SMsgDirection 'MDRcv -> CIContent 'MDRcv -> ACIContent
forall (d :: MsgDirection).
MsgDirectionI d =>
SMsgDirection d -> CIContent d -> ACIContent
ACIContent SMsgDirection 'MDRcv
SMDRcv (CIContent 'MDRcv -> ACIContent) -> CIContent 'MDRcv -> ACIContent
forall a b. (a -> b) -> a -> b
$ MsgContent -> CIContent 'MDRcv
CIRcvMsgContent MsgContent
mc
  DBJCISndDeleted CIDeleteMode
cidm -> SMsgDirection 'MDSnd -> CIContent 'MDSnd -> ACIContent
forall (d :: MsgDirection).
MsgDirectionI d =>
SMsgDirection d -> CIContent d -> ACIContent
ACIContent SMsgDirection 'MDSnd
SMDSnd (CIContent 'MDSnd -> ACIContent) -> CIContent 'MDSnd -> ACIContent
forall a b. (a -> b) -> a -> b
$ CIDeleteMode -> CIContent 'MDSnd
CISndDeleted CIDeleteMode
cidm
  DBJCIRcvDeleted CIDeleteMode
cidm -> SMsgDirection 'MDRcv -> CIContent 'MDRcv -> ACIContent
forall (d :: MsgDirection).
MsgDirectionI d =>
SMsgDirection d -> CIContent d -> ACIContent
ACIContent SMsgDirection 'MDRcv
SMDRcv (CIContent 'MDRcv -> ACIContent) -> CIContent 'MDRcv -> ACIContent
forall a b. (a -> b) -> a -> b
$ CIDeleteMode -> CIContent 'MDRcv
CIRcvDeleted CIDeleteMode
cidm
  DBJCISndCall {CICallStatus
status :: DBJSONCIContent -> CICallStatus
status :: CICallStatus
status, Int
duration :: DBJSONCIContent -> Int
duration :: Int
duration} -> SMsgDirection 'MDSnd -> CIContent 'MDSnd -> ACIContent
forall (d :: MsgDirection).
MsgDirectionI d =>
SMsgDirection d -> CIContent d -> ACIContent
ACIContent SMsgDirection 'MDSnd
SMDSnd (CIContent 'MDSnd -> ACIContent) -> CIContent 'MDSnd -> ACIContent
forall a b. (a -> b) -> a -> b
$ CICallStatus -> Int -> CIContent 'MDSnd
CISndCall CICallStatus
status Int
duration
  DBJCIRcvCall {CICallStatus
status :: DBJSONCIContent -> CICallStatus
status :: CICallStatus
status, Int
duration :: DBJSONCIContent -> Int
duration :: Int
duration} -> SMsgDirection 'MDRcv -> CIContent 'MDRcv -> ACIContent
forall (d :: MsgDirection).
MsgDirectionI d =>
SMsgDirection d -> CIContent d -> ACIContent
ACIContent SMsgDirection 'MDRcv
SMDRcv (CIContent 'MDRcv -> ACIContent) -> CIContent 'MDRcv -> ACIContent
forall a b. (a -> b) -> a -> b
$ CICallStatus -> Int -> CIContent 'MDRcv
CIRcvCall CICallStatus
status Int
duration
  DBJCIRcvIntegrityError (DBME MsgErrorType
err) -> SMsgDirection 'MDRcv -> CIContent 'MDRcv -> ACIContent
forall (d :: MsgDirection).
MsgDirectionI d =>
SMsgDirection d -> CIContent d -> ACIContent
ACIContent SMsgDirection 'MDRcv
SMDRcv (CIContent 'MDRcv -> ACIContent) -> CIContent 'MDRcv -> ACIContent
forall a b. (a -> b) -> a -> b
$ MsgErrorType -> CIContent 'MDRcv
CIRcvIntegrityError MsgErrorType
err
  DBJCIRcvDecryptionError MsgDecryptError
err Word32
n -> SMsgDirection 'MDRcv -> CIContent 'MDRcv -> ACIContent
forall (d :: MsgDirection).
MsgDirectionI d =>
SMsgDirection d -> CIContent d -> ACIContent
ACIContent SMsgDirection 'MDRcv
SMDRcv (CIContent 'MDRcv -> ACIContent) -> CIContent 'MDRcv -> ACIContent
forall a b. (a -> b) -> a -> b
$ MsgDecryptError -> Word32 -> CIContent 'MDRcv
CIRcvDecryptionError MsgDecryptError
err Word32
n
  DBJCIRcvGroupInvitation {CIGroupInvitation
groupInvitation :: DBJSONCIContent -> CIGroupInvitation
groupInvitation :: CIGroupInvitation
groupInvitation, GroupMemberRole
memberRole :: DBJSONCIContent -> GroupMemberRole
memberRole :: GroupMemberRole
memberRole} -> SMsgDirection 'MDRcv -> CIContent 'MDRcv -> ACIContent
forall (d :: MsgDirection).
MsgDirectionI d =>
SMsgDirection d -> CIContent d -> ACIContent
ACIContent SMsgDirection 'MDRcv
SMDRcv (CIContent 'MDRcv -> ACIContent) -> CIContent 'MDRcv -> ACIContent
forall a b. (a -> b) -> a -> b
$ CIGroupInvitation -> GroupMemberRole -> CIContent 'MDRcv
CIRcvGroupInvitation CIGroupInvitation
groupInvitation GroupMemberRole
memberRole
  DBJCISndGroupInvitation {CIGroupInvitation
groupInvitation :: DBJSONCIContent -> CIGroupInvitation
groupInvitation :: CIGroupInvitation
groupInvitation, GroupMemberRole
memberRole :: DBJSONCIContent -> GroupMemberRole
memberRole :: GroupMemberRole
memberRole} -> SMsgDirection 'MDSnd -> CIContent 'MDSnd -> ACIContent
forall (d :: MsgDirection).
MsgDirectionI d =>
SMsgDirection d -> CIContent d -> ACIContent
ACIContent SMsgDirection 'MDSnd
SMDSnd (CIContent 'MDSnd -> ACIContent) -> CIContent 'MDSnd -> ACIContent
forall a b. (a -> b) -> a -> b
$ CIGroupInvitation -> GroupMemberRole -> CIContent 'MDSnd
CISndGroupInvitation CIGroupInvitation
groupInvitation GroupMemberRole
memberRole
  DBJCIRcvDirectEvent (RDE RcvDirectEvent
rde) -> SMsgDirection 'MDRcv -> CIContent 'MDRcv -> ACIContent
forall (d :: MsgDirection).
MsgDirectionI d =>
SMsgDirection d -> CIContent d -> ACIContent
ACIContent SMsgDirection 'MDRcv
SMDRcv (CIContent 'MDRcv -> ACIContent) -> CIContent 'MDRcv -> ACIContent
forall a b. (a -> b) -> a -> b
$ RcvDirectEvent -> CIContent 'MDRcv
CIRcvDirectEvent RcvDirectEvent
rde
  DBJCIRcvGroupEvent (RGE RcvGroupEvent
rge) -> SMsgDirection 'MDRcv -> CIContent 'MDRcv -> ACIContent
forall (d :: MsgDirection).
MsgDirectionI d =>
SMsgDirection d -> CIContent d -> ACIContent
ACIContent SMsgDirection 'MDRcv
SMDRcv (CIContent 'MDRcv -> ACIContent) -> CIContent 'MDRcv -> ACIContent
forall a b. (a -> b) -> a -> b
$ RcvGroupEvent -> CIContent 'MDRcv
CIRcvGroupEvent RcvGroupEvent
rge
  DBJCISndGroupEvent (SGE SndGroupEvent
sge) -> SMsgDirection 'MDSnd -> CIContent 'MDSnd -> ACIContent
forall (d :: MsgDirection).
MsgDirectionI d =>
SMsgDirection d -> CIContent d -> ACIContent
ACIContent SMsgDirection 'MDSnd
SMDSnd (CIContent 'MDSnd -> ACIContent) -> CIContent 'MDSnd -> ACIContent
forall a b. (a -> b) -> a -> b
$ SndGroupEvent -> CIContent 'MDSnd
CISndGroupEvent SndGroupEvent
sge
  DBJCIRcvConnEvent (RCE RcvConnEvent
rce) -> SMsgDirection 'MDRcv -> CIContent 'MDRcv -> ACIContent
forall (d :: MsgDirection).
MsgDirectionI d =>
SMsgDirection d -> CIContent d -> ACIContent
ACIContent SMsgDirection 'MDRcv
SMDRcv (CIContent 'MDRcv -> ACIContent) -> CIContent 'MDRcv -> ACIContent
forall a b. (a -> b) -> a -> b
$ RcvConnEvent -> CIContent 'MDRcv
CIRcvConnEvent RcvConnEvent
rce
  DBJCISndConnEvent (SCE SndConnEvent
sce) -> SMsgDirection 'MDSnd -> CIContent 'MDSnd -> ACIContent
forall (d :: MsgDirection).
MsgDirectionI d =>
SMsgDirection d -> CIContent d -> ACIContent
ACIContent SMsgDirection 'MDSnd
SMDSnd (CIContent 'MDSnd -> ACIContent) -> CIContent 'MDSnd -> ACIContent
forall a b. (a -> b) -> a -> b
$ SndConnEvent -> CIContent 'MDSnd
CISndConnEvent SndConnEvent
sce
  DBJCIRcvChatFeature {ChatFeature
feature :: DBJSONCIContent -> ChatFeature
feature :: ChatFeature
feature, PrefEnabled
enabled :: DBJSONCIContent -> PrefEnabled
enabled :: PrefEnabled
enabled, Maybe Int
param :: DBJSONCIContent -> Maybe Int
param :: Maybe Int
param} -> SMsgDirection 'MDRcv -> CIContent 'MDRcv -> ACIContent
forall (d :: MsgDirection).
MsgDirectionI d =>
SMsgDirection d -> CIContent d -> ACIContent
ACIContent SMsgDirection 'MDRcv
SMDRcv (CIContent 'MDRcv -> ACIContent) -> CIContent 'MDRcv -> ACIContent
forall a b. (a -> b) -> a -> b
$ ChatFeature -> PrefEnabled -> Maybe Int -> CIContent 'MDRcv
CIRcvChatFeature ChatFeature
feature PrefEnabled
enabled Maybe Int
param
  DBJCISndChatFeature {ChatFeature
feature :: DBJSONCIContent -> ChatFeature
feature :: ChatFeature
feature, PrefEnabled
enabled :: DBJSONCIContent -> PrefEnabled
enabled :: PrefEnabled
enabled, Maybe Int
param :: DBJSONCIContent -> Maybe Int
param :: Maybe Int
param} -> SMsgDirection 'MDSnd -> CIContent 'MDSnd -> ACIContent
forall (d :: MsgDirection).
MsgDirectionI d =>
SMsgDirection d -> CIContent d -> ACIContent
ACIContent SMsgDirection 'MDSnd
SMDSnd (CIContent 'MDSnd -> ACIContent) -> CIContent 'MDSnd -> ACIContent
forall a b. (a -> b) -> a -> b
$ ChatFeature -> PrefEnabled -> Maybe Int -> CIContent 'MDSnd
CISndChatFeature ChatFeature
feature PrefEnabled
enabled Maybe Int
param
  DBJCIRcvChatPreference {ChatFeature
feature :: DBJSONCIContent -> ChatFeature
feature :: ChatFeature
feature, FeatureAllowed
allowed :: DBJSONCIContent -> FeatureAllowed
allowed :: FeatureAllowed
allowed, Maybe Int
param :: DBJSONCIContent -> Maybe Int
param :: Maybe Int
param} -> SMsgDirection 'MDRcv -> CIContent 'MDRcv -> ACIContent
forall (d :: MsgDirection).
MsgDirectionI d =>
SMsgDirection d -> CIContent d -> ACIContent
ACIContent SMsgDirection 'MDRcv
SMDRcv (CIContent 'MDRcv -> ACIContent) -> CIContent 'MDRcv -> ACIContent
forall a b. (a -> b) -> a -> b
$ ChatFeature -> FeatureAllowed -> Maybe Int -> CIContent 'MDRcv
CIRcvChatPreference ChatFeature
feature FeatureAllowed
allowed Maybe Int
param
  DBJCISndChatPreference {ChatFeature
feature :: DBJSONCIContent -> ChatFeature
feature :: ChatFeature
feature, FeatureAllowed
allowed :: DBJSONCIContent -> FeatureAllowed
allowed :: FeatureAllowed
allowed, Maybe Int
param :: DBJSONCIContent -> Maybe Int
param :: Maybe Int
param} -> SMsgDirection 'MDSnd -> CIContent 'MDSnd -> ACIContent
forall (d :: MsgDirection).
MsgDirectionI d =>
SMsgDirection d -> CIContent d -> ACIContent
ACIContent SMsgDirection 'MDSnd
SMDSnd (CIContent 'MDSnd -> ACIContent) -> CIContent 'MDSnd -> ACIContent
forall a b. (a -> b) -> a -> b
$ ChatFeature -> FeatureAllowed -> Maybe Int -> CIContent 'MDSnd
CISndChatPreference ChatFeature
feature FeatureAllowed
allowed Maybe Int
param
  DBJCIRcvGroupFeature {GroupFeature
groupFeature :: DBJSONCIContent -> GroupFeature
groupFeature :: GroupFeature
groupFeature, GroupPreference
preference :: DBJSONCIContent -> GroupPreference
preference :: GroupPreference
preference, Maybe Int
param :: DBJSONCIContent -> Maybe Int
param :: Maybe Int
param, Maybe GroupMemberRole
memberRole_ :: DBJSONCIContent -> Maybe GroupMemberRole
memberRole_ :: Maybe GroupMemberRole
memberRole_} -> SMsgDirection 'MDRcv -> CIContent 'MDRcv -> ACIContent
forall (d :: MsgDirection).
MsgDirectionI d =>
SMsgDirection d -> CIContent d -> ACIContent
ACIContent SMsgDirection 'MDRcv
SMDRcv (CIContent 'MDRcv -> ACIContent) -> CIContent 'MDRcv -> ACIContent
forall a b. (a -> b) -> a -> b
$ GroupFeature
-> GroupPreference
-> Maybe Int
-> Maybe GroupMemberRole
-> CIContent 'MDRcv
CIRcvGroupFeature GroupFeature
groupFeature GroupPreference
preference Maybe Int
param Maybe GroupMemberRole
memberRole_
  DBJCISndGroupFeature {GroupFeature
groupFeature :: DBJSONCIContent -> GroupFeature
groupFeature :: GroupFeature
groupFeature, GroupPreference
preference :: DBJSONCIContent -> GroupPreference
preference :: GroupPreference
preference, Maybe Int
param :: DBJSONCIContent -> Maybe Int
param :: Maybe Int
param, Maybe GroupMemberRole
memberRole_ :: DBJSONCIContent -> Maybe GroupMemberRole
memberRole_ :: Maybe GroupMemberRole
memberRole_} -> SMsgDirection 'MDSnd -> CIContent 'MDSnd -> ACIContent
forall (d :: MsgDirection).
MsgDirectionI d =>
SMsgDirection d -> CIContent d -> ACIContent
ACIContent SMsgDirection 'MDSnd
SMDSnd (CIContent 'MDSnd -> ACIContent) -> CIContent 'MDSnd -> ACIContent
forall a b. (a -> b) -> a -> b
$ GroupFeature
-> GroupPreference
-> Maybe Int
-> Maybe GroupMemberRole
-> CIContent 'MDSnd
CISndGroupFeature GroupFeature
groupFeature GroupPreference
preference Maybe Int
param Maybe GroupMemberRole
memberRole_
  DBJCIRcvChatFeatureRejected {ChatFeature
feature :: DBJSONCIContent -> ChatFeature
feature :: ChatFeature
feature} -> SMsgDirection 'MDRcv -> CIContent 'MDRcv -> ACIContent
forall (d :: MsgDirection).
MsgDirectionI d =>
SMsgDirection d -> CIContent d -> ACIContent
ACIContent SMsgDirection 'MDRcv
SMDRcv (CIContent 'MDRcv -> ACIContent) -> CIContent 'MDRcv -> ACIContent
forall a b. (a -> b) -> a -> b
$ ChatFeature -> CIContent 'MDRcv
CIRcvChatFeatureRejected ChatFeature
feature
  DBJCIRcvGroupFeatureRejected {GroupFeature
groupFeature :: DBJSONCIContent -> GroupFeature
groupFeature :: GroupFeature
groupFeature} -> SMsgDirection 'MDRcv -> CIContent 'MDRcv -> ACIContent
forall (d :: MsgDirection).
MsgDirectionI d =>
SMsgDirection d -> CIContent d -> ACIContent
ACIContent SMsgDirection 'MDRcv
SMDRcv (CIContent 'MDRcv -> ACIContent) -> CIContent 'MDRcv -> ACIContent
forall a b. (a -> b) -> a -> b
$ GroupFeature -> CIContent 'MDRcv
CIRcvGroupFeatureRejected GroupFeature
groupFeature
  DBJSONCIContent
DBJCISndModerated -> SMsgDirection 'MDSnd -> CIContent 'MDSnd -> ACIContent
forall (d :: MsgDirection).
MsgDirectionI d =>
SMsgDirection d -> CIContent d -> ACIContent
ACIContent SMsgDirection 'MDSnd
SMDSnd CIContent 'MDSnd
CISndModerated
  DBJSONCIContent
DBJCIRcvModerated -> SMsgDirection 'MDRcv -> CIContent 'MDRcv -> ACIContent
forall (d :: MsgDirection).
MsgDirectionI d =>
SMsgDirection d -> CIContent d -> ACIContent
ACIContent SMsgDirection 'MDRcv
SMDRcv CIContent 'MDRcv
CIRcvModerated
  DBJSONCIContent
DBJCIRcvBlocked -> SMsgDirection 'MDRcv -> CIContent 'MDRcv -> ACIContent
forall (d :: MsgDirection).
MsgDirectionI d =>
SMsgDirection d -> CIContent d -> ACIContent
ACIContent SMsgDirection 'MDRcv
SMDRcv CIContent 'MDRcv
CIRcvBlocked
  DBJCISndDirectE2EEInfo E2EInfo
e2eeInfo -> SMsgDirection 'MDSnd -> CIContent 'MDSnd -> ACIContent
forall (d :: MsgDirection).
MsgDirectionI d =>
SMsgDirection d -> CIContent d -> ACIContent
ACIContent SMsgDirection 'MDSnd
SMDSnd (CIContent 'MDSnd -> ACIContent) -> CIContent 'MDSnd -> ACIContent
forall a b. (a -> b) -> a -> b
$ E2EInfo -> CIContent 'MDSnd
CISndDirectE2EEInfo E2EInfo
e2eeInfo
  DBJCIRcvDirectE2EEInfo E2EInfo
e2eeInfo -> SMsgDirection 'MDRcv -> CIContent 'MDRcv -> ACIContent
forall (d :: MsgDirection).
MsgDirectionI d =>
SMsgDirection d -> CIContent d -> ACIContent
ACIContent SMsgDirection 'MDRcv
SMDRcv (CIContent 'MDRcv -> ACIContent) -> CIContent 'MDRcv -> ACIContent
forall a b. (a -> b) -> a -> b
$ E2EInfo -> CIContent 'MDRcv
CIRcvDirectE2EEInfo E2EInfo
e2eeInfo
  DBJCISndGroupE2EEInfo E2EInfo
e2eeInfo -> SMsgDirection 'MDSnd -> CIContent 'MDSnd -> ACIContent
forall (d :: MsgDirection).
MsgDirectionI d =>
SMsgDirection d -> CIContent d -> ACIContent
ACIContent SMsgDirection 'MDSnd
SMDSnd (CIContent 'MDSnd -> ACIContent) -> CIContent 'MDSnd -> ACIContent
forall a b. (a -> b) -> a -> b
$ E2EInfo -> CIContent 'MDSnd
CISndGroupE2EEInfo E2EInfo
e2eeInfo
  DBJCIRcvGroupE2EEInfo E2EInfo
e2eeInfo -> SMsgDirection 'MDRcv -> CIContent 'MDRcv -> ACIContent
forall (d :: MsgDirection).
MsgDirectionI d =>
SMsgDirection d -> CIContent d -> ACIContent
ACIContent SMsgDirection 'MDRcv
SMDRcv (CIContent 'MDRcv -> ACIContent) -> CIContent 'MDRcv -> ACIContent
forall a b. (a -> b) -> a -> b
$ E2EInfo -> CIContent 'MDRcv
CIRcvGroupE2EEInfo E2EInfo
e2eeInfo
  DBJSONCIContent
DBJCIChatBanner -> SMsgDirection 'MDSnd -> CIContent 'MDSnd -> ACIContent
forall (d :: MsgDirection).
MsgDirectionI d =>
SMsgDirection d -> CIContent d -> ACIContent
ACIContent SMsgDirection 'MDSnd
SMDSnd CIContent 'MDSnd
CIChatBanner
  DBJCIInvalidJSON MsgDirection
dir Text
json -> case MsgDirection -> AMsgDirection
fromMsgDirection MsgDirection
dir of
    AMsgDirection SMsgDirection d
d -> SMsgDirection d -> CIContent d -> ACIContent
forall (d :: MsgDirection).
MsgDirectionI d =>
SMsgDirection d -> CIContent d -> ACIContent
ACIContent SMsgDirection d
d (CIContent d -> ACIContent) -> CIContent d -> ACIContent
forall a b. (a -> b) -> a -> b
$ Text -> CIContent d
forall (d :: MsgDirection). Text -> CIContent d
CIInvalidJSON Text
json

data CICallStatus
  = CISCallPending
  | CISCallMissed
  | CISCallRejected -- only possible for received calls, not on type level
  | CISCallAccepted
  | CISCallNegotiated
  | CISCallProgress
  | CISCallEnded
  | CISCallError
  deriving (Int -> CICallStatus -> ShowS
[CICallStatus] -> ShowS
CICallStatus -> String
(Int -> CICallStatus -> ShowS)
-> (CICallStatus -> String)
-> ([CICallStatus] -> ShowS)
-> Show CICallStatus
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> CICallStatus -> ShowS
showsPrec :: Int -> CICallStatus -> ShowS
$cshow :: CICallStatus -> String
show :: CICallStatus -> String
$cshowList :: [CICallStatus] -> ShowS
showList :: [CICallStatus] -> ShowS
Show)

ciCallInfoText :: CICallStatus -> Int -> Text
ciCallInfoText :: CICallStatus -> Int -> Text
ciCallInfoText CICallStatus
status Int
duration = case CICallStatus
status of
  CICallStatus
CISCallPending -> Text
"calling..."
  CICallStatus
CISCallMissed -> Text
"missed"
  CICallStatus
CISCallRejected -> Text
"rejected"
  CICallStatus
CISCallAccepted -> Text
"accepted"
  CICallStatus
CISCallNegotiated -> Text
"connecting..."
  CICallStatus
CISCallProgress -> Text
"in progress " Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Int -> Text
durationText Int
duration
  CICallStatus
CISCallEnded -> Text
"ended " Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Int -> Text
durationText Int
duration
  CICallStatus
CISCallError -> Text
"error"

callComplete :: CICallStatus -> Bool
callComplete :: CICallStatus -> Bool
callComplete = \case
  CICallStatus
CISCallMissed -> Bool
True
  CICallStatus
CISCallRejected -> Bool
True
  CICallStatus
CISCallEnded -> Bool
True
  CICallStatus
CISCallError -> Bool
True
  CICallStatus
_ -> Bool
False

$(JQ.deriveJSON defaultJSON ''E2EInfo)

$(JQ.deriveJSON (enumJSON $ dropPrefix "MDE") ''MsgDecryptError)

$(JQ.deriveJSON (enumJSON $ dropPrefix "CIGIS") ''CIGroupInvitationStatus)

$(JQ.deriveJSON defaultJSON ''CIGroupInvitation)

$(JQ.deriveJSON (enumJSON $ dropPrefix "CISCall") ''CICallStatus)

-- platform specific
$(JQ.deriveToJSON (sumTypeJSON $ dropPrefix "JCI") ''JSONCIContent)

-- We only need this fallback for platform specific encoding to support remote desktop link
instance FromJSON JSONCIContent where
  parseJSON :: Value -> Parser JSONCIContent
parseJSON Value
v =
    $(JQ.mkParseJSON (sumTypeJSON $ dropPrefix "JCI") ''JSONCIContent) Value
v
      Parser JSONCIContent
-> Parser JSONCIContent -> Parser JSONCIContent
forall a. Parser a -> Parser a -> Parser a
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> JSONCIContent -> Parser JSONCIContent
forall a. a -> Parser a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (MsgDirection -> Text -> JSONCIContent
JCIInvalidJSON MsgDirection
MDRcv (Text -> JSONCIContent) -> Text -> JSONCIContent
forall a b. (a -> b) -> a -> b
$ ByteString -> Text
safeDecodeUtf8 (ByteString -> Text) -> ByteString -> Text
forall a b. (a -> b) -> a -> b
$ LazyByteString -> ByteString
LB.toStrict (LazyByteString -> ByteString) -> LazyByteString -> ByteString
forall a b. (a -> b) -> a -> b
$ Value -> LazyByteString
forall a. ToJSON a => a -> LazyByteString
J.encode Value
v)

-- platform independent
$(JQ.deriveJSON (singleFieldJSON $ dropPrefix "DBJCI") ''DBJSONCIContent)

-- platform independent
instance MsgDirectionI d => ToField (CIContent d) where
  toField :: CIContent d -> SQLData
toField = Text -> SQLData
forall a. ToField a => a -> SQLData
toField (Text -> SQLData)
-> (CIContent d -> Text) -> CIContent d -> SQLData
forall b c a. (b -> c) -> (a -> b) -> a -> c
. DBJSONCIContent -> Text
forall a. ToJSON a => a -> Text
encodeJSON (DBJSONCIContent -> Text)
-> (CIContent d -> DBJSONCIContent) -> CIContent d -> Text
forall b c a. (b -> c) -> (a -> b) -> a -> c
. CIContent d -> DBJSONCIContent
forall (d :: MsgDirection).
MsgDirectionI d =>
CIContent d -> DBJSONCIContent
dbJsonCIContent

-- platform specific
instance MsgDirectionI d => ToJSON (CIContent d) where
  toJSON :: CIContent d -> Value
toJSON = JSONCIContent -> Value
forall a. ToJSON a => a -> Value
J.toJSON (JSONCIContent -> Value)
-> (CIContent d -> JSONCIContent) -> CIContent d -> Value
forall b c a. (b -> c) -> (a -> b) -> a -> c
. CIContent d -> JSONCIContent
forall (d :: MsgDirection).
MsgDirectionI d =>
CIContent d -> JSONCIContent
jsonCIContent
  toEncoding :: CIContent d -> Encoding
toEncoding = JSONCIContent -> Encoding
forall a. ToJSON a => a -> Encoding
J.toEncoding (JSONCIContent -> Encoding)
-> (CIContent d -> JSONCIContent) -> CIContent d -> Encoding
forall b c a. (b -> c) -> (a -> b) -> a -> c
. CIContent d -> JSONCIContent
forall (d :: MsgDirection).
MsgDirectionI d =>
CIContent d -> JSONCIContent
jsonCIContent

instance MsgDirectionI d => FromJSON (CIContent d) where
  parseJSON :: Value -> Parser (CIContent d)
parseJSON Value
v = ACIContent -> Either String (CIContent d)
unwrap (ACIContent -> Either String (CIContent d))
-> Parser ACIContent -> Parser (CIContent d)
forall (m :: * -> *) a b.
MonadFail m =>
(a -> Either String b) -> m a -> m b
<$?> Value -> Parser ACIContent
forall a. FromJSON a => Value -> Parser a
J.parseJSON Value
v
    where
      unwrap :: ACIContent -> Either String (CIContent d)
unwrap = \case
        ACIContent SMsgDirection d
_ (CIInvalidJSON Text
t) -> CIContent d -> Either String (CIContent d)
forall a b. b -> Either a b
Right (CIContent d -> Either String (CIContent d))
-> CIContent d -> Either String (CIContent d)
forall a b. (a -> b) -> a -> b
$ forall (d :: MsgDirection). Text -> CIContent d
CIInvalidJSON @d Text
t -- ignoring direction in ACIContent - it may be incorrect from JSONCIContent parser fallback
        ACIContent SMsgDirection d
_ CIContent d
c -> CIContent d -> Either String (CIContent d)
forall (t :: MsgDirection -> *) (d :: MsgDirection)
       (d' :: MsgDirection).
(MsgDirectionI d, MsgDirectionI d') =>
t d' -> Either String (t d)
checkDirection CIContent d
c

-- platform independent
dbParseACIContent :: Text -> Either String ACIContent
dbParseACIContent :: Text -> Either String ACIContent
dbParseACIContent = (DBJSONCIContent -> ACIContent)
-> Either String DBJSONCIContent -> Either String ACIContent
forall a b. (a -> b) -> Either String a -> Either String b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap DBJSONCIContent -> ACIContent
aciContentDBJSON (Either String DBJSONCIContent -> Either String ACIContent)
-> (Text -> Either String DBJSONCIContent)
-> Text
-> Either String ACIContent
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ByteString -> Either String DBJSONCIContent
forall a. FromJSON a => ByteString -> Either String a
J.eitherDecodeStrict' (ByteString -> Either String DBJSONCIContent)
-> (Text -> ByteString) -> Text -> Either String DBJSONCIContent
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Text -> ByteString
encodeUtf8

-- platform specific
instance FromJSON ACIContent where
  parseJSON :: Value -> Parser ACIContent
parseJSON = (JSONCIContent -> ACIContent)
-> Parser JSONCIContent -> Parser ACIContent
forall a b. (a -> b) -> Parser a -> Parser b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap JSONCIContent -> ACIContent
aciContentJSON (Parser JSONCIContent -> Parser ACIContent)
-> (Value -> Parser JSONCIContent) -> Value -> Parser ACIContent
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Value -> Parser JSONCIContent
forall a. FromJSON a => Value -> Parser a
J.parseJSON

sndMsgContentTag :: Text
sndMsgContentTag :: Text
sndMsgContentTag = Text
"sndMsgContent"

rcvMsgContentTag :: Text
rcvMsgContentTag :: Text
rcvMsgContentTag = Text
"rcvMsgContent"

toCIContentTag :: CIContent e -> Text
toCIContentTag :: forall (d :: MsgDirection). CIContent d -> Text
toCIContentTag CIContent e
ciContent = case CIContent e
ciContent of
  CISndMsgContent MsgContent
_ -> Text
sndMsgContentTag
  CIRcvMsgContent MsgContent
_ -> Text
rcvMsgContentTag
  CISndDeleted CIDeleteMode
_ -> Text
"sndDeleted"
  CIRcvDeleted CIDeleteMode
_ -> Text
"rcvDeleted"
  CISndCall {} -> Text
"sndCall"
  CIRcvCall {} -> Text
"rcvCall"
  CIRcvIntegrityError MsgErrorType
_ -> Text
"rcvIntegrityError"
  CIRcvDecryptionError {} -> Text
"rcvDecryptionError"
  CIRcvGroupInvitation {} -> Text
"rcvGroupInvitation"
  CISndGroupInvitation {} -> Text
"sndGroupInvitation"
  CIRcvDirectEvent RcvDirectEvent
_ -> Text
"rcvDirectEvent"
  CIRcvGroupEvent RcvGroupEvent
_ -> Text
"rcvGroupEvent"
  CISndGroupEvent SndGroupEvent
_ -> Text
"sndGroupEvent"
  CIRcvConnEvent RcvConnEvent
_ -> Text
"rcvConnEvent"
  CISndConnEvent SndConnEvent
_ -> Text
"sndConnEvent"
  CIRcvChatFeature {} -> Text
"rcvChatFeature"
  CISndChatFeature {} -> Text
"sndChatFeature"
  CIRcvChatPreference {} -> Text
"rcvChatPreference"
  CISndChatPreference {} -> Text
"sndChatPreference"
  CIRcvGroupFeature {} -> Text
"rcvGroupFeature"
  CISndGroupFeature {} -> Text
"sndGroupFeature"
  CIRcvChatFeatureRejected ChatFeature
_ -> Text
"rcvChatFeatureRejected"
  CIRcvGroupFeatureRejected GroupFeature
_ -> Text
"rcvGroupFeatureRejected"
  CIContent e
CISndModerated -> Text
"sndModerated"
  CIContent e
CIRcvModerated -> Text
"rcvModerated"
  CIContent e
CIRcvBlocked -> Text
"rcvBlocked"
  CISndDirectE2EEInfo E2EInfo
_ -> Text
"sndDirectE2EEInfo"
  CIRcvDirectE2EEInfo E2EInfo
_ -> Text
"rcvDirectE2EEInfo"
  CISndGroupE2EEInfo E2EInfo
_ -> Text
"sndGroupE2EEInfo"
  CIRcvGroupE2EEInfo E2EInfo
_ -> Text
"rcvGroupE2EEInfo"
  CIContent e
CIChatBanner -> Text
"chatBanner"
  CIInvalidJSON Text
_ -> Text
"invalidJSON"