core: change default for Disappearing Messages to "allow", mobile: support disabling without prohibiting (#2192)

* core: change default for Disappearing Messages to "allow", mobile: support disabling without prohibiting

* fix tests

* disable tests back in CI

* fixed tests 2

* remove enable

Co-authored-by: spaced4ndy <8711996+spaced4ndy@users.noreply.github.com>

---------

Co-authored-by: spaced4ndy <8711996+spaced4ndy@users.noreply.github.com>
This commit is contained in:
Evgeny Poberezkin 2023-04-17 19:13:10 +02:00 committed by GitHub
parent 9edbe2e589
commit 5f41cf3c52
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
10 changed files with 38 additions and 62 deletions

View File

@ -2460,7 +2460,7 @@ data class TimedMessagesPreference(
): ChatPreference { ): ChatPreference {
companion object { companion object {
val ttlValues: List<Int?> val ttlValues: List<Int?>
get() = listOf(30, 300, 3600, 8 * 3600, 86400, 7 * 86400, 30 * 86400) get() = listOf(30, 300, 3600, 8 * 3600, 86400, 7 * 86400, 30 * 86400, null)
fun ttlText(ttl: Int?): String { fun ttlText(ttl: Int?): String {
ttl ?: return generalGetString(R.string.feature_off) ttl ?: return generalGetString(R.string.feature_off)
@ -2593,12 +2593,6 @@ sealed class ContactUserPref {
@Serializable @SerialName("user") data class User(val preference: SimpleChatPreference): ContactUserPref() { @Serializable @SerialName("user") data class User(val preference: SimpleChatPreference): ContactUserPref() {
override val pref get() = preference override val pref get() = preference
} }
val contactOverride: SimpleChatPreference?
get() = when(this) {
is Contact -> pref
is User -> null
}
} }
@Serializable @Serializable
@ -2613,12 +2607,6 @@ sealed class ContactUserPrefTimed {
@Serializable @SerialName("user") data class User(val preference: TimedMessagesPreference): ContactUserPrefTimed() { @Serializable @SerialName("user") data class User(val preference: TimedMessagesPreference): ContactUserPrefTimed() {
override val pref get() = preference override val pref get() = preference
} }
val contactOverride: TimedMessagesPreference?
get() = when(this) {
is Contact -> pref
is User -> null
}
} }
interface Feature { interface Feature {
@ -2831,7 +2819,7 @@ data class ContactFeaturesAllowed(
fun contactUserPrefsToFeaturesAllowed(contactUserPreferences: ContactUserPreferences): ContactFeaturesAllowed { fun contactUserPrefsToFeaturesAllowed(contactUserPreferences: ContactUserPreferences): ContactFeaturesAllowed {
val pref = contactUserPreferences.timedMessages.userPreference val pref = contactUserPreferences.timedMessages.userPreference
val allow = pref.contactOverride?.allow val allow = pref.pref.allow
return ContactFeaturesAllowed( return ContactFeaturesAllowed(
timedMessagesAllowed = allow == FeatureAllowed.YES || allow == FeatureAllowed.ALWAYS, timedMessagesAllowed = allow == FeatureAllowed.YES || allow == FeatureAllowed.ALWAYS,
timedMessagesTTL = pref.pref.ttl, timedMessagesTTL = pref.pref.ttl,

View File

@ -88,7 +88,7 @@ private fun ContactPreferencesLayout(
AppBarTitle(stringResource(R.string.contact_preferences)) AppBarTitle(stringResource(R.string.contact_preferences))
val timedMessages: MutableState<Boolean> = remember(featuresAllowed) { mutableStateOf(featuresAllowed.timedMessagesAllowed) } val timedMessages: MutableState<Boolean> = remember(featuresAllowed) { mutableStateOf(featuresAllowed.timedMessagesAllowed) }
val onTTLUpdated = { ttl: Int? -> val onTTLUpdated = { ttl: Int? ->
applyPrefs(featuresAllowed.copy(timedMessagesTTL = ttl ?: 86400)) applyPrefs(featuresAllowed.copy(timedMessagesTTL = ttl))
} }
TimedMessagesFeatureSection(featuresAllowed, contact.mergedPreferences.timedMessages, timedMessages, onTTLUpdated) { allowed, ttl -> TimedMessagesFeatureSection(featuresAllowed, contact.mergedPreferences.timedMessages, timedMessages, onTTLUpdated) { allowed, ttl ->
applyPrefs(featuresAllowed.copy(timedMessagesAllowed = allowed, timedMessagesTTL = ttl ?: currentFeaturesAllowed.timedMessagesTTL)) applyPrefs(featuresAllowed.copy(timedMessagesAllowed = allowed, timedMessagesTTL = ttl ?: currentFeaturesAllowed.timedMessagesTTL))

View File

@ -71,7 +71,7 @@ struct ChatListView: View {
.toolbar { .toolbar {
ToolbarItem(placement: .navigationBarLeading) { ToolbarItem(placement: .navigationBarLeading) {
Button { Button {
if chatModel.users.filter { u in u.user.activeUser || !u.user.hidden }.count > 1 { if chatModel.users.filter({ u in u.user.activeUser || !u.user.hidden }).count > 1 {
withAnimation { withAnimation {
userPickerVisible.toggle() userPickerVisible.toggle()
} }

View File

@ -248,7 +248,7 @@ public struct TimedMessagesPreference: Preference {
} }
public static var ttlValues: [Int?] { public static var ttlValues: [Int?] {
[30, 300, 3600, 8 * 3600, 86400, 7 * 86400, 30 * 86400] [30, 300, 3600, 8 * 3600, 86400, 7 * 86400, 30 * 86400, nil]
} }
public static func ttlText(_ ttl: Int?) -> String { public static func ttlText(_ ttl: Int?) -> String {
@ -391,13 +391,6 @@ public enum ContactUserPref<P: Preference>: Decodable {
case let .user(preference): return preference case let .user(preference): return preference
} }
} }
var contactOverride: P? {
switch self {
case let .contact(preference): return preference
case .user: return nil
}
}
} }
public protocol Feature { public protocol Feature {
@ -671,7 +664,7 @@ public struct ContactFeaturesAllowed: Equatable {
public func contactUserPrefsToFeaturesAllowed(_ contactUserPreferences: ContactUserPreferences) -> ContactFeaturesAllowed { public func contactUserPrefsToFeaturesAllowed(_ contactUserPreferences: ContactUserPreferences) -> ContactFeaturesAllowed {
let pref = contactUserPreferences.timedMessages.userPreference let pref = contactUserPreferences.timedMessages.userPreference
let allow = pref.contactOverride?.allow let allow = pref.preference.allow
return ContactFeaturesAllowed( return ContactFeaturesAllowed(
timedMessagesAllowed: allow == .yes || allow == .always, timedMessagesAllowed: allow == .yes || allow == .always,
timedMessagesTTL: pref.preference.ttl, timedMessagesTTL: pref.preference.ttl,
@ -2129,7 +2122,7 @@ public enum CIContent: Decodable, ItemContent {
case let .sndCall(status, duration): return status.text(duration) case let .sndCall(status, duration): return status.text(duration)
case let .rcvCall(status, duration): return status.text(duration) case let .rcvCall(status, duration): return status.text(duration)
case let .rcvIntegrityError(msgError): return msgError.text case let .rcvIntegrityError(msgError): return msgError.text
case let .rcvDecryptionError(msgDecryptError, msgCount): return msgDecryptError.text case let .rcvDecryptionError(msgDecryptError, _): return msgDecryptError.text
case let .rcvGroupInvitation(groupInvitation, _): return groupInvitation.text case let .rcvGroupInvitation(groupInvitation, _): return groupInvitation.text
case let .sndGroupInvitation(groupInvitation, _): return groupInvitation.text case let .sndGroupInvitation(groupInvitation, _): return groupInvitation.text
case let .rcvGroupEvent(rcvGroupEvent): return rcvGroupEvent.text case let .rcvGroupEvent(rcvGroupEvent): return rcvGroupEvent.text

View File

@ -661,7 +661,7 @@ toChatPrefs FullPreferences {fullDelete, voice, timedMessages, calls} =
defaultChatPrefs :: FullPreferences defaultChatPrefs :: FullPreferences
defaultChatPrefs = defaultChatPrefs =
FullPreferences FullPreferences
{ timedMessages = TimedMessagesPreference {allow = FANo, ttl = Nothing}, { timedMessages = TimedMessagesPreference {allow = FAYes, ttl = Nothing},
fullDelete = FullDeletePreference {allow = FANo}, fullDelete = FullDeletePreference {allow = FANo},
-- receipts = SimplePreference {allow = FANo}, -- receipts = SimplePreference {allow = FANo},
voice = VoicePreference {allow = FAYes}, voice = VoicePreference {allow = FAYes},
@ -988,7 +988,7 @@ prefStateText feature allowed param = case allowed of
featureStateText :: ChatFeature -> PrefEnabled -> Maybe Int -> Text featureStateText :: ChatFeature -> PrefEnabled -> Maybe Int -> Text
featureStateText feature enabled param = featureStateText feature enabled param =
chatFeatureNameText feature <> ": " <> prefEnabledToText enabled <> case enabled of chatFeatureNameText feature <> ": " <> prefEnabledToText feature enabled param <> case enabled of
PrefEnabled {forUser = True} -> paramText_ feature param PrefEnabled {forUser = True} -> paramText_ feature param
_ -> "" _ -> ""
@ -997,12 +997,16 @@ paramText_ feature param = case feature of
CFTimedMessages -> maybe "" (\p -> " (" <> timedTTLText p <> ")") param CFTimedMessages -> maybe "" (\p -> " (" <> timedTTLText p <> ")") param
_ -> "" _ -> ""
prefEnabledToText :: PrefEnabled -> Text prefEnabledToText :: ChatFeature -> PrefEnabled -> Maybe Int -> Text
prefEnabledToText = \case prefEnabledToText f enabled param = case enabled of
PrefEnabled True True -> "enabled" PrefEnabled True True -> enabledStr
PrefEnabled False False -> "off" PrefEnabled False False -> "off"
PrefEnabled {forUser = True, forContact = False} -> "enabled for you" PrefEnabled {forUser = True, forContact = False} -> enabledStr <> " for you"
PrefEnabled {forUser = False, forContact = True} -> "enabled for contact" PrefEnabled {forUser = False, forContact = True} -> enabledStr <> " for contact"
where
enabledStr = case f of
CFTimedMessages -> if isJust param then "enabled" else "allowed"
_ -> "enabled"
preferenceText :: forall f. FeatureI f => FeaturePreference f -> Text preferenceText :: forall f. FeatureI f => FeaturePreference f -> Text
preferenceText p = preferenceText p =

View File

@ -900,7 +900,7 @@ viewContactPreferences user ct ct' cups =
viewContactPref :: FullPreferences -> FullPreferences -> Maybe Preferences -> ContactUserPreferences -> AChatFeature -> Maybe StyledString viewContactPref :: FullPreferences -> FullPreferences -> Maybe Preferences -> ContactUserPreferences -> AChatFeature -> Maybe StyledString
viewContactPref userPrefs userPrefs' ctPrefs cups (ACF f) viewContactPref userPrefs userPrefs' ctPrefs cups (ACF f)
| userPref == userPref' && ctPref == contactPreference = Nothing | userPref == userPref' && ctPref == contactPreference = Nothing
| otherwise = Just . plain $ chatFeatureNameText' f <> ": " <> prefEnabledToText enabled <> " (you allow: " <> countactUserPrefText userPreference <> ", contact allows: " <> preferenceText contactPreference <> ")" | otherwise = Just . plain $ chatFeatureNameText' f <> ": " <> prefEnabledToText (chatFeature f) enabled (prefParam userPref') <> " (you allow: " <> countactUserPrefText userPreference <> ", contact allows: " <> preferenceText contactPreference <> ")"
where where
userPref = getPreference f userPrefs userPref = getPreference f userPrefs
userPref' = getPreference f userPrefs' userPref' = getPreference f userPrefs'

View File

@ -1530,14 +1530,9 @@ testUsersTimedMessages tmp = do
aliceName <- userName alice aliceName <- userName alice
alice ##> ("/_set prefs @" <> bobId <> " {\"timedMessages\": {\"allow\": \"yes\", \"ttl\": " <> ttl <> "}}") alice ##> ("/_set prefs @" <> bobId <> " {\"timedMessages\": {\"allow\": \"yes\", \"ttl\": " <> ttl <> "}}")
alice <## "you updated preferences for bob:" alice <## "you updated preferences for bob:"
alice <## ("Disappearing messages: off (you allow: yes (" <> ttl <> " sec), contact allows: no)") alice <## ("Disappearing messages: enabled (you allow: yes (" <> ttl <> " sec), contact allows: yes)")
bob <## (aliceName <> " updated preferences for you:") bob <## (aliceName <> " updated preferences for you:")
bob <## ("Disappearing messages: off (you allow: no, contact allows: yes (" <> ttl <> " sec))")
bob ##> ("/set disappear @" <> aliceName <> " yes")
bob <## ("you updated preferences for " <> aliceName <> ":")
bob <## ("Disappearing messages: enabled (you allow: yes (" <> ttl <> " sec), contact allows: yes (" <> ttl <> " sec))") bob <## ("Disappearing messages: enabled (you allow: yes (" <> ttl <> " sec), contact allows: yes (" <> ttl <> " sec))")
alice <## "bob updated preferences for you:"
alice <## ("Disappearing messages: enabled (you allow: yes (" <> ttl <> " sec), contact allows: yes (" <> ttl <> " sec))")
alice #$> ("/clear bob", id, "bob: all messages are removed locally ONLY") -- to remove feature items alice #$> ("/clear bob", id, "bob: all messages are removed locally ONLY") -- to remove feature items
testUserPrivacy :: HasCallStack => FilePath -> IO () testUserPrivacy :: HasCallStack => FilePath -> IO ()
@ -1582,7 +1577,7 @@ testUserPrivacy =
-- hidden message is saved -- hidden message is saved
alice ##> "/tail" alice ##> "/tail"
alice alice
<##? [ "bob> Disappearing messages: off", <##? [ "bob> Disappearing messages: allowed",
"bob> Full deletion: off", "bob> Full deletion: off",
"bob> Voice messages: enabled", "bob> Voice messages: enabled",
"bob> Audio/video calls: enabled", "bob> Audio/video calls: enabled",

View File

@ -976,7 +976,7 @@ testSetContactPrefs = testChat2 aliceProfile bobProfile $
alice ##> "/_set prefs @2 {}" alice ##> "/_set prefs @2 {}"
alice <## "your preferences for bob did not change" alice <## "your preferences for bob did not change"
(bob </) (bob </)
let startFeatures = [(0, "Disappearing messages: off"), (0, "Full deletion: off"), (0, "Voice messages: off"), (0, "Audio/video calls: enabled")] let startFeatures = [(0, "Disappearing messages: allowed"), (0, "Full deletion: off"), (0, "Voice messages: off"), (0, "Audio/video calls: enabled")]
alice #$> ("/_get chat @2 count=100", chat, startFeatures) alice #$> ("/_get chat @2 count=100", chat, startFeatures)
bob #$> ("/_get chat @2 count=100", chat, startFeatures) bob #$> ("/_get chat @2 count=100", chat, startFeatures)
let sendVoice = "/_send @2 json {\"filePath\": \"test.txt\", \"msgContent\": {\"type\": \"voice\", \"text\": \"\", \"duration\": 10}}" let sendVoice = "/_send @2 json {\"filePath\": \"test.txt\", \"msgContent\": {\"type\": \"voice\", \"text\": \"\", \"duration\": 10}}"
@ -1221,25 +1221,22 @@ testEnableTimedMessagesContact =
connectUsers alice bob connectUsers alice bob
alice ##> "/_set prefs @2 {\"timedMessages\": {\"allow\": \"yes\", \"ttl\": 1}}" alice ##> "/_set prefs @2 {\"timedMessages\": {\"allow\": \"yes\", \"ttl\": 1}}"
alice <## "you updated preferences for bob:" alice <## "you updated preferences for bob:"
alice <## "Disappearing messages: off (you allow: yes (1 sec), contact allows: no)" alice <## "Disappearing messages: enabled (you allow: yes (1 sec), contact allows: yes)"
bob <## "alice updated preferences for you:" bob <## "alice updated preferences for you:"
bob <## "Disappearing messages: off (you allow: no, contact allows: yes (1 sec))"
bob ##> "/set disappear @alice yes"
bob <## "you updated preferences for alice:"
bob <## "Disappearing messages: enabled (you allow: yes (1 sec), contact allows: yes (1 sec))" bob <## "Disappearing messages: enabled (you allow: yes (1 sec), contact allows: yes (1 sec))"
alice <## "bob updated preferences for you:" bob ##> "/set disappear @alice yes"
alice <## "Disappearing messages: enabled (you allow: yes (1 sec), contact allows: yes (1 sec))" bob <## "your preferences for alice did not change"
alice <##> bob alice <##> bob
threadDelay 500000 threadDelay 500000
alice #$> ("/_get chat @2 count=100", chat, chatFeatures <> [(1, "you offered Disappearing messages (1 sec)"), (0, "Disappearing messages: enabled (1 sec)"), (1, "hi"), (0, "hey")]) alice #$> ("/_get chat @2 count=100", chat, chatFeatures <> [(1, "Disappearing messages: enabled (1 sec)"), (1, "hi"), (0, "hey")])
bob #$> ("/_get chat @2 count=100", chat, chatFeatures <> [(0, "offered Disappearing messages (1 sec)"), (1, "Disappearing messages: enabled (1 sec)"), (0, "hi"), (1, "hey")]) bob #$> ("/_get chat @2 count=100", chat, chatFeatures <> [(0, "Disappearing messages: enabled (1 sec)"), (0, "hi"), (1, "hey")])
threadDelay 1000000 threadDelay 1000000
alice <## "timed message deleted: hi" alice <## "timed message deleted: hi"
alice <## "timed message deleted: hey" alice <## "timed message deleted: hey"
bob <## "timed message deleted: hi" bob <## "timed message deleted: hi"
bob <## "timed message deleted: hey" bob <## "timed message deleted: hey"
alice #$> ("/_get chat @2 count=100", chat, chatFeatures <> [(1, "you offered Disappearing messages (1 sec)"), (0, "Disappearing messages: enabled (1 sec)")]) alice #$> ("/_get chat @2 count=100", chat, chatFeatures <> [(1, "Disappearing messages: enabled (1 sec)")])
bob #$> ("/_get chat @2 count=100", chat, chatFeatures <> [(0, "offered Disappearing messages (1 sec)"), (1, "Disappearing messages: enabled (1 sec)")]) bob #$> ("/_get chat @2 count=100", chat, chatFeatures <> [(0, "Disappearing messages: enabled (1 sec)")])
-- turn off, messages are not disappearing -- turn off, messages are not disappearing
bob ##> "/set disappear @alice no" bob ##> "/set disappear @alice no"
bob <## "you updated preferences for alice:" bob <## "you updated preferences for alice:"
@ -1248,8 +1245,8 @@ testEnableTimedMessagesContact =
alice <## "Disappearing messages: off (you allow: yes (1 sec), contact allows: no)" alice <## "Disappearing messages: off (you allow: yes (1 sec), contact allows: no)"
alice <##> bob alice <##> bob
threadDelay 1500000 threadDelay 1500000
alice #$> ("/_get chat @2 count=100", chat, chatFeatures <> [(1, "you offered Disappearing messages (1 sec)"), (0, "Disappearing messages: enabled (1 sec)"), (0, "Disappearing messages: off"), (1, "hi"), (0, "hey")]) alice #$> ("/_get chat @2 count=100", chat, chatFeatures <> [(1, "Disappearing messages: enabled (1 sec)"), (0, "Disappearing messages: off"), (1, "hi"), (0, "hey")])
bob #$> ("/_get chat @2 count=100", chat, chatFeatures <> [(0, "offered Disappearing messages (1 sec)"), (1, "Disappearing messages: enabled (1 sec)"), (1, "Disappearing messages: off"), (0, "hi"), (1, "hey")]) bob #$> ("/_get chat @2 count=100", chat, chatFeatures <> [(0, "Disappearing messages: enabled (1 sec)"), (1, "Disappearing messages: off"), (0, "hi"), (1, "hey")])
-- test api -- test api
bob ##> "/set disappear @alice yes 30s" bob ##> "/set disappear @alice yes 30s"
bob <## "you updated preferences for alice:" bob <## "you updated preferences for alice:"
@ -1317,8 +1314,7 @@ testTimedMessagesEnabledGlobally =
testChat2 aliceProfile bobProfile $ testChat2 aliceProfile bobProfile $
\alice bob -> do \alice bob -> do
alice ##> "/set disappear yes" alice ##> "/set disappear yes"
alice <## "updated preferences:" alice <## "user profile did not change"
alice <## "Disappearing messages allowed: yes"
connectUsers alice bob connectUsers alice bob
bob ##> "/_set prefs @2 {\"timedMessages\": {\"allow\": \"yes\", \"ttl\": 1}}" bob ##> "/_set prefs @2 {\"timedMessages\": {\"allow\": \"yes\", \"ttl\": 1}}"
bob <## "you updated preferences for alice:" bob <## "you updated preferences for alice:"

View File

@ -183,7 +183,7 @@ chatFeaturesF :: [((Int, String), Maybe String)]
chatFeaturesF = map (\(a, _, c) -> (a, c)) chatFeatures'' chatFeaturesF = map (\(a, _, c) -> (a, c)) chatFeatures''
chatFeatures'' :: [((Int, String), Maybe (Int, String), Maybe String)] chatFeatures'' :: [((Int, String), Maybe (Int, String), Maybe String)]
chatFeatures'' = [((0, "Disappearing messages: off"), Nothing, Nothing), ((0, "Full deletion: off"), Nothing, Nothing), ((0, "Voice messages: enabled"), Nothing, Nothing), ((0, "Audio/video calls: enabled"), Nothing, Nothing)] chatFeatures'' = [((0, "Disappearing messages: allowed"), Nothing, Nothing), ((0, "Full deletion: off"), Nothing, Nothing), ((0, "Voice messages: enabled"), Nothing, Nothing), ((0, "Audio/video calls: enabled"), Nothing, Nothing)]
lastChatFeature :: String lastChatFeature :: String
lastChatFeature = snd $ last chatFeatures lastChatFeature = snd $ last chatFeatures

View File

@ -26,16 +26,16 @@ noActiveUser = "{\"resp\":{\"type\":\"chatCmdError\",\"chatError\":{\"type\":\"e
activeUserExists :: String activeUserExists :: String
#if defined(darwin_HOST_OS) && defined(swiftJSON) #if defined(darwin_HOST_OS) && defined(swiftJSON)
activeUserExists = "{\"resp\":{\"chatCmdError\":{\"user_\":{\"userId\":1,\"agentUserId\":\"1\",\"userContactId\":1,\"localDisplayName\":\"alice\",\"profile\":{\"profileId\":1,\"displayName\":\"alice\",\"fullName\":\"Alice\",\"localAlias\":\"\"},\"fullPreferences\":{\"timedMessages\":{\"allow\":\"no\"},\"fullDelete\":{\"allow\":\"no\"},\"voice\":{\"allow\":\"yes\"},\"calls\":{\"allow\":\"yes\"}},\"activeUser\":true,\"showNtfs\":true},\"chatError\":{\"error\":{\"errorType\":{\"userExists\":{\"contactName\":\"alice\"}}}}}}}" activeUserExists = "{\"resp\":{\"chatCmdError\":{\"user_\":{\"userId\":1,\"agentUserId\":\"1\",\"userContactId\":1,\"localDisplayName\":\"alice\",\"profile\":{\"profileId\":1,\"displayName\":\"alice\",\"fullName\":\"Alice\",\"localAlias\":\"\"},\"fullPreferences\":{\"timedMessages\":{\"allow\":\"yes\"},\"fullDelete\":{\"allow\":\"no\"},\"voice\":{\"allow\":\"yes\"},\"calls\":{\"allow\":\"yes\"}},\"activeUser\":true,\"showNtfs\":true},\"chatError\":{\"error\":{\"errorType\":{\"userExists\":{\"contactName\":\"alice\"}}}}}}}"
#else #else
activeUserExists = "{\"resp\":{\"type\":\"chatCmdError\",\"user_\":{\"userId\":1,\"agentUserId\":\"1\",\"userContactId\":1,\"localDisplayName\":\"alice\",\"profile\":{\"profileId\":1,\"displayName\":\"alice\",\"fullName\":\"Alice\",\"localAlias\":\"\"},\"fullPreferences\":{\"timedMessages\":{\"allow\":\"no\"},\"fullDelete\":{\"allow\":\"no\"},\"voice\":{\"allow\":\"yes\"},\"calls\":{\"allow\":\"yes\"}},\"activeUser\":true,\"showNtfs\":true},\"chatError\":{\"type\":\"error\",\"errorType\":{\"type\":\"userExists\",\"contactName\":\"alice\"}}}}" activeUserExists = "{\"resp\":{\"type\":\"chatCmdError\",\"user_\":{\"userId\":1,\"agentUserId\":\"1\",\"userContactId\":1,\"localDisplayName\":\"alice\",\"profile\":{\"profileId\":1,\"displayName\":\"alice\",\"fullName\":\"Alice\",\"localAlias\":\"\"},\"fullPreferences\":{\"timedMessages\":{\"allow\":\"yes\"},\"fullDelete\":{\"allow\":\"no\"},\"voice\":{\"allow\":\"yes\"},\"calls\":{\"allow\":\"yes\"}},\"activeUser\":true,\"showNtfs\":true},\"chatError\":{\"type\":\"error\",\"errorType\":{\"type\":\"userExists\",\"contactName\":\"alice\"}}}}"
#endif #endif
activeUser :: String activeUser :: String
#if defined(darwin_HOST_OS) && defined(swiftJSON) #if defined(darwin_HOST_OS) && defined(swiftJSON)
activeUser = "{\"resp\":{\"activeUser\":{\"user\":{\"userId\":1,\"agentUserId\":\"1\",\"userContactId\":1,\"localDisplayName\":\"alice\",\"profile\":{\"profileId\":1,\"displayName\":\"alice\",\"fullName\":\"Alice\",\"localAlias\":\"\"},\"fullPreferences\":{\"timedMessages\":{\"allow\":\"no\"},\"fullDelete\":{\"allow\":\"no\"},\"voice\":{\"allow\":\"yes\"},\"calls\":{\"allow\":\"yes\"}},\"activeUser\":true,\"showNtfs\":true}}}}" activeUser = "{\"resp\":{\"activeUser\":{\"user\":{\"userId\":1,\"agentUserId\":\"1\",\"userContactId\":1,\"localDisplayName\":\"alice\",\"profile\":{\"profileId\":1,\"displayName\":\"alice\",\"fullName\":\"Alice\",\"localAlias\":\"\"},\"fullPreferences\":{\"timedMessages\":{\"allow\":\"yes\"},\"fullDelete\":{\"allow\":\"no\"},\"voice\":{\"allow\":\"yes\"},\"calls\":{\"allow\":\"yes\"}},\"activeUser\":true,\"showNtfs\":true}}}}"
#else #else
activeUser = "{\"resp\":{\"type\":\"activeUser\",\"user\":{\"userId\":1,\"agentUserId\":\"1\",\"userContactId\":1,\"localDisplayName\":\"alice\",\"profile\":{\"profileId\":1,\"displayName\":\"alice\",\"fullName\":\"Alice\",\"localAlias\":\"\"},\"fullPreferences\":{\"timedMessages\":{\"allow\":\"no\"},\"fullDelete\":{\"allow\":\"no\"},\"voice\":{\"allow\":\"yes\"},\"calls\":{\"allow\":\"yes\"}},\"activeUser\":true,\"showNtfs\":true}}}" activeUser = "{\"resp\":{\"type\":\"activeUser\",\"user\":{\"userId\":1,\"agentUserId\":\"1\",\"userContactId\":1,\"localDisplayName\":\"alice\",\"profile\":{\"profileId\":1,\"displayName\":\"alice\",\"fullName\":\"Alice\",\"localAlias\":\"\"},\"fullPreferences\":{\"timedMessages\":{\"allow\":\"yes\"},\"fullDelete\":{\"allow\":\"no\"},\"voice\":{\"allow\":\"yes\"},\"calls\":{\"allow\":\"yes\"}},\"activeUser\":true,\"showNtfs\":true}}}"
#endif #endif
chatStarted :: String chatStarted :: String
@ -74,7 +74,7 @@ pendingSubSummary = "{\"resp\":{\"type\":\"pendingSubSummary\"," <> userJSON <>
#endif #endif
userJSON :: String userJSON :: String
userJSON = "\"user\":{\"userId\":1,\"agentUserId\":\"1\",\"userContactId\":1,\"localDisplayName\":\"alice\",\"profile\":{\"profileId\":1,\"displayName\":\"alice\",\"fullName\":\"Alice\",\"localAlias\":\"\"},\"fullPreferences\":{\"timedMessages\":{\"allow\":\"no\"},\"fullDelete\":{\"allow\":\"no\"},\"voice\":{\"allow\":\"yes\"},\"calls\":{\"allow\":\"yes\"}},\"activeUser\":true,\"showNtfs\":true}" userJSON = "\"user\":{\"userId\":1,\"agentUserId\":\"1\",\"userContactId\":1,\"localDisplayName\":\"alice\",\"profile\":{\"profileId\":1,\"displayName\":\"alice\",\"fullName\":\"Alice\",\"localAlias\":\"\"},\"fullPreferences\":{\"timedMessages\":{\"allow\":\"yes\"},\"fullDelete\":{\"allow\":\"no\"},\"voice\":{\"allow\":\"yes\"},\"calls\":{\"allow\":\"yes\"}},\"activeUser\":true,\"showNtfs\":true}"
parsedMarkdown :: String parsedMarkdown :: String
#if defined(darwin_HOST_OS) && defined(swiftJSON) #if defined(darwin_HOST_OS) && defined(swiftJSON)