From bc604febbc6bc76a21e895a67b106c74ce12f602 Mon Sep 17 00:00:00 2001 From: Bruno Muniz Azevedo Filho <bruno@elixxir.io> Date: Mon, 22 Aug 2022 23:58:35 -0300 Subject: [PATCH] Add user defaults flag for reporting enabled and reporting optional --- .../Controllers/GroupChatController.swift | 14 ++++--- .../Controllers/SingleChatController.swift | 15 +++++-- .../ViewModels/GroupChatViewModel.swift | 3 +- .../ViewModels/SingleChatViewModel.swift | 1 + .../ViewModel/ChatListViewModel.swift | 40 +++++++++++++------ .../ViewModels/ContactListViewModel.swift | 34 +++++++++++----- .../ViewModels/CreateGroupViewModel.swift | 9 ++++- Sources/Defaults/KeyObject.swift | 3 ++ Sources/Integration/Session/Session.swift | 3 +- Sources/LaunchFeature/LaunchViewModel.swift | 8 +++- .../ViewModels/MenuViewModel.swift | 26 ++++++++---- Sources/PushFeature/PushHandler.swift | 3 +- .../RequestsReceivedViewModel.swift | 11 ++++- .../ViewModels/RequestsSentViewModel.swift | 15 +++++-- .../ViewModels/SearchLeftViewModel.swift | 12 ++++-- .../ViewModels/SearchRightViewModel.swift | 7 +++- .../SettingsAdvancedController.swift | 12 ++++++ .../SettingsAdvancedViewModel.swift | 12 ++++++ .../Views/SettingsAdvancedView.swift | 17 ++++++-- Sources/Shared/AutoGenerated/Strings.swift | 6 +++ .../Resources/en.lproj/Localizable.strings | 4 ++ 21 files changed, 197 insertions(+), 58 deletions(-) diff --git a/Sources/ChatFeature/Controllers/GroupChatController.swift b/Sources/ChatFeature/Controllers/GroupChatController.swift index c6b0d6d2..689bc36c 100644 --- a/Sources/ChatFeature/Controllers/GroupChatController.swift +++ b/Sources/ChatFeature/Controllers/GroupChatController.swift @@ -602,17 +602,21 @@ extension GroupChatController: UICollectionViewDelegate { self?.viewModel.retry(item) } - let menu: UIMenu + var children = [UIAction]() if item.status == .sendingFailed { - menu = UIMenu(title: "", children: [copy, retry, delete]) + children = [copy, retry, delete] } else if item.status == .sending { - menu = UIMenu(title: "", children: [copy]) + children = [copy] } else { - menu = UIMenu(title: "", children: [copy, reply, delete, report]) + children = [copy, reply, delete] + + if self.viewModel.isReportingEnabled { + children.append(report) + } } - return menu + return UIMenu(title: "", children: children) } } } diff --git a/Sources/ChatFeature/Controllers/SingleChatController.swift b/Sources/ChatFeature/Controllers/SingleChatController.swift index 03b182e5..08aa3944 100644 --- a/Sources/ChatFeature/Controllers/SingleChatController.swift +++ b/Sources/ChatFeature/Controllers/SingleChatController.swift @@ -655,13 +655,20 @@ extension SingleChatController: UICollectionViewDelegate { guard let self = self else { return nil } let item = self.sections[indexPath.section].elements[indexPath.item] - return UIMenu(title: "", children: [ + var children = [ ActionFactory.build(from: item, action: .copy, closure: self.viewModel.didRequestCopy(_:)), ActionFactory.build(from: item, action: .retry, closure: self.viewModel.didRequestRetry(_:)), ActionFactory.build(from: item, action: .reply, closure: self.viewModel.didRequestReply(_:)), - ActionFactory.build(from: item, action: .delete, closure: self.viewModel.didRequestDeleteSingle(_:)), - ActionFactory.build(from: item, action: .report, closure: self.viewModel.didRequestReport(_:)) - ].compactMap { $0 }) + ActionFactory.build(from: item, action: .delete, closure: self.viewModel.didRequestDeleteSingle(_:)) + ] + + if self.viewModel.isReportingEnabled { + children.append( + ActionFactory.build(from: item, action: .report, closure: self.viewModel.didRequestReport(_:)) + ) + } + + return UIMenu(title: "", children: children.compactMap { $0 }) } } diff --git a/Sources/ChatFeature/ViewModels/GroupChatViewModel.swift b/Sources/ChatFeature/ViewModels/GroupChatViewModel.swift index e9ca9553..42026974 100644 --- a/Sources/ChatFeature/ViewModels/GroupChatViewModel.swift +++ b/Sources/ChatFeature/ViewModels/GroupChatViewModel.swift @@ -23,6 +23,7 @@ final class GroupChatViewModel { @Dependency private var toastController: ToastController @KeyObject(.username, defaultValue: nil) var username: String? + @KeyObject(.isReportingEnabled, defaultValue: true) var isReportingEnabled: Bool var hudPublisher: AnyPublisher<HUDStatus, Never> { hudSubject.eraseToAnyPublisher() @@ -130,7 +131,7 @@ final class GroupChatViewModel { var name = (contact.nickname ?? contact.username) ?? "Fetching username..." - if contact.isBlocked { + if contact.isBlocked, isReportingEnabled { name = "\(name) (Blocked)" } diff --git a/Sources/ChatFeature/ViewModels/SingleChatViewModel.swift b/Sources/ChatFeature/ViewModels/SingleChatViewModel.swift index 8ba933ad..e08b4df2 100644 --- a/Sources/ChatFeature/ViewModels/SingleChatViewModel.swift +++ b/Sources/ChatFeature/ViewModels/SingleChatViewModel.swift @@ -33,6 +33,7 @@ final class SingleChatViewModel: NSObject { @Dependency private var sendReport: SendReport @KeyObject(.username, defaultValue: nil) var username: String? + @KeyObject(.isReportingEnabled, defaultValue: true) var isReportingEnabled: Bool var contact: Contact { contactSubject.value } private var stagedReply: Reply? diff --git a/Sources/ChatListFeature/ViewModel/ChatListViewModel.swift b/Sources/ChatListFeature/ViewModel/ChatListViewModel.swift index d3918b04..266d095d 100644 --- a/Sources/ChatListFeature/ViewModel/ChatListViewModel.swift +++ b/Sources/ChatListFeature/ViewModel/ChatListViewModel.swift @@ -24,6 +24,8 @@ typealias SearchSnapshot = NSDiffableDataSourceSnapshot<SearchSection, SearchIte final class ChatListViewModel { @Dependency private var session: SessionType + @KeyObject(.isReportingEnabled, defaultValue: true) var isReportingEnabled: Bool + var isOnline: AnyPublisher<Bool, Never> { session.isOnline } @@ -37,7 +39,12 @@ final class ChatListViewModel { } var recentsPublisher: AnyPublisher<RecentsSnapshot, Never> { - let query = Contact.Query(isRecent: true, isBlocked: false, isBanned: false) + let query = Contact.Query( + isRecent: true, + isBlocked: isReportingEnabled ? false : nil, + isBanned: isReportingEnabled ? false : nil + ) + return session.dbManager.fetchContactsPublisher(query) .assertNoFailure() .map { @@ -50,8 +57,13 @@ final class ChatListViewModel { } var searchPublisher: AnyPublisher<SearchSnapshot, Never> { + let contactsQuery = Contact.Query( + isBlocked: isReportingEnabled ? false : nil, + isBanned: isReportingEnabled ? false : nil + ) + let contactsStream = session.dbManager - .fetchContactsPublisher(.init(isBlocked: false, isBanned: false)) + .fetchContactsPublisher(contactsQuery) .assertNoFailure() .map { $0.filter { $0.id != self.session.myId }} @@ -107,13 +119,17 @@ final class ChatListViewModel { var badgeCountPublisher: AnyPublisher<Int, Never> { let groupQuery = Group.Query(authStatus: [.pending]) - let contactsQuery = Contact.Query(authStatus: [ - .verified, - .confirming, - .confirmationFailed, - .verificationFailed, - .verificationInProgress - ], isBlocked: false, isBanned: false) + let contactsQuery = Contact.Query( + authStatus: [ + .verified, + .confirming, + .confirmationFailed, + .verificationFailed, + .verificationInProgress + ], + isBlocked: isReportingEnabled ? false : nil, + isBanned: isReportingEnabled ? false : nil + ) return Publishers.CombineLatest( session.dbManager.fetchContactsPublisher(contactsQuery).assertNoFailure(), @@ -134,12 +150,12 @@ final class ChatListViewModel { contactChatInfoQuery: .init( userId: session.myId, authStatus: [.friend], - isBlocked: false, - isBanned: false + isBlocked: isReportingEnabled ? false : nil, + isBanned: isReportingEnabled ? false : nil ), groupChatInfoQuery: GroupChatInfo.Query( authStatus: [.participating], - excludeBannedContactsMessages: true + excludeBannedContactsMessages: isReportingEnabled ), groupQuery: Group.Query( withMessages: false, diff --git a/Sources/ContactListFeature/ViewModels/ContactListViewModel.swift b/Sources/ContactListFeature/ViewModels/ContactListViewModel.swift index d0915822..35711caf 100644 --- a/Sources/ContactListFeature/ViewModels/ContactListViewModel.swift +++ b/Sources/ContactListFeature/ViewModels/ContactListViewModel.swift @@ -1,14 +1,21 @@ import Models import Combine import XXModels +import Defaults import Integration import DependencyInjection final class ContactListViewModel { @Dependency private var session: SessionType + @KeyObject(.isReportingEnabled, defaultValue: true) var isReportingEnabled: Bool + var contacts: AnyPublisher<[Contact], Never> { - let query = Contact.Query(authStatus: [.friend], isBlocked: false, isBanned: false) + let query = Contact.Query( + authStatus: [.friend], + isBlocked: isReportingEnabled ? false : nil, + isBanned: isReportingEnabled ? false: nil + ) return session.dbManager.fetchContactsPublisher(query) .assertNoFailure() @@ -17,14 +24,23 @@ final class ContactListViewModel { } var requestCount: AnyPublisher<Int, Never> { - let groupQuery = Group.Query(authStatus: [.pending], isLeaderBlocked: false, isLeaderBanned: false) - let contactsQuery = Contact.Query(authStatus: [ - .verified, - .confirming, - .confirmationFailed, - .verificationFailed, - .verificationInProgress - ], isBlocked: false, isBanned: false) + let groupQuery = Group.Query( + authStatus: [.pending], + isLeaderBlocked: isReportingEnabled ? false : nil, + isLeaderBanned: isReportingEnabled ? false : nil + ) + + let contactsQuery = Contact.Query( + authStatus: [ + .verified, + .confirming, + .confirmationFailed, + .verificationFailed, + .verificationInProgress + ], + isBlocked: isReportingEnabled ? false : nil, + isBanned: isReportingEnabled ? false : nil + ) return Publishers.CombineLatest( session.dbManager.fetchContactsPublisher(contactsQuery).assertNoFailure(), diff --git a/Sources/ContactListFeature/ViewModels/CreateGroupViewModel.swift b/Sources/ContactListFeature/ViewModels/CreateGroupViewModel.swift index 668b396b..19cadc6e 100644 --- a/Sources/ContactListFeature/ViewModels/CreateGroupViewModel.swift +++ b/Sources/ContactListFeature/ViewModels/CreateGroupViewModel.swift @@ -9,6 +9,7 @@ import DependencyInjection final class CreateGroupViewModel { @KeyObject(.username, defaultValue: "") var username: String + @KeyObject(.isReportingEnabled, defaultValue: true) var isReportingEnabled: Bool // MARK: Injected @@ -42,7 +43,13 @@ final class CreateGroupViewModel { // MARK: Lifecycle init() { - session.dbManager.fetchContactsPublisher(.init(authStatus: [.friend], isBlocked: false, isBanned: false)) + let query = Contact.Query( + authStatus: [.friend], + isBlocked: isReportingEnabled ? false : nil, + isBanned: isReportingEnabled ? false : nil + ) + + session.dbManager.fetchContactsPublisher(query) .assertNoFailure() .map { $0.filter { $0.id != self.session.myId }} .map { $0.sorted(by: { $0.username! < $1.username! })} diff --git a/Sources/Defaults/KeyObject.swift b/Sources/Defaults/KeyObject.swift index 0ade4e83..ddf8aa3a 100644 --- a/Sources/Defaults/KeyObject.swift +++ b/Sources/Defaults/KeyObject.swift @@ -41,6 +41,9 @@ public enum Key: String { case dummyTrafficOn case askedDummyTrafficOnce + + case isReportingEnabled + case isReportingOptional } public struct KeyObjectStore { diff --git a/Sources/Integration/Session/Session.swift b/Sources/Integration/Session/Session.swift index 317a4bae..02836d48 100644 --- a/Sources/Integration/Session/Session.swift +++ b/Sources/Integration/Session/Session.swift @@ -47,6 +47,7 @@ public final class Session: SessionType { @KeyObject(.icognitoKeyboard, defaultValue: false) var icognitoKeyboard: Bool @KeyObject(.pushNotifications, defaultValue: false) var pushNotifications: Bool @KeyObject(.inappnotifications, defaultValue: true) var inappnotifications: Bool + @KeyObject(.isReportingEnabled, defaultValue: true) var isReportingEnabled: Bool @Dependency var backupService: BackupService @Dependency var toastController: ToastController @@ -461,7 +462,7 @@ public final class Session: SessionType { } if let contact = try! dbManager.fetchContacts(.init(id: [request.0.leaderId])).first { - if contact.isBanned || contact.isBlocked { + if isReportingEnabled, (contact.isBlocked || contact.isBanned) { return } } diff --git a/Sources/LaunchFeature/LaunchViewModel.swift b/Sources/LaunchFeature/LaunchViewModel.swift index 399a87a8..81b240eb 100644 --- a/Sources/LaunchFeature/LaunchViewModel.swift +++ b/Sources/LaunchFeature/LaunchViewModel.swift @@ -42,6 +42,7 @@ final class LaunchViewModel { @KeyObject(.username, defaultValue: nil) var username: String? @KeyObject(.biometrics, defaultValue: false) var isBiometricsOn: Bool + @KeyObject(.isReportingEnabled, defaultValue: true) var isReportingEnabled: Bool var hudPublisher: AnyPublisher<HUDStatus, Never> { hudSubject.eraseToAnyPublisher() @@ -138,7 +139,12 @@ final class LaunchViewModel { } func getContactWith(userId: Data) -> Contact? { - let query = Contact.Query(id: [userId], isBlocked: false, isBanned: false) + let query = Contact.Query( + id: [userId], + isBlocked: isReportingEnabled ? false : nil, + isBanned: isReportingEnabled ? false : nil + ) + return try! session.dbManager.fetchContacts(query).first } diff --git a/Sources/MenuFeature/ViewModels/MenuViewModel.swift b/Sources/MenuFeature/ViewModels/MenuViewModel.swift index 35dfd9ec..62be1c13 100644 --- a/Sources/MenuFeature/ViewModels/MenuViewModel.swift +++ b/Sources/MenuFeature/ViewModels/MenuViewModel.swift @@ -10,16 +10,26 @@ final class MenuViewModel { @KeyObject(.avatar, defaultValue: nil) var avatar: Data? @KeyObject(.username, defaultValue: "") var username: String + @KeyObject(.isReportingEnabled, defaultValue: true) var isReportingEnabled: Bool var requestCount: AnyPublisher<Int, Never> { - let groupQuery = Group.Query(authStatus: [.pending], isLeaderBlocked: false, isLeaderBanned: false) - let contactsQuery = Contact.Query(authStatus: [ - .verified, - .confirming, - .confirmationFailed, - .verificationFailed, - .verificationInProgress - ], isBlocked: false, isBanned: false) + let groupQuery = Group.Query( + authStatus: [.pending], + isLeaderBlocked: isReportingEnabled ? false : nil, + isLeaderBanned: isReportingEnabled ? false : nil + ) + + let contactsQuery = Contact.Query( + authStatus: [ + .verified, + .confirming, + .confirmationFailed, + .verificationFailed, + .verificationInProgress + ], + isBlocked: isReportingEnabled ? false : nil, + isBanned: isReportingEnabled ? false : nil + ) return Publishers.CombineLatest( session.dbManager.fetchContactsPublisher(contactsQuery).assertNoFailure(), diff --git a/Sources/PushFeature/PushHandler.swift b/Sources/PushFeature/PushHandler.swift index 9afec926..8f29b148 100644 --- a/Sources/PushFeature/PushHandler.swift +++ b/Sources/PushFeature/PushHandler.swift @@ -12,6 +12,7 @@ public final class PushHandler: PushHandling { } @KeyObject(.pushNotifications, defaultValue: false) var isPushEnabled: Bool + @KeyObject(.isReportingEnabled, defaultValue: true) var isReportingEnabled: Bool let requestAuth: RequestAuth public static let defaultRequestAuth = UNUserNotificationCenter.current().requestAuthorization @@ -108,7 +109,7 @@ public final class PushHandler: PushHandling { return ($0.type.unknownSenderContent!, $0) } - if contact.isBlocked || contact.isBanned { + if isReportingEnabled, (contact.isBlocked || contact.isBanned) { return nil } diff --git a/Sources/RequestsFeature/ViewModels/RequestsReceivedViewModel.swift b/Sources/RequestsFeature/ViewModels/RequestsReceivedViewModel.swift index 5da72d12..650777d1 100644 --- a/Sources/RequestsFeature/ViewModels/RequestsReceivedViewModel.swift +++ b/Sources/RequestsFeature/ViewModels/RequestsReceivedViewModel.swift @@ -19,6 +19,7 @@ struct RequestReceived: Hashable, Equatable { final class RequestsReceivedViewModel { @Dependency private var session: SessionType + @KeyObject(.isReportingEnabled, defaultValue: true) var isReportingEnabled: Bool @KeyObject(.isShowingHiddenRequests, defaultValue: false) var isShowingHiddenRequests: Bool var hudPublisher: AnyPublisher<HUDStatus, Never> { @@ -56,7 +57,10 @@ final class RequestsReceivedViewModel { authStatus: [ .hidden, .pending - ], isLeaderBlocked: false, isLeaderBanned: false) + ], + isLeaderBlocked: isReportingEnabled ? false : nil, + isLeaderBanned: isReportingEnabled ? false : nil + ) let contactsQuery = Contact.Query( authStatus: [ @@ -65,7 +69,10 @@ final class RequestsReceivedViewModel { .verified, .verificationFailed, .verificationInProgress - ], isBlocked: false, isBanned: false) + ], + isBlocked: isReportingEnabled ? false : nil, + isBanned: isReportingEnabled ? false : nil + ) let groupStream = session.dbManager.fetchGroupsPublisher(groupsQuery).assertNoFailure() let contactsStream = session.dbManager.fetchContactsPublisher(contactsQuery).assertNoFailure() diff --git a/Sources/RequestsFeature/ViewModels/RequestsSentViewModel.swift b/Sources/RequestsFeature/ViewModels/RequestsSentViewModel.swift index 26a6f485..fa902162 100644 --- a/Sources/RequestsFeature/ViewModels/RequestsSentViewModel.swift +++ b/Sources/RequestsFeature/ViewModels/RequestsSentViewModel.swift @@ -3,6 +3,7 @@ import UIKit import Models import Shared import Combine +import Defaults import XXModels import Integration import ToastFeature @@ -18,6 +19,8 @@ final class RequestsSentViewModel { @Dependency private var session: SessionType @Dependency private var toastController: ToastController + @KeyObject(.isReportingEnabled, defaultValue: true) var isReportingEnabled: Bool + var hudPublisher: AnyPublisher<HUDStatus, Never> { hudSubject.eraseToAnyPublisher() } @@ -33,10 +36,14 @@ final class RequestsSentViewModel { var backgroundScheduler: AnySchedulerOf<DispatchQueue> = DispatchQueue.global().eraseToAnyScheduler() init() { - let query = Contact.Query(authStatus: [ - .requested, - .requesting - ], isBlocked: false, isBanned: false) + let query = Contact.Query( + authStatus: [ + .requested, + .requesting + ], + isBlocked: isReportingEnabled ? false : nil, + isBanned: isReportingEnabled ? false : nil + ) session.dbManager.fetchContactsPublisher(query) .assertNoFailure() diff --git a/Sources/SearchFeature/ViewModels/SearchLeftViewModel.swift b/Sources/SearchFeature/ViewModels/SearchLeftViewModel.swift index d5ea157d..f7dfe937 100644 --- a/Sources/SearchFeature/ViewModels/SearchLeftViewModel.swift +++ b/Sources/SearchFeature/ViewModels/SearchLeftViewModel.swift @@ -3,6 +3,7 @@ import UIKit import Shared import Combine import XXModels +import Defaults import Countries import Integration import NetworkMonitor @@ -21,6 +22,8 @@ final class SearchLeftViewModel { @Dependency var session: SessionType @Dependency var networkMonitor: NetworkMonitoring + @KeyObject(.isReportingEnabled, defaultValue: true) var isReportingEnabled: Bool + var hudPublisher: AnyPublisher<HUDStatus, Never> { hudSubject.eraseToAnyPublisher() } @@ -150,7 +153,10 @@ final class SearchLeftViewModel { user.authStatus = contact.authStatus } - if user.authStatus != .friend, !user.isBanned, !user.isBlocked { + if user.authStatus != .friend, !isReportingEnabled { + snapshot.appendSections([.stranger]) + snapshot.appendItems([.stranger(user)], toSection: .stranger) + } else if user.authStatus != .friend, isReportingEnabled, !user.isBanned, !user.isBlocked { snapshot.appendSections([.stranger]) snapshot.appendItems([.stranger(user)], toSection: .stranger) } @@ -159,8 +165,8 @@ final class SearchLeftViewModel { let localsQuery = Contact.Query( text: stateSubject.value.input, authStatus: [.friend], - isBlocked: false, - isBanned: false + isBlocked: isReportingEnabled ? false : nil, + isBanned: isReportingEnabled ? false : nil ) if let locals = try? session.dbManager.fetchContacts(localsQuery), diff --git a/Sources/SearchFeature/ViewModels/SearchRightViewModel.swift b/Sources/SearchFeature/ViewModels/SearchRightViewModel.swift index 148db4ca..e70b2d36 100644 --- a/Sources/SearchFeature/ViewModels/SearchRightViewModel.swift +++ b/Sources/SearchFeature/ViewModels/SearchRightViewModel.swift @@ -1,6 +1,7 @@ import Shared import Combine import XXModels +import Defaults import Foundation import Permissions import Integration @@ -24,6 +25,8 @@ final class SearchRightViewModel { @Dependency var session: SessionType @Dependency var permissions: PermissionHandling + @KeyObject(.isReportingEnabled, defaultValue: true) var isReportingEnabled: Bool + var foundPublisher: AnyPublisher<Contact, Never> { foundSubject.eraseToAnyPublisher() } @@ -78,12 +81,12 @@ final class SearchRightViewModel { /// that we already have /// if let alreadyContact = try? session.dbManager.fetchContacts(.init(id: [userId])).first { - if alreadyContact.isBlocked { + if alreadyContact.isBlocked, isReportingEnabled { statusSubject.send(.failed(.unknown("You previously blocked this user."))) return } - if alreadyContact.isBanned { + if alreadyContact.isBanned, isReportingEnabled { statusSubject.send(.failed(.unknown("This user was banned."))) return } diff --git a/Sources/SettingsFeature/Controllers/SettingsAdvancedController.swift b/Sources/SettingsFeature/Controllers/SettingsAdvancedController.swift index a7d92763..16d474d8 100644 --- a/Sources/SettingsFeature/Controllers/SettingsAdvancedController.swift +++ b/Sources/SettingsFeature/Controllers/SettingsAdvancedController.swift @@ -61,17 +61,29 @@ public final class SettingsAdvancedController: UIViewController { .sink { [weak viewModel] in viewModel?.didToggleCrashReporting() } .store(in: &cancellables) + screenView.reportingSwitcher.switcherView + .publisher(for: .valueChanged) + .sink { [weak viewModel] in viewModel?.didToggleReporting() } + .store(in: &cancellables) + viewModel.sharePublisher .receive(on: DispatchQueue.main) .sink { [unowned self] in coordinator.toActivityController(with: [$0], from: self) } .store(in: &cancellables) + viewModel.state + .removeDuplicates() + .map(\.isReportingOptional) + .sink { [unowned self] in screenView.reportingSwitcher.isHidden = !$0 } + .store(in: &cancellables) + viewModel.state .removeDuplicates() .sink { [unowned self] state in screenView.logRecordingSwitcher.switcherView.setOn(state.isRecordingLogs, animated: true) screenView.crashReportingSwitcher.switcherView.setOn(state.isCrashReporting, animated: true) screenView.showUsernamesSwitcher.switcherView.setOn(state.isShowingUsernames, animated: true) + screenView.reportingSwitcher.switcherView.setOn(state.isReportingEnabled, animated: true) }.store(in: &cancellables) } } diff --git a/Sources/SettingsFeature/ViewModels/SettingsAdvancedViewModel.swift b/Sources/SettingsFeature/ViewModels/SettingsAdvancedViewModel.swift index 87170244..60e7f5e7 100644 --- a/Sources/SettingsFeature/ViewModels/SettingsAdvancedViewModel.swift +++ b/Sources/SettingsFeature/ViewModels/SettingsAdvancedViewModel.swift @@ -9,12 +9,17 @@ struct AdvancedViewState: Equatable { var isRecordingLogs = false var isCrashReporting = false var isShowingUsernames = false + var isReportingEnabled = false + var isReportingOptional = false } final class SettingsAdvancedViewModel { @KeyObject(.recordingLogs, defaultValue: true) var isRecordingLogs: Bool @KeyObject(.crashReporting, defaultValue: true) var isCrashReporting: Bool + @KeyObject(.isReportingEnabled, defaultValue: true) var isReportingEnabled: Bool + @KeyObject(.isReportingOptional, defaultValue: true) var isReportingOptional: Bool + private let isShowingUsernamesKey = "isShowingUsernames" @Dependency private var logger: XXLogger @@ -29,6 +34,8 @@ final class SettingsAdvancedViewModel { func loadCachedSettings() { stateRelay.value.isRecordingLogs = isRecordingLogs stateRelay.value.isCrashReporting = isCrashReporting + stateRelay.value.isReportingEnabled = isReportingEnabled + stateRelay.value.isReportingOptional = isReportingOptional guard let defaults = UserDefaults(suiteName: "group.elixxir.messenger") else { print("^^^ Couldn't access user defaults in the app group container \(#file):\(#line)") @@ -75,4 +82,9 @@ final class SettingsAdvancedViewModel { stateRelay.value.isCrashReporting.toggle() crashReporter.setEnabled(isCrashReporting) } + + func didToggleReporting() { + isReportingEnabled.toggle() + stateRelay.value.isReportingEnabled.toggle() + } } diff --git a/Sources/SettingsFeature/Views/SettingsAdvancedView.swift b/Sources/SettingsFeature/Views/SettingsAdvancedView.swift index fb3df7c7..0e5e5d89 100644 --- a/Sources/SettingsFeature/Views/SettingsAdvancedView.swift +++ b/Sources/SettingsFeature/Views/SettingsAdvancedView.swift @@ -7,6 +7,7 @@ final class SettingsAdvancedView: UIView { let logRecordingSwitcher = SettingsSwitcher() let crashReportingSwitcher = SettingsSwitcher() let showUsernamesSwitcher = SettingsSwitcher() + let reportingSwitcher = SettingsSwitcher() init() { super.init(frame: .zero) @@ -33,21 +34,29 @@ final class SettingsAdvancedView: UIView { icon: Asset.settingsCrash.image ) + reportingSwitcher.set( + title: Localized.Settings.Advanced.Reporting.title, + text: Localized.Settings.Advanced.Reporting.description, + icon: Asset.settingsCrash.image + ) + stackView.axis = .vertical stackView.addArrangedSubview(logRecordingSwitcher) stackView.addArrangedSubview(crashReportingSwitcher) stackView.addArrangedSubview(showUsernamesSwitcher) + stackView.addArrangedSubview(reportingSwitcher) stackView.setCustomSpacing(20, after: logRecordingSwitcher) stackView.setCustomSpacing(10, after: crashReportingSwitcher) stackView.setCustomSpacing(10, after: showUsernamesSwitcher) + stackView.setCustomSpacing(10, after: reportingSwitcher) addSubview(stackView) - stackView.snp.makeConstraints { make in - make.top.equalToSuperview().offset(24) - make.left.equalToSuperview().offset(16) - make.right.equalToSuperview().offset(-16) + stackView.snp.makeConstraints { + $0.top.equalToSuperview().offset(24) + $0.left.equalToSuperview().offset(16) + $0.right.equalToSuperview().offset(-16) } } diff --git a/Sources/Shared/AutoGenerated/Strings.swift b/Sources/Shared/AutoGenerated/Strings.swift index afcdff24..975cacad 100644 --- a/Sources/Shared/AutoGenerated/Strings.swift +++ b/Sources/Shared/AutoGenerated/Strings.swift @@ -1110,6 +1110,12 @@ public enum Localized { /// Record logs public static let title = Localized.tr("Localizable", "settings.advanced.logs.title") } + public enum Reporting { + /// Allows you to report users sending innapropriate content + public static let description = Localized.tr("Localizable", "settings.advanced.reporting.description") + /// Enable user reporting feature + public static let title = Localized.tr("Localizable", "settings.advanced.reporting.title") + } public enum ShowUsername { /// Allow us to show a more detailed push notification public static let description = Localized.tr("Localizable", "settings.advanced.showUsername.description") diff --git a/Sources/Shared/Resources/en.lproj/Localizable.strings b/Sources/Shared/Resources/en.lproj/Localizable.strings index 6b61f437..24d260d8 100644 --- a/Sources/Shared/Resources/en.lproj/Localizable.strings +++ b/Sources/Shared/Resources/en.lproj/Localizable.strings @@ -630,6 +630,10 @@ = "Enable crash reporting"; "settings.advanced.crashes.description" = "Automatically sends anonymous reports containing crash data"; +"settings.advanced.reporting.title" += "Enable user reporting feature"; +"settings.advanced.reporting.description" += "Allows you to report users sending innapropriate content"; "settings.advanced.accountBackup.title" = "Account Backup"; -- GitLab