mirror of
https://github.com/simplex-chat/simplex-chat.git
synced 2025-06-29 04:39:53 +00:00
core, ui: report preference (#5620)
* core: report preference * fix tests * ios: disable reports toggle until 6.4 * android, desktop: reports preference * ui: section * boolean
This commit is contained in:
parent
ff35643533
commit
205ced1c1d
19 changed files with 177 additions and 54 deletions
|
@ -1354,7 +1354,11 @@ struct ChatView: View {
|
|||
if ci.chatDir != .groupSnd {
|
||||
if let (groupInfo, _) = ci.memberToModerate(chat.chatInfo) {
|
||||
moderateButton(ci, groupInfo)
|
||||
} else if ci.meta.itemDeleted == nil, case let .group(gInfo) = chat.chatInfo, gInfo.membership.memberRole == .member, !live, composeState.voiceMessageRecordingState == .noRecording {
|
||||
} else if ci.meta.itemDeleted == nil && chat.groupFeatureEnabled(.reports),
|
||||
case let .group(gInfo) = chat.chatInfo,
|
||||
gInfo.membership.memberRole == .member
|
||||
&& !live
|
||||
&& composeState.voiceMessageRecordingState == .noRecording {
|
||||
reportButton(ci)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -37,6 +37,7 @@ struct GroupPreferencesView: View {
|
|||
featureSection(.voice, $preferences.voice.enable, $preferences.voice.role)
|
||||
featureSection(.files, $preferences.files.enable, $preferences.files.role)
|
||||
featureSection(.simplexLinks, $preferences.simplexLinks.enable, $preferences.simplexLinks.role)
|
||||
featureSection(.reports, $preferences.reports.enable)
|
||||
featureSection(.history, $preferences.history.enable)
|
||||
|
||||
if groupInfo.isOwner {
|
||||
|
@ -89,6 +90,7 @@ struct GroupPreferencesView: View {
|
|||
settingsRow(icon, color: color) {
|
||||
Toggle(feature.text, isOn: enable)
|
||||
}
|
||||
.disabled(feature == .reports) // remove in 6.4
|
||||
if timedOn {
|
||||
DropdownCustomTimePicker(
|
||||
selection: $preferences.timedMessages.ttl,
|
||||
|
|
|
@ -711,6 +711,7 @@ public enum GroupFeature: String, Decodable, Feature, Hashable {
|
|||
case voice
|
||||
case files
|
||||
case simplexLinks
|
||||
case reports
|
||||
case history
|
||||
|
||||
public var id: Self { self }
|
||||
|
@ -731,6 +732,7 @@ public enum GroupFeature: String, Decodable, Feature, Hashable {
|
|||
case .voice: true
|
||||
case .files: true
|
||||
case .simplexLinks: true
|
||||
case .reports: false
|
||||
case .history: false
|
||||
}
|
||||
}
|
||||
|
@ -744,6 +746,7 @@ public enum GroupFeature: String, Decodable, Feature, Hashable {
|
|||
case .voice: return NSLocalizedString("Voice messages", comment: "chat feature")
|
||||
case .files: return NSLocalizedString("Files and media", comment: "chat feature")
|
||||
case .simplexLinks: return NSLocalizedString("SimpleX links", comment: "chat feature")
|
||||
case .reports: return NSLocalizedString("Member reports", comment: "chat feature")
|
||||
case .history: return NSLocalizedString("Visible history", comment: "chat feature")
|
||||
}
|
||||
}
|
||||
|
@ -757,6 +760,7 @@ public enum GroupFeature: String, Decodable, Feature, Hashable {
|
|||
case .voice: return "mic"
|
||||
case .files: return "doc"
|
||||
case .simplexLinks: return "link.circle"
|
||||
case .reports: return "flag"
|
||||
case .history: return "clock"
|
||||
}
|
||||
}
|
||||
|
@ -770,6 +774,7 @@ public enum GroupFeature: String, Decodable, Feature, Hashable {
|
|||
case .voice: return "mic.fill"
|
||||
case .files: return "doc.fill"
|
||||
case .simplexLinks: return "link.circle.fill"
|
||||
case .reports: return "flag.fill"
|
||||
case .history: return "clock.fill"
|
||||
}
|
||||
}
|
||||
|
@ -819,6 +824,11 @@ public enum GroupFeature: String, Decodable, Feature, Hashable {
|
|||
case .on: return "Allow to send SimpleX links."
|
||||
case .off: return "Prohibit sending SimpleX links."
|
||||
}
|
||||
case .reports:
|
||||
switch enabled {
|
||||
case .on: return "Allow to report messsages to moderators."
|
||||
case .off: return "Prohibit reporting messages to moderators."
|
||||
}
|
||||
case .history:
|
||||
switch enabled {
|
||||
case .on: return "Send up to 100 last messages to new members."
|
||||
|
@ -862,6 +872,11 @@ public enum GroupFeature: String, Decodable, Feature, Hashable {
|
|||
case .on: return "Members can send SimpleX links."
|
||||
case .off: return "SimpleX links are prohibited."
|
||||
}
|
||||
case .reports:
|
||||
switch enabled {
|
||||
case .on: return "Members can report messsages to moderators."
|
||||
case .off: return "Reporting messages to moderators is prohibited."
|
||||
}
|
||||
case .history:
|
||||
switch enabled {
|
||||
case .on: return "Up to 100 last messages are sent to new members."
|
||||
|
@ -1007,6 +1022,7 @@ public struct FullGroupPreferences: Decodable, Equatable, Hashable {
|
|||
public var voice: RoleGroupPreference
|
||||
public var files: RoleGroupPreference
|
||||
public var simplexLinks: RoleGroupPreference
|
||||
public var reports: GroupPreference
|
||||
public var history: GroupPreference
|
||||
|
||||
public init(
|
||||
|
@ -1017,6 +1033,7 @@ public struct FullGroupPreferences: Decodable, Equatable, Hashable {
|
|||
voice: RoleGroupPreference,
|
||||
files: RoleGroupPreference,
|
||||
simplexLinks: RoleGroupPreference,
|
||||
reports: GroupPreference,
|
||||
history: GroupPreference
|
||||
) {
|
||||
self.timedMessages = timedMessages
|
||||
|
@ -1026,6 +1043,7 @@ public struct FullGroupPreferences: Decodable, Equatable, Hashable {
|
|||
self.voice = voice
|
||||
self.files = files
|
||||
self.simplexLinks = simplexLinks
|
||||
self.reports = reports
|
||||
self.history = history
|
||||
}
|
||||
|
||||
|
@ -1037,6 +1055,7 @@ public struct FullGroupPreferences: Decodable, Equatable, Hashable {
|
|||
voice: RoleGroupPreference(enable: .on, role: nil),
|
||||
files: RoleGroupPreference(enable: .on, role: nil),
|
||||
simplexLinks: RoleGroupPreference(enable: .on, role: nil),
|
||||
reports: GroupPreference(enable: .on),
|
||||
history: GroupPreference(enable: .on)
|
||||
)
|
||||
}
|
||||
|
@ -1049,6 +1068,7 @@ public struct GroupPreferences: Codable, Hashable {
|
|||
public var voice: RoleGroupPreference?
|
||||
public var files: RoleGroupPreference?
|
||||
public var simplexLinks: RoleGroupPreference?
|
||||
public var reports: GroupPreference?
|
||||
public var history: GroupPreference?
|
||||
|
||||
public init(
|
||||
|
@ -1059,6 +1079,7 @@ public struct GroupPreferences: Codable, Hashable {
|
|||
voice: RoleGroupPreference? = nil,
|
||||
files: RoleGroupPreference? = nil,
|
||||
simplexLinks: RoleGroupPreference? = nil,
|
||||
reports: GroupPreference? = nil,
|
||||
history: GroupPreference? = nil
|
||||
) {
|
||||
self.timedMessages = timedMessages
|
||||
|
@ -1068,6 +1089,7 @@ public struct GroupPreferences: Codable, Hashable {
|
|||
self.voice = voice
|
||||
self.files = files
|
||||
self.simplexLinks = simplexLinks
|
||||
self.reports = reports
|
||||
self.history = history
|
||||
}
|
||||
|
||||
|
@ -1079,6 +1101,7 @@ public struct GroupPreferences: Codable, Hashable {
|
|||
voice: RoleGroupPreference(enable: .on, role: nil),
|
||||
files: RoleGroupPreference(enable: .on, role: nil),
|
||||
simplexLinks: RoleGroupPreference(enable: .on, role: nil),
|
||||
reports: GroupPreference(enable: .on),
|
||||
history: GroupPreference(enable: .on)
|
||||
)
|
||||
}
|
||||
|
@ -1092,6 +1115,7 @@ public func toGroupPreferences(_ fullPreferences: FullGroupPreferences) -> Group
|
|||
voice: fullPreferences.voice,
|
||||
files: fullPreferences.files,
|
||||
simplexLinks: fullPreferences.simplexLinks,
|
||||
reports: fullPreferences.reports,
|
||||
history: fullPreferences.history
|
||||
)
|
||||
}
|
||||
|
|
|
@ -27,6 +27,7 @@ extension ChatLike {
|
|||
case .files: p.files.on(for: groupInfo.membership)
|
||||
case .simplexLinks: p.simplexLinks.on(for: groupInfo.membership)
|
||||
case .history: p.history.on
|
||||
case .reports: p.reports.on
|
||||
}
|
||||
} else {
|
||||
return true
|
||||
|
|
|
@ -1225,18 +1225,7 @@ data class Chat(
|
|||
|
||||
fun groupFeatureEnabled(feature: GroupFeature): Boolean =
|
||||
if (chatInfo is ChatInfo.Group) {
|
||||
val groupInfo = chatInfo.groupInfo
|
||||
val p = groupInfo.fullGroupPreferences
|
||||
when (feature) {
|
||||
GroupFeature.TimedMessages -> p.timedMessages.on
|
||||
GroupFeature.DirectMessages -> p.directMessages.on(groupInfo.membership)
|
||||
GroupFeature.FullDelete -> p.fullDelete.on
|
||||
GroupFeature.Reactions -> p.reactions.on
|
||||
GroupFeature.Voice -> p.voice.on(groupInfo.membership)
|
||||
GroupFeature.Files -> p.files.on(groupInfo.membership)
|
||||
GroupFeature.SimplexLinks -> p.simplexLinks.on(groupInfo.membership)
|
||||
GroupFeature.History -> p.history.on
|
||||
}
|
||||
chatInfo.groupInfo.groupFeatureEnabled(feature)
|
||||
} else {
|
||||
true
|
||||
}
|
||||
|
@ -1780,6 +1769,21 @@ data class GroupInfo (
|
|||
val canModerate: Boolean
|
||||
get() = membership.memberRole >= GroupMemberRole.Moderator && membership.memberActive
|
||||
|
||||
fun groupFeatureEnabled(feature: GroupFeature): Boolean {
|
||||
val p = fullGroupPreferences
|
||||
return when (feature) {
|
||||
GroupFeature.TimedMessages -> p.timedMessages.on
|
||||
GroupFeature.DirectMessages -> p.directMessages.on(membership)
|
||||
GroupFeature.FullDelete -> p.fullDelete.on
|
||||
GroupFeature.Reactions -> p.reactions.on
|
||||
GroupFeature.Voice -> p.voice.on(membership)
|
||||
GroupFeature.Files -> p.files.on(membership)
|
||||
GroupFeature.SimplexLinks -> p.simplexLinks.on(membership)
|
||||
GroupFeature.Reports -> p.reports.on
|
||||
GroupFeature.History -> p.history.on
|
||||
}
|
||||
}
|
||||
|
||||
companion object {
|
||||
val sampleData = GroupInfo(
|
||||
groupId = 1,
|
||||
|
|
|
@ -5160,6 +5160,7 @@ enum class GroupFeature: Feature {
|
|||
@SerialName("voice") Voice,
|
||||
@SerialName("files") Files,
|
||||
@SerialName("simplexLinks") SimplexLinks,
|
||||
@SerialName("reports") Reports,
|
||||
@SerialName("history") History;
|
||||
|
||||
override val hasParam: Boolean get() = when(this) {
|
||||
|
@ -5176,6 +5177,7 @@ enum class GroupFeature: Feature {
|
|||
Voice -> true
|
||||
Files -> true
|
||||
SimplexLinks -> true
|
||||
Reports -> false
|
||||
History -> false
|
||||
}
|
||||
|
||||
|
@ -5188,6 +5190,7 @@ enum class GroupFeature: Feature {
|
|||
Voice -> generalGetString(MR.strings.voice_messages)
|
||||
Files -> generalGetString(MR.strings.files_and_media)
|
||||
SimplexLinks -> generalGetString(MR.strings.simplex_links)
|
||||
Reports -> generalGetString(MR.strings.group_reports_member_reports)
|
||||
History -> generalGetString(MR.strings.recent_history)
|
||||
}
|
||||
|
||||
|
@ -5200,6 +5203,7 @@ enum class GroupFeature: Feature {
|
|||
Voice -> painterResource(MR.images.ic_keyboard_voice)
|
||||
Files -> painterResource(MR.images.ic_draft)
|
||||
SimplexLinks -> painterResource(MR.images.ic_link)
|
||||
Reports -> painterResource(MR.images.ic_flag)
|
||||
History -> painterResource(MR.images.ic_schedule)
|
||||
}
|
||||
|
||||
|
@ -5212,6 +5216,7 @@ enum class GroupFeature: Feature {
|
|||
Voice -> painterResource(MR.images.ic_keyboard_voice_filled)
|
||||
Files -> painterResource(MR.images.ic_draft_filled)
|
||||
SimplexLinks -> painterResource(MR.images.ic_link)
|
||||
Reports -> painterResource(MR.images.ic_flag_filled)
|
||||
History -> painterResource(MR.images.ic_schedule_filled)
|
||||
}
|
||||
|
||||
|
@ -5246,6 +5251,10 @@ enum class GroupFeature: Feature {
|
|||
GroupFeatureEnabled.ON -> generalGetString(MR.strings.allow_to_send_simplex_links)
|
||||
GroupFeatureEnabled.OFF -> generalGetString(MR.strings.prohibit_sending_simplex_links)
|
||||
}
|
||||
Reports -> when(enabled) {
|
||||
GroupFeatureEnabled.ON -> generalGetString(MR.strings.enable_sending_member_reports)
|
||||
GroupFeatureEnabled.OFF -> generalGetString(MR.strings.disable_sending_member_reports)
|
||||
}
|
||||
History -> when(enabled) {
|
||||
GroupFeatureEnabled.ON -> generalGetString(MR.strings.enable_sending_recent_history)
|
||||
GroupFeatureEnabled.OFF -> generalGetString(MR.strings.disable_sending_recent_history)
|
||||
|
@ -5281,6 +5290,10 @@ enum class GroupFeature: Feature {
|
|||
GroupFeatureEnabled.ON -> generalGetString(MR.strings.group_members_can_send_simplex_links)
|
||||
GroupFeatureEnabled.OFF -> generalGetString(MR.strings.simplex_links_are_prohibited_in_group)
|
||||
}
|
||||
Reports -> when(enabled) {
|
||||
GroupFeatureEnabled.ON -> generalGetString(MR.strings.group_members_can_send_reports)
|
||||
GroupFeatureEnabled.OFF -> generalGetString(MR.strings.member_reports_are_prohibited)
|
||||
}
|
||||
History -> when(enabled) {
|
||||
GroupFeatureEnabled.ON -> generalGetString(MR.strings.recent_history_is_sent_to_new_members)
|
||||
GroupFeatureEnabled.OFF -> generalGetString(MR.strings.recent_history_is_not_sent_to_new_members)
|
||||
|
@ -5400,6 +5413,7 @@ data class FullGroupPreferences(
|
|||
val voice: RoleGroupPreference,
|
||||
val files: RoleGroupPreference,
|
||||
val simplexLinks: RoleGroupPreference,
|
||||
val reports: GroupPreference,
|
||||
val history: GroupPreference,
|
||||
) {
|
||||
fun toGroupPreferences(): GroupPreferences =
|
||||
|
@ -5411,7 +5425,8 @@ data class FullGroupPreferences(
|
|||
voice = voice,
|
||||
files = files,
|
||||
simplexLinks = simplexLinks,
|
||||
history = history
|
||||
reports = reports,
|
||||
history = history,
|
||||
)
|
||||
|
||||
companion object {
|
||||
|
@ -5423,6 +5438,7 @@ data class FullGroupPreferences(
|
|||
voice = RoleGroupPreference(GroupFeatureEnabled.ON, role = null),
|
||||
files = RoleGroupPreference(GroupFeatureEnabled.ON, role = null),
|
||||
simplexLinks = RoleGroupPreference(GroupFeatureEnabled.ON, role = null),
|
||||
reports = GroupPreference(GroupFeatureEnabled.ON),
|
||||
history = GroupPreference(GroupFeatureEnabled.ON),
|
||||
)
|
||||
}
|
||||
|
@ -5437,6 +5453,7 @@ data class GroupPreferences(
|
|||
val voice: RoleGroupPreference? = null,
|
||||
val files: RoleGroupPreference? = null,
|
||||
val simplexLinks: RoleGroupPreference? = null,
|
||||
val reports: GroupPreference? = null,
|
||||
val history: GroupPreference? = null,
|
||||
) {
|
||||
companion object {
|
||||
|
@ -5448,6 +5465,7 @@ data class GroupPreferences(
|
|||
voice = RoleGroupPreference(GroupFeatureEnabled.ON, role = null),
|
||||
files = RoleGroupPreference(GroupFeatureEnabled.ON, role = null),
|
||||
simplexLinks = RoleGroupPreference(GroupFeatureEnabled.ON, role = null),
|
||||
reports = GroupPreference(GroupFeatureEnabled.ON),
|
||||
history = GroupPreference(GroupFeatureEnabled.ON),
|
||||
)
|
||||
}
|
||||
|
|
|
@ -132,6 +132,11 @@ private fun GroupPreferencesLayout(
|
|||
applyPrefs(preferences.copy(simplexLinks = RoleGroupPreference(enable = enable, role)))
|
||||
}
|
||||
|
||||
SectionDividerSpaced(true, maxBottomPadding = false)
|
||||
val enableReports = remember(preferences) { mutableStateOf(preferences.reports.enable) }
|
||||
FeatureSection(GroupFeature.Reports, enableReports, null, groupInfo, preferences, onTTLUpdated) { enable, _ ->
|
||||
applyPrefs(preferences.copy(reports = GroupPreference(enable = enable)))
|
||||
}
|
||||
SectionDividerSpaced(true, maxBottomPadding = false)
|
||||
val enableHistory = remember(preferences) { mutableStateOf(preferences.history.enable) }
|
||||
FeatureSection(GroupFeature.History, enableHistory, null, groupInfo, preferences, onTTLUpdated) { enable, _ ->
|
||||
|
@ -169,6 +174,7 @@ private fun FeatureSection(
|
|||
feature.text,
|
||||
icon,
|
||||
iconTint,
|
||||
disabled = feature == GroupFeature.Reports, // remove in 6.4
|
||||
checked = enableFeature.value == GroupFeatureEnabled.ON,
|
||||
) { checked ->
|
||||
onSelected(if (checked) GroupFeatureEnabled.ON else GroupFeatureEnabled.OFF, enableForRole?.value)
|
||||
|
|
|
@ -400,7 +400,7 @@ fun ChatItemView(
|
|||
val groupInfo = cItem.memberToModerate(cInfo)?.first
|
||||
if (groupInfo != null) {
|
||||
ModerateItemAction(cItem, questionText = moderateMessageQuestionText(cInfo.featureEnabled(ChatFeature.FullDelete), 1), showMenu, deleteMessage)
|
||||
} else if (cItem.meta.itemDeleted == null && cInfo is ChatInfo.Group && cInfo.groupInfo.membership.memberRole == GroupMemberRole.Member && !live) {
|
||||
} else if (cItem.meta.itemDeleted == null && cInfo is ChatInfo.Group && cInfo.groupInfo.groupFeatureEnabled(GroupFeature.Reports) && cInfo.groupInfo.membership.memberRole == GroupMemberRole.Member && !live) {
|
||||
ReportItemAction(cItem, composeState, showMenu)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2064,6 +2064,8 @@
|
|||
<string name="prohibit_sending_simplex_links">Prohibit sending SimpleX links</string>
|
||||
<string name="enable_sending_recent_history">Send up to 100 last messages to new members.</string>
|
||||
<string name="disable_sending_recent_history">Do not send history to new members.</string>
|
||||
<string name="enable_sending_member_reports">Allow to report messsages to moderators.</string>
|
||||
<string name="disable_sending_member_reports">Prohibit reporting messages to moderators.</string>
|
||||
<string name="group_members_can_send_disappearing">Members can send disappearing messages.</string>
|
||||
<string name="disappearing_messages_are_prohibited">Disappearing messages are prohibited.</string>
|
||||
<string name="group_members_can_send_dms">Members can send direct messages.</string>
|
||||
|
@ -2082,6 +2084,8 @@
|
|||
<string name="simplex_links_are_prohibited_in_group">SimpleX links are prohibited.</string>
|
||||
<string name="recent_history_is_sent_to_new_members">Up to 100 last messages are sent to new members.</string>
|
||||
<string name="recent_history_is_not_sent_to_new_members">History is not sent to new members.</string>
|
||||
<string name="group_members_can_send_reports">Members can report messsages to moderators.</string>
|
||||
<string name="member_reports_are_prohibited">Reporting messages is prohibited in this group.</string>
|
||||
<string name="delete_after">Delete after</string>
|
||||
<string name="ttl_sec">%d sec</string>
|
||||
<string name="ttl_s">%ds</string>
|
||||
|
|
|
@ -3066,7 +3066,7 @@ processChatCommand' vr = \case
|
|||
findProhibited :: [ComposedMessageReq] -> Maybe GroupFeature
|
||||
findProhibited =
|
||||
foldr'
|
||||
(\(ComposedMessage {fileSource, msgContent = mc}, _, (_, ft), _) acc -> prohibitedGroupContent gInfo membership mc ft fileSource <|> acc)
|
||||
(\(ComposedMessage {fileSource, msgContent = mc}, _, (_, ft), _) acc -> prohibitedGroupContent gInfo membership mc ft fileSource True <|> acc)
|
||||
Nothing
|
||||
processComposedMessages :: CM ChatResponse
|
||||
processComposedMessages = do
|
||||
|
@ -3974,6 +3974,7 @@ chatCommandP =
|
|||
"/set disappear #" *> (SetGroupTimedMessages <$> displayNameP <*> (A.space *> timedTTLOnOffP)),
|
||||
"/set disappear @" *> (SetContactTimedMessages <$> displayNameP <*> optional (A.space *> timedMessagesEnabledP)),
|
||||
"/set disappear " *> (SetUserTimedMessages <$> (("yes" $> True) <|> ("no" $> False))),
|
||||
"/set reports #" *> (SetGroupFeature (AGFNR SGFReports) <$> displayNameP <*> _strP),
|
||||
"/set links #" *> (SetGroupFeatureRole (AGFR SGFSimplexLinks) <$> displayNameP <*> _strP <*> optional memberRole),
|
||||
("/incognito" <* optional (A.space *> onOffP)) $> ChatHelp HSIncognito,
|
||||
"/set device name " *> (SetLocalDeviceName <$> textP),
|
||||
|
|
|
@ -320,12 +320,18 @@ quoteContent mc qmc ciFile_
|
|||
qFileName = maybe qText (T.pack . getFileName) ciFile_
|
||||
qTextOrFile = if T.null qText then qFileName else qText
|
||||
|
||||
prohibitedGroupContent :: GroupInfo -> GroupMember -> MsgContent -> Maybe MarkdownList -> Maybe f -> Maybe GroupFeature
|
||||
prohibitedGroupContent gInfo m mc ft file_
|
||||
prohibitedGroupContent :: GroupInfo -> GroupMember -> MsgContent -> Maybe MarkdownList -> Maybe f -> Bool -> Maybe GroupFeature
|
||||
prohibitedGroupContent gInfo@GroupInfo {membership = GroupMember {memberRole = userRole}} m mc ft file_ sent
|
||||
| isVoice mc && not (groupFeatureMemberAllowed SGFVoice m gInfo) = Just GFVoice
|
||||
| not (isVoice mc) && isJust file_ && not (groupFeatureMemberAllowed SGFFiles m gInfo) = Just GFFiles
|
||||
| isReport mc && (badReportUser || not (groupFeatureAllowed SGFReports gInfo)) = Just GFReports
|
||||
| prohibitedSimplexLinks gInfo m ft = Just GFSimplexLinks
|
||||
| otherwise = Nothing
|
||||
where
|
||||
-- admins cannot send reports, non-admins cannot receive reports
|
||||
badReportUser
|
||||
| sent = userRole >= GRModerator
|
||||
| otherwise = userRole < GRModerator
|
||||
|
||||
prohibitedSimplexLinks :: GroupInfo -> GroupMember -> Maybe MarkdownList -> Bool
|
||||
prohibitedSimplexLinks gInfo m ft =
|
||||
|
|
|
@ -1720,7 +1720,7 @@ processAgentMessageConn vr user@User {userId} corrId agentConnId agentMessage =
|
|||
newGroupContentMessage :: GroupInfo -> GroupMember -> MsgContainer -> RcvMessage -> UTCTime -> Bool -> CM ()
|
||||
newGroupContentMessage gInfo m@GroupMember {memberId, memberRole} mc msg@RcvMessage {sharedMsgId_} brokerTs forwarded
|
||||
| blockedByAdmin m = createBlockedByAdmin
|
||||
| otherwise = case prohibitedGroupContent gInfo m content ft_ fInv_ of
|
||||
| otherwise = case prohibitedGroupContent gInfo m content ft_ fInv_ False of
|
||||
Just f -> rejected f
|
||||
Nothing ->
|
||||
withStore' (\db -> getCIModeration db vr user gInfo memberId sharedMsgId_) >>= \case
|
||||
|
@ -1729,7 +1729,7 @@ processAgentMessageConn vr user@User {userId} corrId agentConnId agentMessage =
|
|||
withStore' $ \db -> deleteCIModeration db gInfo memberId sharedMsgId_
|
||||
Nothing -> createContentItem
|
||||
where
|
||||
rejected f = void $ newChatItem (ciContentNoParse $ CIRcvGroupFeatureRejected f) Nothing Nothing False
|
||||
rejected f = newChatItem (ciContentNoParse $ CIRcvGroupFeatureRejected f) Nothing Nothing False
|
||||
timed' = if forwarded then rcvCITimed_ (Just Nothing) itemTTL else rcvGroupCITimed gInfo itemTTL
|
||||
live' = fromMaybe False live_
|
||||
ExtMsgContent content mentions fInv_ itemTTL live_ = mcExtMsgContent mc
|
||||
|
|
|
@ -410,8 +410,8 @@ forwardedToGroupMembers ms forwardedMsgs =
|
|||
XGrpMemRestrict mId _ -> Just mId
|
||||
_ -> Nothing
|
||||
_ -> Nothing
|
||||
hasReport = any isReport forwardedMsgs
|
||||
isReport ChatMessage {chatMsgEvent} = case encoding @e of
|
||||
hasReport = any isReportEvent forwardedMsgs
|
||||
isReportEvent ChatMessage {chatMsgEvent} = case encoding @e of
|
||||
SJson -> case chatMsgEvent of
|
||||
XMsgNew mc -> case mcExtMsgContent mc of
|
||||
ExtMsgContent {content = MCReport {}} -> True
|
||||
|
@ -600,6 +600,11 @@ isVoice = \case
|
|||
MCVoice {} -> True
|
||||
_ -> False
|
||||
|
||||
isReport :: MsgContent -> Bool
|
||||
isReport = \case
|
||||
MCReport {} -> True
|
||||
_ -> False
|
||||
|
||||
msgContentTag :: MsgContent -> MsgContentTag
|
||||
msgContentTag = \case
|
||||
MCText _ -> MCText_
|
||||
|
|
|
@ -2453,10 +2453,10 @@ markReceivedGroupReportsDeleted db User {userId} GroupInfo {groupId, membership}
|
|||
[sql|
|
||||
UPDATE chat_items
|
||||
SET item_deleted = ?, item_deleted_ts = ?, item_deleted_by_group_member_id = ?, updated_at = ?
|
||||
WHERE user_id = ? AND group_id = ? AND msg_content_tag = ? AND item_deleted = ? AND item_sent = ?
|
||||
WHERE user_id = ? AND group_id = ? AND msg_content_tag = ? AND item_deleted = ? AND item_sent = 0
|
||||
RETURNING chat_item_id
|
||||
|]
|
||||
(DBCIDeleted, deletedTs, groupMemberId' membership, currentTs, userId, groupId, MCReport_, DBCINotDeleted, False)
|
||||
(DBCIDeleted, deletedTs, groupMemberId' membership, currentTs, userId, groupId, MCReport_, DBCINotDeleted)
|
||||
|
||||
getGroupChatItemBySharedMsgId :: DB.Connection -> User -> GroupInfo -> GroupMemberId -> SharedMsgId -> ExceptT StoreError IO (CChatItem 'CTGroup)
|
||||
getGroupChatItemBySharedMsgId db user@User {userId} g@GroupInfo {groupId} groupMemberId sharedMsgId = do
|
||||
|
|
|
@ -3322,6 +3322,15 @@ Query:
|
|||
Plan:
|
||||
SEARCH chat_items USING INTEGER PRIMARY KEY (rowid=?)
|
||||
|
||||
Query:
|
||||
UPDATE chat_items
|
||||
SET item_deleted = ?, item_deleted_ts = ?, item_deleted_by_group_member_id = ?, updated_at = ?
|
||||
WHERE user_id = ? AND group_id = ? AND msg_content_tag = ? AND item_deleted = ? AND item_sent = ?
|
||||
RETURNING chat_item_id
|
||||
|
||||
Plan:
|
||||
SEARCH chat_items USING COVERING INDEX idx_chat_items_groups_msg_content_tag_deleted (user_id=? AND group_id=? AND msg_content_tag=? AND item_deleted=? AND item_sent=?)
|
||||
|
||||
Query:
|
||||
UPDATE chat_items
|
||||
SET item_deleted = ?, item_deleted_ts = ?, item_deleted_by_group_member_id = ?, updated_at = ?
|
||||
|
|
|
@ -149,6 +149,7 @@ data GroupFeature
|
|||
| GFVoice
|
||||
| GFFiles
|
||||
| GFSimplexLinks
|
||||
| GFReports
|
||||
| GFHistory
|
||||
deriving (Show)
|
||||
|
||||
|
@ -160,6 +161,7 @@ data SGroupFeature (f :: GroupFeature) where
|
|||
SGFVoice :: SGroupFeature 'GFVoice
|
||||
SGFFiles :: SGroupFeature 'GFFiles
|
||||
SGFSimplexLinks :: SGroupFeature 'GFSimplexLinks
|
||||
SGFReports :: SGroupFeature 'GFReports
|
||||
SGFHistory :: SGroupFeature 'GFHistory
|
||||
|
||||
deriving instance Show (SGroupFeature f)
|
||||
|
@ -185,6 +187,7 @@ groupFeatureNameText = \case
|
|||
GFVoice -> "Voice messages"
|
||||
GFFiles -> "Files and media"
|
||||
GFSimplexLinks -> "SimpleX links"
|
||||
GFReports -> "Member reports"
|
||||
GFHistory -> "Recent history"
|
||||
|
||||
groupFeatureNameText' :: SGroupFeature f -> Text
|
||||
|
@ -208,11 +211,12 @@ allGroupFeatures =
|
|||
AGF SGFVoice,
|
||||
AGF SGFFiles,
|
||||
AGF SGFSimplexLinks,
|
||||
AGF SGFReports,
|
||||
AGF SGFHistory
|
||||
]
|
||||
|
||||
groupPrefSel :: SGroupFeature f -> GroupPreferences -> Maybe (GroupFeaturePreference f)
|
||||
groupPrefSel f GroupPreferences {timedMessages, directMessages, fullDelete, reactions, voice, files, simplexLinks, history} = case f of
|
||||
groupPrefSel f GroupPreferences {timedMessages, directMessages, fullDelete, reactions, voice, files, simplexLinks, reports, history} = case f of
|
||||
SGFTimedMessages -> timedMessages
|
||||
SGFDirectMessages -> directMessages
|
||||
SGFFullDelete -> fullDelete
|
||||
|
@ -220,6 +224,7 @@ groupPrefSel f GroupPreferences {timedMessages, directMessages, fullDelete, reac
|
|||
SGFVoice -> voice
|
||||
SGFFiles -> files
|
||||
SGFSimplexLinks -> simplexLinks
|
||||
SGFReports -> reports
|
||||
SGFHistory -> history
|
||||
|
||||
toGroupFeature :: SGroupFeature f -> GroupFeature
|
||||
|
@ -231,6 +236,7 @@ toGroupFeature = \case
|
|||
SGFVoice -> GFVoice
|
||||
SGFFiles -> GFFiles
|
||||
SGFSimplexLinks -> GFSimplexLinks
|
||||
SGFReports -> GFReports
|
||||
SGFHistory -> GFHistory
|
||||
|
||||
class GroupPreferenceI p where
|
||||
|
@ -243,7 +249,7 @@ instance GroupPreferenceI (Maybe GroupPreferences) where
|
|||
getGroupPreference pt prefs = fromMaybe (getGroupPreference pt defaultGroupPrefs) (groupPrefSel pt =<< prefs)
|
||||
|
||||
instance GroupPreferenceI FullGroupPreferences where
|
||||
getGroupPreference f FullGroupPreferences {timedMessages, directMessages, fullDelete, reactions, voice, files, simplexLinks, history} = case f of
|
||||
getGroupPreference f FullGroupPreferences {timedMessages, directMessages, fullDelete, reactions, voice, files, simplexLinks, reports, history} = case f of
|
||||
SGFTimedMessages -> timedMessages
|
||||
SGFDirectMessages -> directMessages
|
||||
SGFFullDelete -> fullDelete
|
||||
|
@ -251,6 +257,7 @@ instance GroupPreferenceI FullGroupPreferences where
|
|||
SGFVoice -> voice
|
||||
SGFFiles -> files
|
||||
SGFSimplexLinks -> simplexLinks
|
||||
SGFReports -> reports
|
||||
SGFHistory -> history
|
||||
{-# INLINE getGroupPreference #-}
|
||||
|
||||
|
@ -263,6 +270,7 @@ data GroupPreferences = GroupPreferences
|
|||
voice :: Maybe VoiceGroupPreference,
|
||||
files :: Maybe FilesGroupPreference,
|
||||
simplexLinks :: Maybe SimplexLinksGroupPreference,
|
||||
reports :: Maybe ReportsGroupPreference,
|
||||
history :: Maybe HistoryGroupPreference
|
||||
}
|
||||
deriving (Eq, Show)
|
||||
|
@ -296,6 +304,7 @@ setGroupPreference_ f pref prefs =
|
|||
SGFVoice -> prefs {voice = pref}
|
||||
SGFFiles -> prefs {files = pref}
|
||||
SGFSimplexLinks -> prefs {simplexLinks = pref}
|
||||
SGFReports -> prefs {reports = pref}
|
||||
SGFHistory -> prefs {history = pref}
|
||||
|
||||
setGroupTimedMessagesPreference :: TimedMessagesGroupPreference -> Maybe GroupPreferences -> GroupPreferences
|
||||
|
@ -325,6 +334,7 @@ data FullGroupPreferences = FullGroupPreferences
|
|||
voice :: VoiceGroupPreference,
|
||||
files :: FilesGroupPreference,
|
||||
simplexLinks :: SimplexLinksGroupPreference,
|
||||
reports :: ReportsGroupPreference,
|
||||
history :: HistoryGroupPreference
|
||||
}
|
||||
deriving (Eq, Show)
|
||||
|
@ -377,22 +387,23 @@ defaultGroupPrefs =
|
|||
FullGroupPreferences
|
||||
{ timedMessages = TimedMessagesGroupPreference {enable = FEOff, ttl = Just 86400},
|
||||
directMessages = DirectMessagesGroupPreference {enable = FEOff, role = Nothing},
|
||||
fullDelete = FullDeleteGroupPreference {enable = FEOn, role = Just GRModerator},
|
||||
fullDelete = FullDeleteGroupPreference {enable = FEOff, role = Nothing},
|
||||
reactions = ReactionsGroupPreference {enable = FEOn},
|
||||
voice = VoiceGroupPreference {enable = FEOn, role = Nothing},
|
||||
files = FilesGroupPreference {enable = FEOn, role = Nothing},
|
||||
simplexLinks = SimplexLinksGroupPreference {enable = FEOn, role = Nothing},
|
||||
reports = ReportsGroupPreference {enable = FEOn},
|
||||
history = HistoryGroupPreference {enable = FEOff}
|
||||
}
|
||||
|
||||
emptyGroupPrefs :: GroupPreferences
|
||||
emptyGroupPrefs = GroupPreferences Nothing Nothing Nothing Nothing Nothing Nothing Nothing Nothing
|
||||
emptyGroupPrefs = GroupPreferences Nothing Nothing Nothing Nothing Nothing Nothing Nothing Nothing Nothing
|
||||
|
||||
businessGroupPrefs :: Preferences -> GroupPreferences
|
||||
businessGroupPrefs Preferences {timedMessages, fullDelete, reactions, voice} =
|
||||
defaultBusinessGroupPrefs
|
||||
{ timedMessages = Just TimedMessagesGroupPreference {enable = maybe FEOff enableFeature timedMessages, ttl = maybe Nothing prefParam timedMessages},
|
||||
fullDelete = Just FullDeleteGroupPreference {enable = maybe FEOff enableFeature fullDelete, role = Just GRModerator},
|
||||
fullDelete = Just FullDeleteGroupPreference {enable = maybe FEOff enableFeature fullDelete, role = Nothing},
|
||||
reactions = Just ReactionsGroupPreference {enable = maybe FEOn enableFeature reactions},
|
||||
voice = Just VoiceGroupPreference {enable = maybe FEOff enableFeature voice, role = Nothing}
|
||||
}
|
||||
|
@ -412,6 +423,7 @@ defaultBusinessGroupPrefs =
|
|||
voice = Just $ VoiceGroupPreference FEOff Nothing,
|
||||
files = Just $ FilesGroupPreference FEOn Nothing,
|
||||
simplexLinks = Just $ SimplexLinksGroupPreference FEOn Nothing,
|
||||
reports = Just $ ReportsGroupPreference FEOff,
|
||||
history = Just $ HistoryGroupPreference FEOn
|
||||
}
|
||||
|
||||
|
@ -512,6 +524,10 @@ data SimplexLinksGroupPreference = SimplexLinksGroupPreference
|
|||
{enable :: GroupFeatureEnabled, role :: Maybe GroupMemberRole}
|
||||
deriving (Eq, Show)
|
||||
|
||||
data ReportsGroupPreference = ReportsGroupPreference
|
||||
{enable :: GroupFeatureEnabled}
|
||||
deriving (Eq, Show)
|
||||
|
||||
data HistoryGroupPreference = HistoryGroupPreference
|
||||
{enable :: GroupFeatureEnabled}
|
||||
deriving (Eq, Show)
|
||||
|
@ -550,6 +566,9 @@ instance HasField "enable" FilesGroupPreference GroupFeatureEnabled where
|
|||
instance HasField "enable" SimplexLinksGroupPreference GroupFeatureEnabled where
|
||||
hasField p@SimplexLinksGroupPreference {enable} = (\e -> p {enable = e}, enable)
|
||||
|
||||
instance HasField "enable" ReportsGroupPreference GroupFeatureEnabled where
|
||||
hasField p@ReportsGroupPreference {enable} = (\e -> p {enable = e}, enable)
|
||||
|
||||
instance HasField "enable" HistoryGroupPreference GroupFeatureEnabled where
|
||||
hasField p@HistoryGroupPreference {enable} = (\e -> p {enable = e}, enable)
|
||||
|
||||
|
@ -595,6 +614,12 @@ instance GroupFeatureI 'GFSimplexLinks where
|
|||
groupPrefParam _ = Nothing
|
||||
groupPrefRole SimplexLinksGroupPreference {role} = role
|
||||
|
||||
instance GroupFeatureI 'GFReports where
|
||||
type GroupFeaturePreference 'GFReports = ReportsGroupPreference
|
||||
sGroupFeature = SGFReports
|
||||
groupPrefParam _ = Nothing
|
||||
groupPrefRole _ = Nothing
|
||||
|
||||
instance GroupFeatureI 'GFHistory where
|
||||
type GroupFeaturePreference 'GFHistory = HistoryGroupPreference
|
||||
sGroupFeature = SGFHistory
|
||||
|
@ -607,6 +632,8 @@ instance GroupFeatureNoRoleI 'GFFullDelete
|
|||
|
||||
instance GroupFeatureNoRoleI 'GFReactions
|
||||
|
||||
instance GroupFeatureNoRoleI 'GFReports
|
||||
|
||||
instance GroupFeatureNoRoleI 'GFHistory
|
||||
|
||||
instance HasField "role" DirectMessagesGroupPreference (Maybe GroupMemberRole) where
|
||||
|
@ -761,6 +788,7 @@ mergeGroupPreferences groupPreferences =
|
|||
voice = pref SGFVoice,
|
||||
files = pref SGFFiles,
|
||||
simplexLinks = pref SGFSimplexLinks,
|
||||
reports = pref SGFReports,
|
||||
history = pref SGFHistory
|
||||
}
|
||||
where
|
||||
|
@ -777,6 +805,7 @@ toGroupPreferences groupPreferences =
|
|||
voice = pref SGFVoice,
|
||||
files = pref SGFFiles,
|
||||
simplexLinks = pref SGFSimplexLinks,
|
||||
reports = pref SGFReports,
|
||||
history = pref SGFHistory
|
||||
}
|
||||
where
|
||||
|
@ -885,6 +914,8 @@ $(J.deriveJSON defaultJSON ''FilesGroupPreference)
|
|||
|
||||
$(J.deriveJSON defaultJSON ''SimplexLinksGroupPreference)
|
||||
|
||||
$(J.deriveJSON defaultJSON ''ReportsGroupPreference)
|
||||
|
||||
$(J.deriveJSON defaultJSON ''HistoryGroupPreference)
|
||||
|
||||
$(J.deriveJSON defaultJSON ''GroupPreferences)
|
||||
|
|
|
@ -559,7 +559,7 @@ testGroup2 =
|
|||
]
|
||||
dan <##> alice
|
||||
-- show last messages
|
||||
alice ##> "/t #club 17"
|
||||
alice ##> "/t #club 18"
|
||||
alice -- these strings are expected in any order because of sorting by time and rounding of time for sent
|
||||
<##?
|
||||
( map (ConsoleString . ("#club " <> )) groupFeatureStrs
|
||||
|
@ -1226,7 +1226,7 @@ testGroupMessageDelete =
|
|||
testChat3 aliceProfile bobProfile cathProfile $
|
||||
\alice bob cath -> do
|
||||
createGroup3 "team" alice bob cath
|
||||
disableFullDeletion3 "team" alice bob cath
|
||||
-- disableFullDeletion3 "team" alice bob cath
|
||||
threadDelay 1000000
|
||||
-- alice, bob: msg id 5, cath: msg id 4 (after group invitations & group events)
|
||||
alice #> "#team hello!"
|
||||
|
@ -1238,7 +1238,7 @@ testGroupMessageDelete =
|
|||
msgItemId1 <- lastItemId alice
|
||||
alice #$> ("/_delete item #1 " <> msgItemId1 <> " internal", id, "message deleted")
|
||||
|
||||
alice #$> ("/_get chat #1 count=2", chat, [(0, "connected"), (1, "Full deletion: off")])
|
||||
alice #$> ("/_get chat #1 count=2", chat, [(0, "connected"), (0, "connected")])
|
||||
bob #$> ("/_get chat #1 count=1", chat, [(0, "hello!")])
|
||||
cath #$> ("/_get chat #1 count=1", chat, [(0, "hello!")])
|
||||
|
||||
|
@ -1264,7 +1264,7 @@ testGroupMessageDelete =
|
|||
msgItemId2 <- lastItemId alice
|
||||
alice #$> ("/_delete item #1 " <> msgItemId2 <> " internal", id, "message deleted")
|
||||
|
||||
alice #$> ("/_get chat #1 count=2", chat', [((0, "connected"), Nothing), ((1, "Full deletion: off"), Nothing)])
|
||||
alice #$> ("/_get chat #1 count=2", chat', [((0, "connected"), Nothing), ((0, "connected"), Nothing)])
|
||||
bob #$> ("/_get chat #1 count=2", chat', [((0, "hello!"), Nothing), ((1, "hi alic"), Just (0, "hello!"))])
|
||||
cath #$> ("/_get chat #1 count=2", chat', [((0, "hello!"), Nothing), ((0, "hi alic"), Just (0, "hello!"))])
|
||||
|
||||
|
@ -1311,7 +1311,7 @@ testGroupMessageDeleteMultiple =
|
|||
testChat3 aliceProfile bobProfile cathProfile $
|
||||
\alice bob cath -> do
|
||||
createGroup3 "team" alice bob cath
|
||||
disableFullDeletion3 "team" alice bob cath
|
||||
-- disableFullDeletion3 "team" alice bob cath
|
||||
|
||||
threadDelay 1000000
|
||||
alice #> "#team hello"
|
||||
|
@ -1348,7 +1348,7 @@ testGroupMessageDeleteMultipleManyBatches =
|
|||
testChat3 aliceProfile bobProfile cathProfile $
|
||||
\alice bob cath -> do
|
||||
createGroup3 "team" alice bob cath
|
||||
disableFullDeletion3 "team" alice bob cath
|
||||
-- disableFullDeletion3 "team" alice bob cath
|
||||
|
||||
bob ##> "/set receipts all off"
|
||||
bob <## "ok"
|
||||
|
@ -1499,9 +1499,9 @@ testGroupDescription = testChat4 aliceProfile bobProfile cathProfile danProfile
|
|||
alice ##> "/g team"
|
||||
alice <## "group #team is created"
|
||||
alice <## "to add members use /a team <name> or /create link #team"
|
||||
alice ##> "/set delete #team off"
|
||||
alice <## "updated group preferences:"
|
||||
alice <## "Full deletion: off"
|
||||
-- alice ##> "/set delete #team off"
|
||||
-- alice <## "updated group preferences:"
|
||||
-- alice <## "Full deletion: off"
|
||||
addMember "team" alice bob GRAdmin
|
||||
bob ##> "/j team"
|
||||
concurrentlyN_
|
||||
|
@ -1561,6 +1561,7 @@ testGroupDescription = testChat4 aliceProfile bobProfile cathProfile danProfile
|
|||
alice <## "Voice messages: on"
|
||||
alice <## "Files and media: on"
|
||||
alice <## "SimpleX links: on"
|
||||
alice <## "Member reports: on"
|
||||
alice <## "Recent history: on"
|
||||
bobAddedDan :: HasCallStack => TestCC -> IO ()
|
||||
bobAddedDan cc = do
|
||||
|
@ -1572,7 +1573,7 @@ testGroupModerate =
|
|||
testChat3 aliceProfile bobProfile cathProfile $
|
||||
\alice bob cath -> do
|
||||
createGroup3 "team" alice bob cath
|
||||
disableFullDeletion3 "team" alice bob cath
|
||||
-- disableFullDeletion3 "team" alice bob cath
|
||||
alice ##> "/mr team cath member"
|
||||
concurrentlyN_
|
||||
[ alice <## "#team: you changed the role of cath from admin to member",
|
||||
|
@ -1604,7 +1605,7 @@ testGroupModerateOwn =
|
|||
testChat2 aliceProfile bobProfile $
|
||||
\alice bob -> do
|
||||
createGroup2 "team" alice bob
|
||||
disableFullDeletion2 "team" alice bob
|
||||
-- disableFullDeletion2 "team" alice bob
|
||||
threadDelay 1000000
|
||||
alice #> "#team hello"
|
||||
bob <# "#team alice> hello"
|
||||
|
@ -1619,7 +1620,7 @@ testGroupModerateMultiple =
|
|||
testChat3 aliceProfile bobProfile cathProfile $
|
||||
\alice bob cath -> do
|
||||
createGroup3 "team" alice bob cath
|
||||
disableFullDeletion3 "team" alice bob cath
|
||||
-- disableFullDeletion3 "team" alice bob cath
|
||||
|
||||
threadDelay 1000000
|
||||
alice #> "#team hello"
|
||||
|
@ -1655,7 +1656,7 @@ testGroupModerateFullDelete =
|
|||
testChat3 aliceProfile bobProfile cathProfile $
|
||||
\alice bob cath -> do
|
||||
createGroup3 "team" alice bob cath
|
||||
disableFullDeletion3 "team" alice bob cath
|
||||
-- disableFullDeletion3 "team" alice bob cath
|
||||
alice ##> "/mr team cath member"
|
||||
concurrentlyN_
|
||||
[ alice <## "#team: you changed the role of cath from admin to member",
|
||||
|
@ -1694,7 +1695,7 @@ testGroupDelayedModeration ps = do
|
|||
withNewTestChatCfg ps cfg "alice" aliceProfile $ \alice -> do
|
||||
withNewTestChatCfg ps cfg "bob" bobProfile $ \bob -> do
|
||||
createGroup2 "team" alice bob
|
||||
disableFullDeletion2 "team" alice bob
|
||||
-- disableFullDeletion2 "team" alice bob
|
||||
withNewTestChatCfg ps cfg "cath" cathProfile $ \cath -> do
|
||||
connectUsers alice cath
|
||||
addMember "team" alice cath GRMember
|
||||
|
@ -1742,7 +1743,7 @@ testGroupDelayedModerationFullDelete ps = do
|
|||
withNewTestChatCfg ps cfg "alice" aliceProfile $ \alice -> do
|
||||
withNewTestChatCfg ps cfg "bob" bobProfile $ \bob -> do
|
||||
createGroup2 "team" alice bob
|
||||
disableFullDeletion2 "team" alice bob
|
||||
-- disableFullDeletion2 "team" alice bob
|
||||
withNewTestChatCfg ps cfg "cath" cathProfile $ \cath -> do
|
||||
connectUsers alice cath
|
||||
addMember "team" alice cath GRMember
|
||||
|
@ -3998,6 +3999,12 @@ testGroupMsgForwardReport =
|
|||
cath <## "#team: alice changed the role of bob from admin to moderator"
|
||||
]
|
||||
|
||||
alice ##> "/mr team cath member"
|
||||
concurrentlyN_
|
||||
[ alice <## "#team: you changed the role of cath from admin to member",
|
||||
bob <## "#team: alice changed the role of cath from admin to member",
|
||||
cath <## "#team: alice changed your role from admin to member"
|
||||
]
|
||||
cath ##> "/report #team content hi there"
|
||||
cath <# "#team > bob hi there"
|
||||
cath <## " report content"
|
||||
|
@ -4127,7 +4134,7 @@ testGroupMsgForwardDeletion =
|
|||
testChat3 aliceProfile bobProfile cathProfile $
|
||||
\alice bob cath -> do
|
||||
setupGroupForwarding3 "team" alice bob cath
|
||||
disableFullDeletion3 "team" alice bob cath
|
||||
-- disableFullDeletion3 "team" alice bob cath
|
||||
|
||||
bob #> "#team hi there"
|
||||
alice <# "#team bob> hi there"
|
||||
|
@ -4845,7 +4852,7 @@ testGroupHistoryDeletedMessage =
|
|||
testChat3 aliceProfile bobProfile cathProfile $
|
||||
\alice bob cath -> do
|
||||
createGroup2 "team" alice bob
|
||||
disableFullDeletion2 "team" alice bob
|
||||
-- disableFullDeletion2 "team" alice bob
|
||||
|
||||
alice #> "#team hello"
|
||||
bob <# "#team alice> hello"
|
||||
|
@ -5535,7 +5542,7 @@ testBlockForAllMarkedBlocked =
|
|||
testChat3 aliceProfile bobProfile cathProfile $
|
||||
\alice bob cath -> do
|
||||
createGroup3 "team" alice bob cath
|
||||
disableFullDeletion3 "team" alice bob cath
|
||||
-- disableFullDeletion3 "team" alice bob cath
|
||||
|
||||
threadDelay 1000000
|
||||
|
||||
|
@ -5623,7 +5630,7 @@ testBlockForAllFullDelete =
|
|||
testChat3 aliceProfile bobProfile cathProfile $
|
||||
\alice bob cath -> do
|
||||
createGroup3 "team" alice bob cath
|
||||
disableFullDeletion3 "team" alice bob cath
|
||||
-- disableFullDeletion3 "team" alice bob cath
|
||||
|
||||
alice ##> "/set delete #team on"
|
||||
alice <## "updated group preferences:"
|
||||
|
@ -5704,7 +5711,7 @@ testBlockForAllAnotherAdminUnblocks =
|
|||
testChat3 aliceProfile bobProfile cathProfile $
|
||||
\alice bob cath -> do
|
||||
createGroup3 "team" alice bob cath
|
||||
disableFullDeletion3 "team" alice bob cath
|
||||
-- disableFullDeletion3 "team" alice bob cath
|
||||
|
||||
bob #> "#team 1"
|
||||
[alice, cath] *<# "#team bob> 1"
|
||||
|
@ -5733,7 +5740,7 @@ testBlockForAllBeforeJoining =
|
|||
testChat4 aliceProfile bobProfile cathProfile danProfile $
|
||||
\alice bob cath dan -> do
|
||||
createGroup3 "team" alice bob cath
|
||||
disableFullDeletion3 "team" alice bob cath
|
||||
-- disableFullDeletion3 "team" alice bob cath
|
||||
|
||||
bob #> "#team 1"
|
||||
[alice, cath] *<# "#team bob> 1"
|
||||
|
@ -5802,7 +5809,7 @@ testBlockForAllCantRepeat =
|
|||
testChat3 aliceProfile bobProfile cathProfile $
|
||||
\alice bob cath -> do
|
||||
createGroup3 "team" alice bob cath
|
||||
disableFullDeletion3 "team" alice bob cath
|
||||
-- disableFullDeletion3 "team" alice bob cath
|
||||
|
||||
alice ##> "/unblock for all #team bob"
|
||||
alice <## "bad chat command: already unblocked"
|
||||
|
@ -5919,7 +5926,7 @@ testGroupMemberReports =
|
|||
testChat4 aliceProfile bobProfile cathProfile danProfile $
|
||||
\alice bob cath dan -> do
|
||||
createGroup3 "jokes" alice bob cath
|
||||
disableFullDeletion3 "jokes" alice bob cath
|
||||
-- disableFullDeletion3 "jokes" alice bob cath
|
||||
alice ##> "/mr jokes bob moderator"
|
||||
concurrentlyN_
|
||||
[ alice <## "#jokes: you changed the role of bob from admin to moderator",
|
||||
|
|
|
@ -300,11 +300,12 @@ groupFeatures'' dir =
|
|||
[ ((dir, e2eeInfoNoPQStr), Nothing, Nothing),
|
||||
((dir, "Disappearing messages: off"), Nothing, Nothing),
|
||||
((dir, "Direct messages: on"), Nothing, Nothing),
|
||||
((dir, "Full deletion: on for moderators"), Nothing, Nothing),
|
||||
((dir, "Full deletion: off"), Nothing, Nothing),
|
||||
((dir, "Message reactions: on"), Nothing, Nothing),
|
||||
((dir, "Voice messages: on"), Nothing, Nothing),
|
||||
((dir, "Files and media: on"), Nothing, Nothing),
|
||||
((dir, "SimpleX links: on"), Nothing, Nothing),
|
||||
((dir, "Member reports: on"), Nothing, Nothing),
|
||||
((dir, "Recent history: on"), Nothing, Nothing)
|
||||
]
|
||||
|
||||
|
|
|
@ -101,7 +101,7 @@ testChatPreferences :: Maybe Preferences
|
|||
testChatPreferences = Just Preferences {voice = Just VoicePreference {allow = FAYes}, fullDelete = Nothing, timedMessages = Nothing, calls = Nothing, reactions = Just ReactionsPreference {allow = FAYes}}
|
||||
|
||||
testGroupPreferences :: Maybe GroupPreferences
|
||||
testGroupPreferences = Just GroupPreferences {timedMessages = Nothing, directMessages = Nothing, reactions = Just ReactionsGroupPreference {enable = FEOn}, voice = Just VoiceGroupPreference {enable = FEOn, role = Nothing}, files = Nothing, fullDelete = Nothing, simplexLinks = Nothing, history = Nothing}
|
||||
testGroupPreferences = Just GroupPreferences {timedMessages = Nothing, directMessages = Nothing, reactions = Just ReactionsGroupPreference {enable = FEOn}, voice = Just VoiceGroupPreference {enable = FEOn, role = Nothing}, files = Nothing, fullDelete = Nothing, simplexLinks = Nothing, history = Nothing, reports = Nothing}
|
||||
|
||||
testProfile :: Profile
|
||||
testProfile = Profile {displayName = "alice", fullName = "Alice", image = Just (ImageData "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAgAAAAIAQMAAAD+wSzIAAAABlBMVEX///+/v7+jQ3Y5AAAADklEQVQI12P4AIX8EAgALgAD/aNpbtEAAAAASUVORK5CYII="), contactLink = Nothing, preferences = testChatPreferences}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue