diff --git a/kDrive/UI/Controller/Menu/StoreViewController.swift b/kDrive/UI/Controller/Menu/StoreViewController.swift index c164a5285..ff4742401 100644 --- a/kDrive/UI/Controller/Menu/StoreViewController.swift +++ b/kDrive/UI/Controller/Menu/StoreViewController.swift @@ -65,7 +65,7 @@ final class StoreViewController: UICollectionViewController, SceneStateRestorabl private var purchaseEnabled = true private var items = Item.allItems - private lazy var selectedPackId = DrivePackId(rawValue: driveFileManager.drive.pack.id) + private lazy var selectedPackId = DrivePackId(rawValue: driveFileManager.drive.pack.name) private var selectedStorage = 1 private var selectedPeriod = PeriodTab.yearly { didSet { updateOffers() } diff --git a/kDrive/UI/View/Files/FileDetail/FileDetailActivityTableViewCell.swift b/kDrive/UI/View/Files/FileDetail/FileDetailActivityTableViewCell.swift index abaf87234..8512093d3 100644 --- a/kDrive/UI/View/Files/FileDetail/FileDetailActivityTableViewCell.swift +++ b/kDrive/UI/View/Files/FileDetail/FileDetailActivityTableViewCell.swift @@ -133,7 +133,7 @@ class FileDetailActivityTableViewCell: InsetTableViewCell { localizedKey = "fileDetailsActivityFileColorUpdate" case .fileColorDelete: localizedKey = "fileDetailsActivityFileColorDelete" - case .none: + case .unknown: localizedKey = "fileActivityUnknown" } detailLabel.text = localizedKey.localized diff --git a/kDriveCore/Data/Models/Drive/Drive.swift b/kDriveCore/Data/Models/Drive/Drive.swift index aeb0eeed9..9a60185d1 100644 --- a/kDriveCore/Data/Models/Drive/Drive.swift +++ b/kDriveCore/Data/Models/Drive/Drive.swift @@ -52,6 +52,14 @@ public enum MaintenanceReason: String, PersistableEnum, Codable { case demoEnd = "demo_end" case invoiceOverdue = "invoice_overdue" case technical + case unknown + + public init(from decoder: any Decoder) throws { + let singleKeyContainer = try decoder.singleValueContainer() + let value = try singleKeyContainer.decode(String.self) + + self = MaintenanceReason(rawValue: value) ?? .unknown + } } public final class DrivePreferences: EmbeddedObject, Codable { @@ -135,11 +143,7 @@ public final class Drive: Object, Codable { } public var isFreePack: Bool { - guard let packId = pack.drivePackId else { - return false - } - - return packId == .free + return pack.drivePackId == .free } public var isInTechnicalMaintenance: Bool { diff --git a/kDriveCore/Data/Models/Drive/DrivePack.swift b/kDriveCore/Data/Models/Drive/DrivePack.swift index 4a320e230..e5a0c96c7 100644 --- a/kDriveCore/Data/Models/Drive/DrivePack.swift +++ b/kDriveCore/Data/Models/Drive/DrivePack.swift @@ -19,14 +19,21 @@ import Foundation import RealmSwift -public enum DrivePackId: Int { - case solo = 1 - case team = 2 - case pro = 3 - case free = 6 - case kSuiteStandard = 8 - case kSuitePro = 11 - case kSuiteEntreprise = 14 +public enum DrivePackId: String { + case solo + case team + case pro + case free + case kSuiteStandard = "ksuite_standard" + case kSuitePro = "ksuite_pro" + case kSuiteEntreprise = "ksuite_entreprise" + case myKSuite = "my_ksuite" + case myKSuitePlus = "my_ksuite_plus" + case unknown + + public init(apiRawValue: String) { + self = .init(rawValue: apiRawValue) ?? .unknown + } } public class DrivePack: EmbeddedObject, Codable { @@ -39,8 +46,8 @@ public class DrivePack: EmbeddedObject, Codable { } /// Convenience enum bridge - public var drivePackId: DrivePackId? { - DrivePackId(rawValue: id) + public var drivePackId: DrivePackId { + DrivePackId(apiRawValue: name) } enum CodingKeys: String, CodingKey { diff --git a/kDriveCore/Data/Models/DriveUser.swift b/kDriveCore/Data/Models/DriveUser.swift index c02ccfa56..0daccfe76 100644 --- a/kDriveCore/Data/Models/DriveUser.swift +++ b/kDriveCore/Data/Models/DriveUser.swift @@ -26,6 +26,14 @@ public enum DriveUserRole: String, Codable { case admin case user case external + case unknown + + public init(from decoder: any Decoder) throws { + let singleKeyContainer = try decoder.singleValueContainer() + let value = try singleKeyContainer.decode(String.self) + + self = DriveUserRole(rawValue: value) ?? .unknown + } } public enum UserPermission: String, Codable, CaseIterable { diff --git a/kDriveCore/Data/Models/File.swift b/kDriveCore/Data/Models/File.swift index ecf725049..2efa71c48 100644 --- a/kDriveCore/Data/Models/File.swift +++ b/kDriveCore/Data/Models/File.swift @@ -181,6 +181,10 @@ public enum ConvertedType: String, CaseIterable { public static let ignoreThumbnailTypes = downloadableTypes /// Documents that can be previewed by the OS but not necessarily handled by OnlyOffice (eg. .pages) public static let documentTypes: Set = [.presentation, .spreadsheet, .text] + + public init(apiRawValue: String) { + self = .init(rawValue: apiRawValue) ?? .unknown + } } /// Minimal data needed to query a PublicShare @@ -321,7 +325,20 @@ public enum FileStatus: String { public enum FileImportStatus: String, PersistableEnum, Codable { // ⚠️ For some reason PersistableEnum breaks something with key decoding, that's why we are explicitly writing snake case - case waiting, inProgress = "in_progress", done, failed, canceling, canceled + case waiting + case inProgress = "in_progress" + case done + case failed + case canceling + case canceled + case unknown + + public init(from decoder: any Decoder) throws { + let singleKeyContainer = try decoder.singleValueContainer() + let value = try singleKeyContainer.decode(String.self) + + self = FileImportStatus(rawValue: value) ?? .unknown + } } public final class FileExternalImport: EmbeddedObject, Codable { @@ -370,6 +387,15 @@ public enum FileSupportedBy: String, PersistableEnum, Codable { case thumbnail /// This file can be read by OnlyOffice case onlyOffice = "onlyoffice" + + case unknown + + public init(from decoder: any Decoder) throws { + let singleKeyContainer = try decoder.singleValueContainer() + let value = try singleKeyContainer.decode(String.self) + + self = FileSupportedBy(rawValue: value) ?? .unknown + } } public typealias FileCursor = String @@ -666,7 +692,7 @@ public final class File: Object, Codable { } else if isBookmark { return .url } else { - return ConvertedType(rawValue: extensionType ?? "") ?? .unknown + return ConvertedType(apiRawValue: extensionType ?? "") } } @@ -840,9 +866,9 @@ public final class File: Object, Codable { dropbox = try container.decodeIfPresent(DropBox.self, forKey: .dropbox) externalImport = try container.decodeIfPresent(FileExternalImport.self, forKey: .externalImport) size = try container.decodeIfPresent(Int.self, forKey: .size) - let rawSupportedBy = try container.decodeIfPresent([String].self, forKey: .supportedBy) ?? [] + let rawSupportedBy = try container.decodeIfPresent([FileSupportedBy].self, forKey: .supportedBy) ?? [] supportedBy = MutableSet() - supportedBy.insert(objectsIn: rawSupportedBy.compactMap { FileSupportedBy(rawValue: $0) }) + supportedBy.insert(objectsIn: rawSupportedBy.filter { $0 != .unknown }) extensionType = try container.decodeIfPresent(String.self, forKey: .extensionType) version = try container.decodeIfPresent(FileVersion.self, forKey: .version) conversion = try container.decodeIfPresent(FileConversion.self, forKey: .conversion) diff --git a/kDriveCore/Data/Models/FileActivity.swift b/kDriveCore/Data/Models/FileActivity.swift index 14aff36a1..b3ddc4049 100644 --- a/kDriveCore/Data/Models/FileActivity.swift +++ b/kDriveCore/Data/Models/FileActivity.swift @@ -58,6 +58,7 @@ public enum FileActivityType: String, Codable, CaseIterable { case collaborativeUserDelete = "collaborative_user_delete" case fileColorUpdate = "file_color_update" case fileColorDelete = "file_color_delete" + case unknown public static let displayedFileActivities: [FileActivityType] = [ .fileCreate, @@ -85,6 +86,10 @@ public enum FileActivityType: String, Codable, CaseIterable { .fileColorUpdate, .fileColorDelete ] + + public init(apiRawValue: String) { + self = .init(rawValue: apiRawValue) ?? .unknown + } } public class FileActivity: Object, Decodable { @@ -109,8 +114,8 @@ public class FileActivity: Object, Decodable { public var mergedFileActivities: [FileActivity] = [] /// Activity type - public var action: FileActivityType? { - return FileActivityType(rawValue: rawAction) + public var action: FileActivityType { + return FileActivityType(apiRawValue: rawAction) } public var user: DriveUser? {