mirror of
https://github.com/simplex-chat/simplex-chat.git
synced 2026-11-04 10:47:32 +00:00
core, ui: terminal chat layout for LLM and service bot chats (#7811)
* plan: UI improvements to improve LLM usage via SimpleX * core, ui: types for chat layout * core, ui: settings for alternative terminal-like chat layout for managing LLMs or other service bots * plan: message priority * fixes * query plan * update plans * remove silent messages plan * rename migrations * implement layout * amend * fix * fix * fix * improve * time on the right, sender name in blue * no avatar in direct chats * better previews * update, fixes * update * time gap * changes * ui: terminal layout line heights, gaps and time placement * ui: simplify terminal meta layout, correct its docs and tests * ui: right-to-left emoji edge in terminal rows, time placement tests * android, desktop: raise Kotlin compiler memory to 4 GB * ui: terminal captions as follow-up text, classic event separators * ui: terminal media edge and overlay time, plan decisions * ui: simplify terminal row separation, correct doc line references * ui: keep the media time inside terminal rows, restore caption conditions * ui: terminal heading capitals at large font scales, idle live message time * ui: rename the classic voice-with-text flag, correct the meta copy docs * ui: smaller terminal layout diff, sender gap and meta names * ui: terminal row as tall as the media time * docs: remove the chat layout section from the bots readme * docs: shorten the terminal layout section of the chat view * core: address settings API as on master, /auto_accept reads the stored layout * ui: smaller terminal headings * ui: classic sender rows and avatar rule as on master * ui: classic reply quote text colour as on master * ios: keep the chat layout setting with other UI settings * ui: go-to button at the end of terminal rows, no gutter in direct chats * ui: forwarded arrow on the header line of terminal rows, above the time * ui: forwarded arrow centred above the time line of terminal rows --------- Co-authored-by: Evgeny Poberezkin <evgeny@poberezkin.com>
This commit is contained in:
1 parent
4f81c6f632
commit
7810fc4752
103 files changed
+5098
-901
No files matched your search
@@ -123,7 +123,8 @@ badgeGroupTests = describe "badge group" $ do
|
||||
image = Nothing,
|
||||
publicGroup = Nothing,
|
||||
groupPreferences = Nothing,
|
||||
memberAdmission = Nothing
|
||||
memberAdmission = Nothing,
|
||||
chatLayout = Nothing
|
||||
}
|
||||
it "says nothing when the config matches the group profile" $ do
|
||||
inertGroupConfig (cfg "SimpleX Badges" (Just "badge ops desk")) (profile "SimpleX Badges" (Just "badge ops desk"))
|
||||
|
||||
@@ -43,6 +43,7 @@ import Simplex.Chat.Protocol (ChatMessage (ChatMessage), ChatMsgEvent (XGrpMemNe
|
||||
import Simplex.Chat.Types
|
||||
import Simplex.Chat.Types.MemberRelations (MemberRelation (..), getRelation, setRelation)
|
||||
import Simplex.Chat.Types.Shared (GroupMemberRole (..), GroupAcceptance (..))
|
||||
import Simplex.Chat.Types.UITheme (ChatLayout (..))
|
||||
import Simplex.Messaging.Agent (joinConnection, prepareConnectionToJoin, sendMessages, vrValue)
|
||||
import Simplex.Messaging.Agent.Env.SQLite
|
||||
import Simplex.Messaging.Agent.RetryInterval
|
||||
@@ -311,6 +312,7 @@ chatGroupTests = do
|
||||
it "should update channel profile (signed)" testChannelUpdateProfileSigned
|
||||
it "should preserve working link after profile update" testChannelLinkAfterProfileUpdate
|
||||
it "should preserve working link after welcome message update" testChannelLinkAfterWelcomeUpdate
|
||||
it "should set chat layout of channel joined via relays from link data" testChannelChatLayout
|
||||
it "should preserve owner key in link data after profile update" testChannelOwnerKeyAfterLinkUpdate
|
||||
it "should update channel preferences (signed)" testChannelUpdatePrefsSigned
|
||||
it "should change member role (signed)" testChannelChangeRoleSigned
|
||||
@@ -10552,6 +10554,32 @@ testChannelLinkAfterWelcomeUpdate ps =
|
||||
bob <# "#team> hi"
|
||||
[cath, dan] *<# "#team> hi [>>]"
|
||||
|
||||
testChannelChatLayout :: HasCallStack => TestParams -> IO ()
|
||||
testChannelChatLayout ps =
|
||||
withNewTestChat ps "alice" aliceProfile $ \alice ->
|
||||
withNewTestChatOpts ps relayTestOpts "bob" bobProfile $ \bob ->
|
||||
withNewTestChat ps "cath" cathProfile $ \cath -> do
|
||||
(shortLink, _fullLink) <- prepareChannel1Relay "team" alice bob
|
||||
alice ##> "/set layout #team terminal"
|
||||
alice <## "chat layout changed to: terminal"
|
||||
bob <## "alice updated group #team: (signed)"
|
||||
bob <## "chat layout changed to: terminal"
|
||||
cath ##> ("/c " <> shortLink)
|
||||
cath <## "#team: connection started"
|
||||
concurrentlyN_
|
||||
[ cath
|
||||
<### [ "#team: joining the group (connecting to relay bob)...",
|
||||
"#team: you joined the group (connected to relay bob)"
|
||||
],
|
||||
do
|
||||
bob <## "cath (Catherine): accepting request to join group #team..."
|
||||
bob <## "#team: cath joined the group",
|
||||
alice <### [EndsWith "introduced cath (Catherine) in the channel"]
|
||||
]
|
||||
groupChatLayout alice "team" `shouldReturn` Just CLTerminal
|
||||
groupChatLayout bob "team" `shouldReturn` Just CLTerminal
|
||||
groupChatLayout cath "team" `shouldReturn` Just CLTerminal
|
||||
|
||||
testChannelOwnerKeyAfterLinkUpdate :: HasCallStack => TestParams -> IO ()
|
||||
testChannelOwnerKeyAfterLinkUpdate ps =
|
||||
withNewTestChat ps "alice" aliceProfile $ \alice ->
|
||||
|
||||
+166
-3
@@ -166,6 +166,12 @@ chatProfileTests = do
|
||||
it "files & media" testGroupPrefsFilesForRole
|
||||
it "SimpleX links" testGroupPrefsSimplexLinksForRole
|
||||
it "set user, contact and group UI theme" testSetUITheme
|
||||
describe "chat layout" $ do
|
||||
it "group chat layout from group profile" testGroupChatLayout
|
||||
it "group chat layout from group link without prepare" testGroupLinkChatLayout
|
||||
it "unknown chat layout stored and read" testUnknownChatLayout
|
||||
it "contact chat layout from address" testAddressChatLayout
|
||||
it "business chat layout from business address" testBusinessAddressChatLayout
|
||||
describe "short links" $ do
|
||||
it "should connect via one-time invitation" testShortLinkInvitation
|
||||
it "should plan and connect via one-time invitation" testPlanShortLinkInvitation
|
||||
@@ -1125,7 +1131,7 @@ testUserBadgeLinkDataOtherLink ps = do
|
||||
alice ##> "/_connect 1"
|
||||
(shortLink, _) <- getInvitations alice
|
||||
Right otherProof <- badgeProof pk cred (PHLink "other link key")
|
||||
setTestInvLinkData alice $ ContactShortLinkData aliceProfile {badge = Just otherProof} Nothing False Nothing
|
||||
setTestInvLinkData alice $ ContactShortLinkData aliceProfile {badge = Just otherProof} Nothing False Nothing Nothing
|
||||
bob ##> ("/_connect plan 1 " <> shortLink)
|
||||
bob <## "invitation link: ok to connect"
|
||||
sLinkData <- getTermLine bob
|
||||
@@ -1139,7 +1145,7 @@ testUserBadgeLinkDataNoProof =
|
||||
alice ##> "/_connect 1"
|
||||
(shortLink, _) <- getInvitations alice
|
||||
let shownBadge = ShownBadge BadgeInfo {badgeType = BTSupporter, badgeExpiry = futureDate, badgeExtra = ""} BSActive
|
||||
setTestInvLinkData alice $ ContactShortLinkData aliceProfile Nothing False (Just shownBadge)
|
||||
setTestInvLinkData alice $ ContactShortLinkData aliceProfile Nothing False Nothing (Just shownBadge)
|
||||
bob ##> ("/_connect plan 1 " <> shortLink)
|
||||
bob <## "invitation link: ok to connect"
|
||||
sLinkData <- getTermLine bob
|
||||
@@ -3835,7 +3841,7 @@ testSetUITheme =
|
||||
alice ##> "/i #team"
|
||||
groupInfo alice
|
||||
where
|
||||
theme cm = T.unpack $ encodeJSON UIThemeEntityOverrides {light = Nothing, dark = Just $ UIThemeEntityOverride cm Nothing defaultUIColors}
|
||||
theme cm = T.unpack $ encodeJSON UIThemeEntityOverrides {light = Nothing, dark = Just $ UIThemeEntityOverride cm Nothing defaultUIColors, chatLayout = Just CLTerminal}
|
||||
userInfo a name = do
|
||||
a <## ("user profile: " <> name)
|
||||
a <## "use /p <name> [<bio>] to change it"
|
||||
@@ -3851,6 +3857,163 @@ testSetUITheme =
|
||||
a <## "group ID: 1"
|
||||
a <## "current members: 1"
|
||||
|
||||
testGroupChatLayout :: HasCallStack => TestParams -> IO ()
|
||||
testGroupChatLayout =
|
||||
testChat3 aliceProfile bobProfile cathProfile $ \alice bob cath -> do
|
||||
connectUsers alice cath
|
||||
createGroupWithLayout alice "terminal"
|
||||
groupChatLayout alice "team" `shouldReturn` Just CLTerminal
|
||||
addMember "team" alice cath GRAdmin
|
||||
cath ##> "/j team"
|
||||
concurrently_
|
||||
(alice <## "#team: cath joined the group")
|
||||
(cath <## "#team: you joined the group")
|
||||
groupChatLayout cath "team" `shouldReturn` Just CLTerminal
|
||||
alice ##> "/create link #team"
|
||||
(shortLink, fullLink) <- getGroupLinks alice "team" GRMember True
|
||||
alice ##> "/set layout #team classic"
|
||||
alice <## "chat layout changed to: classic"
|
||||
cath <## "alice updated group #team: (signed)"
|
||||
cath <## "chat layout changed to: classic"
|
||||
groupChatLayout alice "team" `shouldReturn` Just CLClassic
|
||||
groupChatLayout cath "team" `shouldReturn` Just CLClassic
|
||||
alice ##> "/group_profile team"
|
||||
alice <## "#team"
|
||||
alice <## "chat layout: classic"
|
||||
alice <## "group preferences:"
|
||||
mapM_ (\((_, feature), _, _) -> alice <## feature) $ groupFeatures_ 0 False
|
||||
bob ##> ("/_connect plan 1 " <> shortLink)
|
||||
bob <## "group link: ok to connect directly"
|
||||
groupSLinkData <- getTermLine bob
|
||||
bob ##> ("/_prepare group 1 " <> fullLink <> " " <> shortLink <> " " <> groupSLinkData)
|
||||
bob <## "#team: group is prepared"
|
||||
groupChatLayout bob "team" `shouldReturn` Just CLClassic
|
||||
alice ##> "/set layout #team default"
|
||||
alice <## "chat layout removed"
|
||||
cath <## "alice updated group #team: (signed)"
|
||||
cath <## "chat layout removed"
|
||||
groupChatLayout alice "team" `shouldReturn` Nothing
|
||||
groupChatLayout cath "team" `shouldReturn` Nothing
|
||||
bob ##> "/_connect group #1"
|
||||
bob <## "#team: connection started"
|
||||
alice <## "bob (Bob): accepting request to join group #team..."
|
||||
concurrentlyN_
|
||||
[ alice <## "#team: bob joined the group",
|
||||
do
|
||||
bob <## "#team: joining the group..."
|
||||
bob <## "#team: you joined the group"
|
||||
bob <## "#team: member cath (Catherine) is connected",
|
||||
do
|
||||
cath <## "#team: alice added bob (Bob) to the group (connecting...)"
|
||||
cath <## "#team: new member bob is connected"
|
||||
]
|
||||
groupChatLayout bob "team" `shouldReturn` Nothing
|
||||
|
||||
createGroupWithLayout :: HasCallStack => TestCC -> String -> IO ()
|
||||
createGroupWithLayout cc layout = do
|
||||
cc ##> ("/_group 1 {\"displayName\": \"team\", \"fullName\": \"\", \"groupPreferences\": {\"directMessages\": {\"enable\": \"on\"}, \"history\": {\"enable\": \"on\"}}, \"chatLayout\": \"" <> layout <> "\"}")
|
||||
cc <## "group #team is created"
|
||||
cc <## "to add members use /a team <name> or /create link #team"
|
||||
|
||||
testGroupLinkChatLayout :: HasCallStack => TestParams -> IO ()
|
||||
testGroupLinkChatLayout =
|
||||
testChat2 aliceProfile bobProfile $ \alice bob -> do
|
||||
createGroupWithLayout alice "terminal"
|
||||
alice ##> "/create link #team"
|
||||
gLink <- getGroupLink alice "team" GRMember True
|
||||
bob ##> ("/c " <> gLink)
|
||||
bob <## "connection request sent!"
|
||||
alice <## "bob (Bob): accepting request to join group #team..."
|
||||
concurrentlyN_
|
||||
[ alice <## "#team: bob joined the group",
|
||||
do
|
||||
bob <## "#team: joining the group..."
|
||||
bob <## "#team: you joined the group"
|
||||
]
|
||||
groupChatLayout bob "team" `shouldReturn` Just CLTerminal
|
||||
|
||||
testUnknownChatLayout :: HasCallStack => TestParams -> IO ()
|
||||
testUnknownChatLayout =
|
||||
testChat aliceProfile $ \alice -> do
|
||||
createGroupWithLayout alice "wide"
|
||||
groupChatLayout alice "team" `shouldReturn` Just (CLUnknown "wide")
|
||||
|
||||
testAddressChatLayout :: HasCallStack => TestParams -> IO ()
|
||||
testAddressChatLayout =
|
||||
testChat2 aliceProfile bobProfile $ \alice bob -> do
|
||||
alice ##> "/ad"
|
||||
(shortLink, fullLink) <- getContactLinks alice True
|
||||
alice ##> "/_address_settings 1 {\"businessAddress\": false, \"autoAccept\": {\"acceptIncognito\": false}, \"chatLayout\": \"terminal\"}"
|
||||
alice <## "auto_accept on"
|
||||
alice <## "chat layout: terminal"
|
||||
bob ##> ("/_connect plan 1 " <> shortLink)
|
||||
bob <## "contact address: ok to connect"
|
||||
contactSLinkData <- getTermLine bob
|
||||
bob ##> ("/_prepare contact 1 " <> fullLink <> " " <> shortLink <> " " <> contactSLinkData)
|
||||
bob <## "alice: contact is prepared"
|
||||
contactChatLayout bob "alice" `shouldReturn` Just CLTerminal
|
||||
bob ##> "/_connect contact @2 text hello"
|
||||
bob
|
||||
<### [ "alice: connection started",
|
||||
WithTime "@alice hello"
|
||||
]
|
||||
alice <# "bob> hello"
|
||||
alice <## "bob (Bob): accepting contact request..."
|
||||
alice <## "bob (Bob): you can send messages to contact"
|
||||
concurrently_
|
||||
(bob <## "alice (Alice): contact is connected")
|
||||
(alice <## "bob (Bob): contact is connected")
|
||||
contactChatLayout bob "alice" `shouldReturn` Just CLTerminal
|
||||
contactChatLayout alice "bob" `shouldReturn` Nothing
|
||||
alice ##> "/auto_accept on layout=classic"
|
||||
alice <## "auto_accept on"
|
||||
alice <## "chat layout: classic"
|
||||
alice ##> "/auto_accept off"
|
||||
alice <## "auto_accept off"
|
||||
alice <## "chat layout: classic"
|
||||
alice ##> "/auto_accept on business"
|
||||
alice <## "auto_accept on, business"
|
||||
alice <## "chat layout: classic"
|
||||
alice ##> "/auto_accept off layout=default"
|
||||
alice <## "auto_accept off"
|
||||
alice ##> "/_address_settings 1 {\"businessAddress\": false, \"chatLayout\": \"terminal\"}"
|
||||
alice <## "auto_accept off"
|
||||
alice <## "chat layout: terminal"
|
||||
alice ##> "/_address_settings 1 {\"businessAddress\": false}"
|
||||
alice <## "auto_accept off"
|
||||
|
||||
testBusinessAddressChatLayout :: HasCallStack => TestParams -> IO ()
|
||||
testBusinessAddressChatLayout =
|
||||
testChat3 businessProfile aliceProfile bobProfile $ \biz alice bob -> do
|
||||
biz ##> "/ad"
|
||||
(shortLink, fullLink) <- getContactLinks biz True
|
||||
biz ##> "/auto_accept on business layout=terminal"
|
||||
biz <## "auto_accept on, business"
|
||||
biz <## "chat layout: terminal"
|
||||
bob ##> ("/_connect plan 1 " <> shortLink)
|
||||
bob <## "business address: ok to connect"
|
||||
contactSLinkData <- getTermLine bob
|
||||
bob ##> ("/_prepare contact 1 " <> fullLink <> " " <> shortLink <> " " <> contactSLinkData)
|
||||
bob <## "#biz: group is prepared"
|
||||
groupChatLayout bob "biz" `shouldReturn` Just CLTerminal
|
||||
bob ##> "/_connect group #1"
|
||||
bob <## "#biz: connection started"
|
||||
biz <## "#bob (Bob): accepting business address request..."
|
||||
bob <## "#biz: joining the group..."
|
||||
concurrently_
|
||||
(biz <## "#bob: bob_1 joined the group")
|
||||
(bob <## "#biz: you joined the group")
|
||||
groupChatLayout bob "biz" `shouldReturn` Just CLTerminal
|
||||
groupChatLayout biz "bob" `shouldReturn` Nothing
|
||||
alice ##> ("/c " <> fullLink)
|
||||
alice <## "connection request sent!"
|
||||
biz <## "#alice (Alice): accepting business address request..."
|
||||
alice <## "#biz: joining the group..."
|
||||
concurrently_
|
||||
(biz <## "#alice: alice_1 joined the group")
|
||||
(alice <## "#biz: you joined the group")
|
||||
groupChatLayout alice "biz" `shouldReturn` Just CLTerminal
|
||||
|
||||
testShortLinkInvitation :: HasCallStack => TestParams -> IO ()
|
||||
testShortLinkInvitation =
|
||||
testChatOpts2 testOptsNoFullLinks aliceProfile bobProfile $ \alice bob -> do
|
||||
|
||||
@@ -33,9 +33,11 @@ import Simplex.Chat.Store.Direct (getContact, getContactIdByName, getContactRequ
|
||||
import Simplex.Chat.Store.Groups (getGroupIdByName, getGroupMember, getGroupMemberIdByName)
|
||||
import Simplex.Chat.Store.NoteFolders (createNoteFolder)
|
||||
import Simplex.Chat.Store.Profiles (getUserContactProfiles)
|
||||
import Simplex.Chat.Store.Shared (getGroupInfo)
|
||||
import Simplex.Chat.Types
|
||||
import Simplex.Chat.Types.Preferences
|
||||
import Simplex.Chat.Types.Shared
|
||||
import Simplex.Chat.Types.UITheme (ChatLayout)
|
||||
import Simplex.FileTransfer.Description (FileSize (..))
|
||||
import Simplex.Messaging.Agent.Client (agentClientStore)
|
||||
import Simplex.Messaging.Agent.Store.AgentStore (maybeFirstRow, withTransaction)
|
||||
@@ -729,6 +731,20 @@ getTestCCContact cc contactId = do
|
||||
withCCUser cc $ \user ->
|
||||
runExceptT (getContact db (storeCxt chatController) user contactId) >>= either (fail . show) pure
|
||||
|
||||
contactChatLayout :: TestCC -> ContactName -> IO (Maybe ChatLayout)
|
||||
contactChatLayout cc cName =
|
||||
withCCTransaction cc $ \db ->
|
||||
withCCUser cc $ \user ->
|
||||
runExceptT (getContact db (storeCxt $ chatController cc) user =<< getContactIdByName db user cName)
|
||||
>>= either (fail . show) (\Contact {chatLayout} -> pure chatLayout)
|
||||
|
||||
groupChatLayout :: TestCC -> GroupName -> IO (Maybe ChatLayout)
|
||||
groupChatLayout cc gName =
|
||||
withCCTransaction cc $ \db ->
|
||||
withCCUser cc $ \user ->
|
||||
runExceptT (getGroupInfo db (storeCxt $ chatController cc) user =<< getGroupIdByName db user gName)
|
||||
>>= either (fail . show) (\GroupInfo {groupProfile = GroupProfile {chatLayout}} -> pure chatLayout)
|
||||
|
||||
contactBadgeHeader :: TestCC -> ContactName -> IO (Maybe (String, BadgeStatus))
|
||||
contactBadgeHeader cc cName =
|
||||
withCCTransaction cc $ \db ->
|
||||
|
||||
@@ -21,6 +21,7 @@ import Simplex.Chat.Protocol
|
||||
import Simplex.Chat.Types
|
||||
import Simplex.Chat.Types.Preferences
|
||||
import Simplex.Chat.Types.Shared
|
||||
import Simplex.Chat.Types.UITheme (ChatLayout (..))
|
||||
import Simplex.Messaging.Agent.Protocol
|
||||
import Simplex.Messaging.Compression (compress1)
|
||||
import qualified Simplex.Messaging.Crypto as C
|
||||
@@ -194,7 +195,7 @@ testProfile :: Profile
|
||||
testProfile = Profile {displayName = "alice", fullName = "Alice", shortDescr = Nothing, description = Nothing, image = Just (ImageData "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAgAAAAIAQMAAAD+wSzIAAAABlBMVEX///+/v7+jQ3Y5AAAADklEQVQI12P4AIX8EAgALgAD/aNpbtEAAAAASUVORK5CYII="), peerType = Nothing, contactLink = Nothing, preferences = testChatPreferences, badge = Nothing, contactDomain = Nothing}
|
||||
|
||||
testGroupProfile :: GroupProfile
|
||||
testGroupProfile = GroupProfile {displayName = "team", fullName = "Team", description = Nothing, shortDescr = Nothing, image = Nothing, publicGroup = Nothing, groupPreferences = testGroupPreferences, memberAdmission = Nothing}
|
||||
testGroupProfile = GroupProfile {displayName = "team", fullName = "Team", description = Nothing, shortDescr = Nothing, image = Nothing, publicGroup = Nothing, groupPreferences = testGroupPreferences, memberAdmission = Nothing, chatLayout = Nothing}
|
||||
|
||||
shortLinkDataTests :: Spec
|
||||
shortLinkDataTests = describe "Short link data encoding/decoding" $ do
|
||||
@@ -353,6 +354,12 @@ decodeChatMessageTest = describe "Chat message encoding/decoding" $ do
|
||||
it "x.grp.inv with group link id" $
|
||||
"{\"v\":\"9\",\"event\":\"x.grp.inv\",\"params\":{\"groupInvitation\":{\"connRequest\":\"simplex:/invitation#/?v=1&smp=smp%3A%2F%2F1234-w%3D%3D%40smp.simplex.im%3A5223%2F3456-w%3D%3D%23%2F%3Fv%3D1-4%26dh%3DMCowBQYDK2VuAyEAjiswwI3O_NlS8Fk3HJUW870EY2bAwmttMBsvRB9eV3o%253D&e2e=v%3D3%26x3dh%3DMEIwBQYDK2VvAzkAmKuSYeQ_m0SixPDS8Wq8VBaTS1cW-Lp0n0h4Diu-kUpR-qXx4SDJ32YGEFoGFGSbGPry5Ychr6U%3D%2CMEIwBQYDK2VvAzkAmKuSYeQ_m0SixPDS8Wq8VBaTS1cW-Lp0n0h4Diu-kUpR-qXx4SDJ32YGEFoGFGSbGPry5Ychr6U%3D\",\"invitedMember\":{\"memberRole\":\"member\",\"memberId\":\"BQYHCA==\"},\"groupProfile\":{\"fullName\":\"Team\",\"displayName\":\"team\",\"groupPreferences\":{\"reactions\":{\"enable\":\"on\"},\"voice\":{\"enable\":\"on\"}}},\"fromMember\":{\"memberRole\":\"admin\",\"memberId\":\"AQIDBA==\"}, \"groupLinkId\":\"AQIDBA==\"}}}"
|
||||
#==# XGrpInv GroupInvitation {fromMember = MemberIdRole (MemberId "\1\2\3\4") GRAdmin, fromMemberKey = Nothing, invitedMember = MemberIdRole (MemberId "\5\6\7\8") GRMember, connRequest = testConnReq, groupProfile = testGroupProfile, business = Nothing, groupLinkId = Just $ GroupLinkId "\1\2\3\4", groupSize = Nothing}
|
||||
it "x.grp.info with chat layout" $
|
||||
"{\"v\":\"9\",\"event\":\"x.grp.info\",\"params\":{\"groupProfile\":{\"fullName\":\"Team\",\"displayName\":\"team\",\"groupPreferences\":{\"reactions\":{\"enable\":\"on\"},\"voice\":{\"enable\":\"on\"}},\"chatLayout\":\"terminal\"}}}"
|
||||
#==# XGrpInfo (testGroupProfile {chatLayout = Just CLTerminal} :: GroupProfile)
|
||||
it "x.grp.info with unknown chat layout" $
|
||||
"{\"v\":\"9\",\"event\":\"x.grp.info\",\"params\":{\"groupProfile\":{\"fullName\":\"Team\",\"displayName\":\"team\",\"groupPreferences\":{\"reactions\":{\"enable\":\"on\"},\"voice\":{\"enable\":\"on\"}},\"chatLayout\":\"wide\"}}}"
|
||||
#==# XGrpInfo (testGroupProfile {chatLayout = Just $ CLUnknown "wide"} :: GroupProfile)
|
||||
it "x.grp.acpt without incognito profile" $
|
||||
"{\"v\":\"9\",\"event\":\"x.grp.acpt\",\"params\":{\"memberId\":\"AQIDBA==\"}}"
|
||||
#==# XGrpAcpt (MemberId "\1\2\3\4") Nothing Nothing
|
||||
|
||||
Reference in new issue
Block a user