Skip to content
Snippets Groups Projects
SettingsAdvancedViewModel.swift 3.09 KiB
Newer Older
Bruno Muniz's avatar
Bruno Muniz committed
import Combine
import XXLogger
import Defaults
import Foundation
import CrashReporting
import ReportingFeature
Bruno Muniz's avatar
Bruno Muniz committed
import DependencyInjection

struct AdvancedViewState: Equatable {
    var isRecordingLogs = false
    var isCrashReporting = false
Ahmed Shehata's avatar
Ahmed Shehata committed
    var isShowingUsernames = false
    var isReportingEnabled = false
    var isReportingOptional = false
Bruno Muniz's avatar
Bruno Muniz committed
}

final class SettingsAdvancedViewModel {
Bruno Muniz's avatar
Bruno Muniz committed
    @KeyObject(.recordingLogs, defaultValue: true) var isRecordingLogs: Bool
    @KeyObject(.crashReporting, defaultValue: true) var isCrashReporting: Bool

Bruno Muniz's avatar
Bruno Muniz committed
    private var cancellables = Set<AnyCancellable>()
Ahmed Shehata's avatar
Ahmed Shehata committed
    private let isShowingUsernamesKey = "isShowingUsernames"

Bruno Muniz's avatar
Bruno Muniz committed
    @Dependency private var logger: XXLogger
    @Dependency private var crashReporter: CrashReporter
    @Dependency private var reportingStatus: ReportingStatus
Bruno Muniz's avatar
Bruno Muniz committed

    var sharePublisher: AnyPublisher<URL, Never> { shareRelay.eraseToAnyPublisher() }
    private let shareRelay = PassthroughSubject<URL, Never>()

    var state: AnyPublisher<AdvancedViewState, Never> { stateRelay.eraseToAnyPublisher() }
    private let stateRelay = CurrentValueSubject<AdvancedViewState, Never>(.init())

    func loadCachedSettings() {
        stateRelay.value.isRecordingLogs = isRecordingLogs
        stateRelay.value.isCrashReporting = isCrashReporting
        stateRelay.value.isReportingOptional = reportingStatus.isOptional()
Ahmed Shehata's avatar
Ahmed Shehata committed

Bruno Muniz's avatar
Bruno Muniz committed
        reportingStatus
            .isEnabledPublisher()
            .sink { [weak stateRelay] in stateRelay?.value.isReportingEnabled = $0 }
            .store(in: &cancellables)

Ahmed Shehata's avatar
Ahmed Shehata committed
        guard let defaults = UserDefaults(suiteName: "group.elixxir.messenger") else {
            print("^^^ Couldn't access user defaults in the app group container \(#file):\(#line)")
            return
        }

        guard let isShowingUsernames = defaults.value(forKey: isShowingUsernamesKey) as? Bool else {
            defaults.set(false, forKey: isShowingUsernamesKey)
            return
        }

        stateRelay.value.isShowingUsernames = isShowingUsernames
    }

    func didToggleShowUsernames() {
        stateRelay.value.isShowingUsernames.toggle()

        guard let defaults = UserDefaults(suiteName: "group.elixxir.messenger") else {
            print("^^^ Couldn't access user defaults in the app group container \(#file):\(#line)")
            return
        }

        defaults.set(stateRelay.value.isShowingUsernames, forKey: isShowingUsernamesKey)
Bruno Muniz's avatar
Bruno Muniz committed
    }

    func didToggleRecordLogs() {
        if isRecordingLogs == true {
            XXLogger.stop()
        } else {
            XXLogger.start()
        }

        isRecordingLogs.toggle()
        stateRelay.value.isRecordingLogs.toggle()
    }

    func didTapDownloadLogs() {
        let url = FileManager.default.urls(for: .cachesDirectory, in: .userDomainMask)[0]
        shareRelay.send(url.appendingPathComponent("swiftybeaver.log"))
    }

    func didToggleCrashReporting() {
        isCrashReporting.toggle()
        stateRelay.value.isCrashReporting.toggle()
        crashReporter.setEnabled(isCrashReporting)
    }
Bruno Muniz's avatar
Bruno Muniz committed
    func didSetReporting(enabled: Bool) {
        reportingStatus.enable(enabled)
Bruno Muniz's avatar
Bruno Muniz committed
}