mirror of
https://github.com/yattee/yattee.git
synced 2024-11-15 10:38:22 +00:00
194 lines
6.7 KiB
Swift
194 lines
6.7 KiB
Swift
|
import Defaults
|
||
|
import Foundation
|
||
|
import SwiftUI
|
||
|
import SwiftyJSON
|
||
|
|
||
|
final class ImportExportSettingsModel: ObservableObject {
|
||
|
static let shared = ImportExportSettingsModel()
|
||
|
|
||
|
static var exportFile: URL {
|
||
|
YatteeApp.settingsExportDirectory
|
||
|
.appendingPathComponent("Yattee Settings from \(Constants.deviceName).\(settingsExtension)")
|
||
|
}
|
||
|
|
||
|
static var settingsExtension: String {
|
||
|
"yatteesettings"
|
||
|
}
|
||
|
|
||
|
enum ExportGroup: String, Identifiable, CaseIterable {
|
||
|
case browsingSettings
|
||
|
case playerSettings
|
||
|
case controlsSettings
|
||
|
case qualitySettings
|
||
|
case historySettings
|
||
|
case sponsorBlockSettings
|
||
|
case advancedSettings
|
||
|
|
||
|
case locationsSettings
|
||
|
case instances
|
||
|
case accounts
|
||
|
case accountsUnencryptedPasswords
|
||
|
|
||
|
case recentlyOpened
|
||
|
case otherData
|
||
|
|
||
|
static var settingsGroups: [Self] {
|
||
|
[.browsingSettings, .playerSettings, .controlsSettings, .qualitySettings, .historySettings, .sponsorBlockSettings, .advancedSettings]
|
||
|
}
|
||
|
|
||
|
static var locationsGroups: [Self] {
|
||
|
[.locationsSettings, .instances, .accounts, .accountsUnencryptedPasswords]
|
||
|
}
|
||
|
|
||
|
static var otherGroups: [Self] {
|
||
|
[.recentlyOpened, .otherData]
|
||
|
}
|
||
|
|
||
|
var id: RawValue {
|
||
|
rawValue
|
||
|
}
|
||
|
|
||
|
var label: String {
|
||
|
switch self {
|
||
|
case .browsingSettings:
|
||
|
"Browsing"
|
||
|
case .playerSettings:
|
||
|
"Player"
|
||
|
case .controlsSettings:
|
||
|
"Controls"
|
||
|
case .qualitySettings:
|
||
|
"Quality"
|
||
|
case .historySettings:
|
||
|
"History"
|
||
|
case .sponsorBlockSettings:
|
||
|
"SponsorBlock"
|
||
|
case .locationsSettings:
|
||
|
"Public Locations"
|
||
|
case .instances:
|
||
|
"Custom Locations"
|
||
|
case .accounts:
|
||
|
"Accounts"
|
||
|
case .accountsUnencryptedPasswords:
|
||
|
"Accounts passwords (unencrypted)"
|
||
|
case .advancedSettings:
|
||
|
"Advanced"
|
||
|
case .recentlyOpened:
|
||
|
"Recents"
|
||
|
case .otherData:
|
||
|
"Other data"
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
@Published var selectedExportGroups = Set<ExportGroup>()
|
||
|
static var defaultExportGroups = Set<ExportGroup>([
|
||
|
.browsingSettings,
|
||
|
.playerSettings,
|
||
|
.controlsSettings,
|
||
|
.qualitySettings,
|
||
|
.historySettings,
|
||
|
.sponsorBlockSettings,
|
||
|
.locationsSettings,
|
||
|
.instances,
|
||
|
.accounts,
|
||
|
.advancedSettings
|
||
|
])
|
||
|
|
||
|
@Published var isExportInProgress = false
|
||
|
|
||
|
private var navigation = NavigationModel.shared
|
||
|
private var settings = SettingsModel.shared
|
||
|
|
||
|
func toggleExportGroupSelection(_ group: ExportGroup) {
|
||
|
if isGroupSelected(group) {
|
||
|
selectedExportGroups.remove(group)
|
||
|
} else {
|
||
|
selectedExportGroups.insert(group)
|
||
|
}
|
||
|
|
||
|
removeNotEnabledSelectedGroups()
|
||
|
}
|
||
|
|
||
|
func reset() {
|
||
|
isExportInProgress = false
|
||
|
selectedExportGroups = Self.defaultExportGroups
|
||
|
}
|
||
|
|
||
|
func reset(_ model: ImportSettingsFileModel? = nil) {
|
||
|
reset()
|
||
|
|
||
|
guard let model else { return }
|
||
|
|
||
|
selectedExportGroups = selectedExportGroups.filter { model.isGroupIncludedInFile($0) }
|
||
|
}
|
||
|
|
||
|
func exportAction() {
|
||
|
DispatchQueue.global(qos: .background).async { [weak self] in
|
||
|
var writingOptions: JSONSerialization.WritingOptions = []
|
||
|
#if DEBUG
|
||
|
writingOptions.insert(.prettyPrinted)
|
||
|
writingOptions.insert(.sortedKeys)
|
||
|
#endif
|
||
|
try? self?.jsonForExport?.rawString(options: writingOptions)?.write(to: Self.exportFile, atomically: true, encoding: String.Encoding.utf8)
|
||
|
#if os(macOS)
|
||
|
DispatchQueue.main.async { [weak self] in
|
||
|
self?.isExportInProgress = false
|
||
|
}
|
||
|
NSWorkspace.shared.selectFile(Self.exportFile.path, inFileViewerRootedAtPath: YatteeApp.settingsExportDirectory.path)
|
||
|
#endif
|
||
|
}
|
||
|
}
|
||
|
|
||
|
private var jsonForExport: JSON? {
|
||
|
[
|
||
|
"metadata": metadataJSON,
|
||
|
"browsingSettings": selectedExportGroups.contains(.browsingSettings) ? BrowsingSettingsGroupExporter().exportJSON : JSON(),
|
||
|
"playerSettings": selectedExportGroups.contains(.playerSettings) ? PlayerSettingsGroupExporter().exportJSON : JSON(),
|
||
|
"controlsSettings": selectedExportGroups.contains(.controlsSettings) ? ConstrolsSettingsGroupExporter().exportJSON : JSON(),
|
||
|
"qualitySettings": selectedExportGroups.contains(.qualitySettings) ? QualitySettingsGroupExporter().exportJSON : JSON(),
|
||
|
"historySettings": selectedExportGroups.contains(.historySettings) ? HistorySettingsGroupExporter().exportJSON : JSON(),
|
||
|
"sponsorBlockSettings": selectedExportGroups.contains(.sponsorBlockSettings) ? SponsorBlockSettingsGroupExporter().exportJSON : JSON(),
|
||
|
"locationsSettings": LocationsSettingsGroupExporter(
|
||
|
includePublicInstances: isGroupSelected(.locationsSettings),
|
||
|
includeInstances: isGroupSelected(.instances),
|
||
|
includeAccounts: isGroupSelected(.accounts),
|
||
|
includeAccountsUnencryptedPasswords: isGroupSelected(.accountsUnencryptedPasswords)
|
||
|
).exportJSON,
|
||
|
"advancedSettings": selectedExportGroups.contains(.advancedSettings) ? AdvancedSettingsGroupExporter().exportJSON : JSON(),
|
||
|
"recentlyOpened": selectedExportGroups.contains(.recentlyOpened) ? RecentlyOpenedExporter().exportJSON : JSON(),
|
||
|
"otherData": selectedExportGroups.contains(.otherData) ? OtherDataSettingsGroupExporter().exportJSON : JSON()
|
||
|
]
|
||
|
}
|
||
|
|
||
|
private var metadataJSON: JSON {
|
||
|
[
|
||
|
"build": YatteeApp.build,
|
||
|
"timestamp": "\(Date().timeIntervalSince1970)",
|
||
|
"platform": Constants.platform
|
||
|
]
|
||
|
}
|
||
|
|
||
|
func isGroupSelected(_ group: ExportGroup) -> Bool {
|
||
|
selectedExportGroups.contains(group)
|
||
|
}
|
||
|
|
||
|
func isGroupEnabled(_ group: ExportGroup) -> Bool {
|
||
|
switch group {
|
||
|
case .accounts:
|
||
|
return selectedExportGroups.contains(.instances)
|
||
|
case .accountsUnencryptedPasswords:
|
||
|
return selectedExportGroups.contains(.instances) && selectedExportGroups.contains(.accounts)
|
||
|
default:
|
||
|
return true
|
||
|
}
|
||
|
}
|
||
|
|
||
|
func removeNotEnabledSelectedGroups() {
|
||
|
selectedExportGroups = selectedExportGroups.filter { isGroupEnabled($0) }
|
||
|
}
|
||
|
|
||
|
var isExportAvailable: Bool {
|
||
|
!selectedExportGroups.isEmpty && !isExportInProgress
|
||
|
}
|
||
|
}
|