diff --git a/MVMCoreUI/Atomic/Atoms/Views/TileContainerModel.swift b/MVMCoreUI/Atomic/Atoms/Views/TileContainerModel.swift index 72ffb974..9933cdf1 100644 --- a/MVMCoreUI/Atomic/Atoms/Views/TileContainerModel.swift +++ b/MVMCoreUI/Atomic/Atoms/Views/TileContainerModel.swift @@ -20,8 +20,11 @@ open class TileContainerModel: TileContainerBaseModel, MoleculeModelProtocol { public var padding: TileContainer.Padding = .padding4X public var aspectRatio: TileContainer.AspectRatio = .ratio1x1 public var color: TileContainer.BackgroundColor = .secondary - public var backgroundEffect: TileContainer.BackgroundEffect = .none public var molecule: MoleculeModelProtocol? + public var backgroundEffect: TileContainer.BackgroundEffect { + guard let effect = backgroundEffectContainer else { return .none } + return .convert(from: effect) + } private enum CodingKeys: String, CodingKey { case id @@ -30,7 +33,6 @@ open class TileContainerModel: TileContainerBaseModel, MoleculeModelProtocol { case padding case aspectRatio case color - case backgroundEffect } required public init(from decoder: Decoder) throws { let container = try decoder.container(keyedBy: CodingKeys.self) @@ -38,7 +40,6 @@ open class TileContainerModel: TileContainerBaseModel, MoleculeModelProtocol { molecule = try container.decodeModelIfPresent(codingKey: .molecule) padding = try container.decodeIfPresent(TileContainer.Padding.self, forKey: .padding) ?? .padding4X color = try container.decodeIfPresent(TileContainer.BackgroundColor.self, forKey: .color) ?? .secondary - backgroundEffect = try container.decodeIfPresent(TileContainer.BackgroundEffect.self, forKey: .backgroundEffect) ?? .none aspectRatio = try container.decodeIfPresent(TileContainer.AspectRatio.self, forKey: .aspectRatio) ?? .none try super.init(from: decoder) } @@ -50,7 +51,6 @@ open class TileContainerModel: TileContainerBaseModel, MoleculeModelProtocol { try container.encodeModelIfPresent(molecule, forKey: .molecule) try container.encodeIfPresent(padding, forKey: .padding) try container.encodeIfPresent(color, forKey: .color) - try container.encodeIfPresent(backgroundEffect, forKey: .backgroundEffect) try container.encodeIfPresent(aspectRatio, forKey: .aspectRatio) try super.encode(to: encoder) } @@ -69,6 +69,7 @@ open class TileContainerBaseModel: Codable { public var height: CGFloat? public var showBorder: Bool = false public var showDropShadwows: Bool = false + internal var backgroundEffectContainer: BackgroundEffectContainer? private enum CodingKeys: String, CodingKey { case backgroundImage @@ -79,6 +80,7 @@ open class TileContainerBaseModel: Codable { case height case showBorder case showDropShadows + case backgroundEffect } required public init(from decoder: Decoder) throws { let container = try decoder.container(keyedBy: CodingKeys.self) @@ -86,6 +88,7 @@ open class TileContainerBaseModel: Codable { width = try container.decodeIfPresent(CGFloat.self, forKey: .width) height = try container.decodeIfPresent(CGFloat.self, forKey: .height) action = try container.decodeModelIfPresent(codingKey: .action) + backgroundEffectContainer = try container.decodeIfPresent(BackgroundEffectContainer.self, forKey: .backgroundEffect) } public func encode(to encoder: Encoder) throws { @@ -93,8 +96,65 @@ open class TileContainerBaseModel: Codable { try container.encodeIfPresent(backgroundImage, forKey: .backgroundImage) try container.encodeIfPresent(width, forKey: .width) try container.encodeIfPresent(height, forKey: .height) + try container.encodeIfPresent(backgroundEffectContainer, forKey: .backgroundEffect) try container.encodeModelIfPresent(action, forKey: .action) } - - +} + +internal struct BackgroundEffectContainer: Codable { + public enum BackgroundEffectType: String, Codable { + case transparency + case none + case gradient + } + + public struct GradientValue: Codable { + public let firstColor: String + public let secondColor: String + } + + private enum CodingKeys: String, CodingKey { + case type + case value + } + + public let type: BackgroundEffectType + public let value: GradientValue? + + public init(from decoder: Decoder) throws { + let container = try decoder.container(keyedBy: CodingKeys.self) + type = try container.decode(BackgroundEffectType.self, forKey: .type) + if type == .gradient { + value = try container.decode(GradientValue.self, forKey: .value) + } else { + value = nil + } + } + + public func encode(to encoder: Encoder) throws { + var container = encoder.container(keyedBy: CodingKeys.self) + try container.encode(type, forKey: .type) + switch type { + case .transparency, .none: + break // No value to encode + case .gradient: + try container.encode(value, forKey: .value) + } + } +} + +extension TileContainerBase.BackgroundEffect { + internal static func convert(from effect: BackgroundEffectContainer) -> Self { + switch effect.type { + case .transparency: + return .transparency + case .none: + return .none + case .gradient: + guard let value = effect.value else { + fatalError("Gradient must have a value") + } + return .gradient(value.firstColor, value.secondColor) + } + } } diff --git a/MVMCoreUI/Atomic/Atoms/Views/TileletModel.swift b/MVMCoreUI/Atomic/Atoms/Views/TileletModel.swift index 2abd1eec..6afc9c12 100644 --- a/MVMCoreUI/Atomic/Atoms/Views/TileletModel.swift +++ b/MVMCoreUI/Atomic/Atoms/Views/TileletModel.swift @@ -20,7 +20,10 @@ open class TileletModel: TileContainerBaseModel, MoleculeModelProtocol { public var color: Tilelet.BackgroundColor = .black public var padding: Tilelet.Padding = .large public var aspectRatio: Tilelet.AspectRatio = .ratio1x1 - public var backgroundEffect: Tilelet.BackgroundEffect = .none + public var backgroundEffect: Tilelet.BackgroundEffect { + guard let effect = backgroundEffectContainer else { return .none } + return .convert(from: effect) + } public var badge: Tilelet.BadgeModel? public var title: LabelModel? public var subTitle: LabelModel? @@ -33,7 +36,6 @@ open class TileletModel: TileContainerBaseModel, MoleculeModelProtocol { case id case moleculeName case backgroundColor - case backgroundEffect case color case padding case aspectRatio @@ -50,7 +52,6 @@ open class TileletModel: TileContainerBaseModel, MoleculeModelProtocol { id = try container.decodeIfPresent(String.self, forKey: .id) ?? UUID().uuidString backgroundColor = try container.decodeIfPresent(Color.self, forKey: .backgroundColor) color = try container.decodeIfPresent(Tilelet.BackgroundColor.self, forKey: .color) ?? Tilelet.BackgroundColor.black - backgroundEffect = try container.decodeIfPresent(Tilelet.BackgroundEffect.self, forKey: .backgroundEffect) ?? .none padding = try container.decodeIfPresent(Tilelet.Padding.self, forKey: .padding) ?? Tilelet.Padding.small aspectRatio = try container.decodeIfPresent(Tilelet.AspectRatio.self, forKey: .aspectRatio) ?? Tilelet.AspectRatio.none badge = try container.decodeIfPresent(Tilelet.BadgeModel.self, forKey: .badge) diff --git a/MVMCoreUI/Atomic/Extensions/VDS-Enums+Codable.swift b/MVMCoreUI/Atomic/Extensions/VDS-Enums+Codable.swift index 0cd9ba2e..19efa0a9 100644 --- a/MVMCoreUI/Atomic/Extensions/VDS-Enums+Codable.swift +++ b/MVMCoreUI/Atomic/Extensions/VDS-Enums+Codable.swift @@ -100,54 +100,6 @@ extension VDS.TileContainerBase.BackgroundColor: Codable { } } -extension VDS.TileContainerBase.BackgroundEffect: Codable { - enum Error: Swift.Error { - case valueNotFound(type: String) - } - enum CodingKeys: String, CodingKey { - case type - case firstColor - case secondColor - } - - enum BackgroundEffectType: String, Codable { - case transparency - case none - case gradient - } - - public init(from decoder: Decoder) throws { - let container = try decoder.container(keyedBy: CodingKeys.self) - let type = try container.decode(BackgroundEffectType.self, forKey: .type) - - switch type { - case .transparency: - self = .transparency - case .none: - self = .none - case .gradient: - let firstColor = try container.decode(String.self, forKey: .firstColor) - let secondColor = try container.decode(String.self, forKey: .secondColor) - self = .gradient(firstColor, secondColor) - } - } - - public func encode(to encoder: Encoder) throws { - var container = encoder.container(keyedBy: CodingKeys.self) - switch self { - case .transparency: - try container.encode(BackgroundEffectType.transparency.rawValue, forKey: .type) - case .none: - try container.encode(BackgroundEffectType.none.rawValue, forKey: .type) - case .gradient(let firstColor, let secondColor): - try container.encode(BackgroundEffectType.gradient.rawValue, forKey: .type) - try container.encode(firstColor, forKey: .firstColor) - try container.encode(secondColor, forKey: .secondColor) - @unknown default: break - } - } -} - extension VDS.TileContainer.Padding: Codable { enum PaddingError: Error { case valueNotFound(type: String)