Digital PCT265 story PCT-135: Code review comments, cleanups and isEquals expansion.
This commit is contained in:
parent
f37e7abcb1
commit
32deda3d3d
@ -25,4 +25,11 @@ public struct ActionAlertModel: ActionModelProtocol {
|
|||||||
public init(alert: AlertModel) {
|
public init(alert: AlertModel) {
|
||||||
self.alert = alert
|
self.alert = alert
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public func isEqual(to model: any ModelComparisonProtocol) -> Bool {
|
||||||
|
guard let model = model as? Self else { return false }
|
||||||
|
return model.extraParameters == extraParameters
|
||||||
|
&& model.analyticsData == analyticsData
|
||||||
|
&& model.alert == alert
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -20,4 +20,12 @@ public struct ActionCollapseNotificationModel: ActionModelProtocol {
|
|||||||
self.extraParameters = extraParameters
|
self.extraParameters = extraParameters
|
||||||
self.analyticsData = analyticsData
|
self.analyticsData = analyticsData
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Default
|
||||||
|
//public func isEqual(to model: any ModelComparisonProtocol) -> Bool {
|
||||||
|
// guard let model = model as? Self else { return false }
|
||||||
|
// return model.actionType == actionType
|
||||||
|
// && model.extraParameters == extraParameters
|
||||||
|
// && model.analyticsData == analyticsData
|
||||||
|
//}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -20,4 +20,12 @@ public struct ActionDismissNotificationModel: ActionModelProtocol {
|
|||||||
self.extraParameters = extraParameters
|
self.extraParameters = extraParameters
|
||||||
self.analyticsData = analyticsData
|
self.analyticsData = analyticsData
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Default
|
||||||
|
// public func isEqual(to model: any ModelComparisonProtocol) -> Bool {
|
||||||
|
// guard let model = model as? Self else { return false }
|
||||||
|
// return model.actionType == actionType
|
||||||
|
// && model.extraParameters == extraParameters
|
||||||
|
// && model.analyticsData == analyticsData
|
||||||
|
//}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -29,4 +29,12 @@ public struct ActionOpenPanelModel: ActionModelProtocol {
|
|||||||
self.extraParameters = extraParameters
|
self.extraParameters = extraParameters
|
||||||
self.analyticsData = analyticsData
|
self.analyticsData = analyticsData
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Default
|
||||||
|
public func isEqual(to model: any ModelComparisonProtocol) -> Bool {
|
||||||
|
guard let model = model as? Self else { return false }
|
||||||
|
return model.extraParameters == extraParameters
|
||||||
|
&& model.analyticsData == analyticsData
|
||||||
|
&& model.panel == panel
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -22,4 +22,11 @@ public struct ActionTopNotificationModel: ActionModelProtocol {
|
|||||||
self.extraParameters = extraParameters
|
self.extraParameters = extraParameters
|
||||||
self.analyticsData = analyticsData
|
self.analyticsData = analyticsData
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public func isEqual(to model: any ModelComparisonProtocol) -> Bool {
|
||||||
|
guard let model = model as? Self else { return false }
|
||||||
|
return model.extraParameters == extraParameters
|
||||||
|
&& model.analyticsData == analyticsData
|
||||||
|
&& model.topNotification == topNotification
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -9,7 +9,8 @@
|
|||||||
import UIKit
|
import UIKit
|
||||||
import MVMCore
|
import MVMCore
|
||||||
|
|
||||||
public struct AlertButtonModel: Codable {
|
public struct AlertButtonModel: Codable, Equatable {
|
||||||
|
|
||||||
//--------------------------------------------------
|
//--------------------------------------------------
|
||||||
// MARK: - Properties
|
// MARK: - Properties
|
||||||
//--------------------------------------------------
|
//--------------------------------------------------
|
||||||
@ -62,14 +63,21 @@ public struct AlertButtonModel: Codable {
|
|||||||
try container.encodeModel(action, forKey: .action)
|
try container.encodeModel(action, forKey: .action)
|
||||||
try container.encodeIfPresent(preferred, forKey: .preferred)
|
try container.encodeIfPresent(preferred, forKey: .preferred)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static func == (lhs: AlertButtonModel, rhs: AlertButtonModel) -> Bool {
|
||||||
|
lhs.title == rhs.title
|
||||||
|
&& lhs.preferred == rhs.preferred
|
||||||
|
&& lhs.style == rhs.style
|
||||||
|
&& lhs.action.isEqual(to: rhs.action)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public struct AlertModel: Codable, Identifiable, AlertModelProtocol {
|
public struct AlertModel: Codable, Identifiable, Equatable, AlertModelProtocol {
|
||||||
|
|
||||||
//--------------------------------------------------
|
//--------------------------------------------------
|
||||||
// MARK: - Properties
|
// MARK: - Properties
|
||||||
//--------------------------------------------------
|
//--------------------------------------------------
|
||||||
|
|
||||||
public var title: String?
|
public var title: String?
|
||||||
public var message: String?
|
public var message: String?
|
||||||
public var preferredStyle: UIAlertController.Style = .alert
|
public var preferredStyle: UIAlertController.Style = .alert
|
||||||
@ -78,7 +86,7 @@ public struct AlertModel: Codable, Identifiable, AlertModelProtocol {
|
|||||||
public var id: String
|
public var id: String
|
||||||
|
|
||||||
public var delegateObject: DelegateObject?
|
public var delegateObject: DelegateObject?
|
||||||
|
|
||||||
public var actions: [UIAlertAction] {
|
public var actions: [UIAlertAction] {
|
||||||
get {
|
get {
|
||||||
buttonModels.map({ alertButtonModel in
|
buttonModels.map({ alertButtonModel in
|
||||||
@ -94,8 +102,7 @@ public struct AlertModel: Codable, Identifiable, AlertModelProtocol {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
//--------------------------------------------------
|
//--------------------------------------------------
|
||||||
// MARK: - Init
|
// MARK: - Init
|
||||||
//--------------------------------------------------
|
//--------------------------------------------------
|
||||||
@ -149,6 +156,14 @@ public struct AlertModel: Codable, Identifiable, AlertModelProtocol {
|
|||||||
try container.encodeIfPresent(analyticsData, forKey: .analyticsData)
|
try container.encodeIfPresent(analyticsData, forKey: .analyticsData)
|
||||||
try container.encode(id, forKey: .id)
|
try container.encode(id, forKey: .id)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static func == (lhs: AlertModel, rhs: AlertModel) -> Bool {
|
||||||
|
lhs.title == rhs.title
|
||||||
|
&& lhs.message == rhs.title
|
||||||
|
&& lhs.preferredStyle == rhs.preferredStyle
|
||||||
|
&& lhs.buttonModels == rhs.buttonModels
|
||||||
|
&& lhs.analyticsData == rhs.analyticsData
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public extension AlertButtonModel {
|
public extension AlertButtonModel {
|
||||||
|
|||||||
@ -30,9 +30,9 @@ import UIKit
|
|||||||
}
|
}
|
||||||
|
|
||||||
public override class func nameForReuse(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?) -> String? {
|
public override class func nameForReuse(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?) -> String? {
|
||||||
if let listModel = model as? ListItemModel, listModel.hasStableId {
|
// if let listModel = model as? ListItemModel, listModel.hasStableId {
|
||||||
return "\(MoleculeContainer.nameForReuse(with: model, delegateObject) ?? "")<\(listModel.id)>"
|
// return "\(MoleculeContainer.nameForReuse(with: model, delegateObject) ?? "")<\(listModel.id)>"
|
||||||
}
|
// }
|
||||||
return MoleculeContainer.nameForReuse(with: model, delegateObject)
|
return MoleculeContainer.nameForReuse(with: model, delegateObject)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -21,9 +21,6 @@ public protocol MoleculeDelegateProtocol: AnyObject {
|
|||||||
|
|
||||||
/// Notifies the delegate that the molecule layout update. Should be called when the layout may change due to an async method. Mainly used for list or collections.
|
/// Notifies the delegate that the molecule layout update. Should be called when the layout may change due to an async method. Mainly used for list or collections.
|
||||||
func moleculeLayoutUpdated(_ molecule: MoleculeViewProtocol) //optional
|
func moleculeLayoutUpdated(_ molecule: MoleculeViewProtocol) //optional
|
||||||
|
|
||||||
/// Attempts to replace the molecules provided. Returns the ones that replaced successfully.
|
|
||||||
func replaceMoleculeData(_ moleculeModels: [MoleculeModelProtocol], completionHandler: (([MoleculeModelProtocol])->Void)?)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
extension MoleculeDelegateProtocol {
|
extension MoleculeDelegateProtocol {
|
||||||
|
|||||||
@ -150,7 +150,7 @@ import MVMCore
|
|||||||
do {
|
do {
|
||||||
let template = try parsePageJSON(loadObject: loadObject)
|
let template = try parsePageJSON(loadObject: loadObject)
|
||||||
pageModel = template // TODO: Eventually this page parsing should be done outside of this class and then set by the caller. For now, double duty.
|
pageModel = template // TODO: Eventually this page parsing should be done outside of this class and then set by the caller. For now, double duty.
|
||||||
isFirstRender = true
|
isFirstRender = true // Assuming this is only on the first page load from the handler. Might need to revist later.
|
||||||
if let backgroundRequest = loadObject.requestParameters?.backgroundRequest, !backgroundRequest, let pageType, let identifier = loadObject.identifier {
|
if let backgroundRequest = loadObject.requestParameters?.backgroundRequest, !backgroundRequest, let pageType, let identifier = loadObject.identifier {
|
||||||
MVMCoreLoggingHandler.shared()?.logCoreEvent(.pageProcessingComplete(pageType: pageType, requestUUID: identifier, webUrl: nil))
|
MVMCoreLoggingHandler.shared()?.logCoreEvent(.pageProcessingComplete(pageType: pageType, requestUUID: identifier, webUrl: nil))
|
||||||
}
|
}
|
||||||
@ -234,7 +234,7 @@ import MVMCore
|
|||||||
open func handleNewData(_ pageModel: PageModelProtocol? = nil) {
|
open func handleNewData(_ pageModel: PageModelProtocol? = nil) {
|
||||||
|
|
||||||
guard var newPageModel = pageModel ?? self.pageModel else { return }
|
guard var newPageModel = pageModel ?? self.pageModel else { return }
|
||||||
let originalModel = self.isFirstRender ? self.pageModel as? MVMControllerModelProtocol : nil
|
let originalModel = isFirstRender ? self.pageModel as? MVMControllerModelProtocol : nil
|
||||||
|
|
||||||
if originalModel != nil, let behaviorContainer = newPageModel as? PageBehaviorContainerModelProtocol {
|
if originalModel != nil, let behaviorContainer = newPageModel as? PageBehaviorContainerModelProtocol {
|
||||||
var behaviorHandler = self
|
var behaviorHandler = self
|
||||||
@ -246,8 +246,10 @@ import MVMCore
|
|||||||
newPageModel.navigationBar = navigationItem
|
newPageModel.navigationBar = navigationItem
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Make the template available for onPageNew behavior handling. See if we can have behaviors rely on roots later.
|
||||||
self.pageModel = newPageModel
|
self.pageModel = newPageModel
|
||||||
|
|
||||||
|
// Run through behavior tranformations.
|
||||||
var behaviorUpdatedModels = [MoleculeModelProtocol]()
|
var behaviorUpdatedModels = [MoleculeModelProtocol]()
|
||||||
if var newTemplateModel = newPageModel as? TemplateModelProtocol {
|
if var newTemplateModel = newPageModel as? TemplateModelProtocol {
|
||||||
executeBehaviors { (behavior: PageMoleculeTransformationBehavior) in
|
executeBehaviors { (behavior: PageMoleculeTransformationBehavior) in
|
||||||
@ -258,6 +260,8 @@ import MVMCore
|
|||||||
debugLog("Behavior updated \(molecule) in template model.")
|
debugLog("Behavior updated \(molecule) in template model.")
|
||||||
behaviorUpdatedModels.append(molecule) // Need to specifically trace molecule updates here as replacements are modifying the original tree. (We don't have a deep copy.)
|
behaviorUpdatedModels.append(molecule) // Need to specifically trace molecule updates here as replacements are modifying the original tree. (We don't have a deep copy.)
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
debugLog("Failed to replace \(molecule) in the template model.")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -265,13 +269,14 @@ import MVMCore
|
|||||||
}
|
}
|
||||||
|
|
||||||
if formValidator == nil { // TODO: Can't change form rules?
|
if formValidator == nil { // TODO: Can't change form rules?
|
||||||
let rules = (newPageModel as? MVMControllerModelProtocol)?.formRules
|
let rules = (newPageModel as? FormHolderModelProtocol)?.formRules
|
||||||
formValidator = FormValidator(rules)
|
formValidator = FormValidator(rules)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Reset after tranformations.
|
||||||
self.pageModel = newPageModel
|
self.pageModel = newPageModel
|
||||||
|
|
||||||
/// Run through the differences between separate page model trees.
|
// Run through the differences between separate page model trees.
|
||||||
var pageUpdatedModels = [MoleculeModelProtocol]()
|
var pageUpdatedModels = [MoleculeModelProtocol]()
|
||||||
if let originalModel, // We had a prior.
|
if let originalModel, // We had a prior.
|
||||||
let newPageModel = newPageModel as? TemplateModelProtocol,
|
let newPageModel = newPageModel as? TemplateModelProtocol,
|
||||||
@ -573,49 +578,6 @@ import MVMCore
|
|||||||
// Needed otherwise when subclassed, the extension gets called.
|
// Needed otherwise when subclassed, the extension gets called.
|
||||||
open func moleculeLayoutUpdated(_ molecule: MoleculeViewProtocol) { }
|
open func moleculeLayoutUpdated(_ molecule: MoleculeViewProtocol) { }
|
||||||
|
|
||||||
public func replaceMoleculeData(_ moleculeModels: [MoleculeModelProtocol], completionHandler: (([MoleculeModelProtocol])->Void)? = nil) {
|
|
||||||
pageUpdateQueue.addOperation { [self] in
|
|
||||||
let replacedModels:[(MoleculeModelProtocol, MoleculeModelProtocol)] = moleculeModels.compactMap { model in
|
|
||||||
guard let replacedMolecule = attemptToReplace(with: model) else {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
return (model, replacedMolecule)
|
|
||||||
}
|
|
||||||
let uiUpdatedModels: [MoleculeModelProtocol] = replacedModels.compactMap { new, existing in
|
|
||||||
guard !new.isEqual(to: existing) else {
|
|
||||||
debugLog("UI for molecules: \(new) is the same. Skip UI update.")
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
return new
|
|
||||||
}
|
|
||||||
if uiUpdatedModels.count > 0 {
|
|
||||||
debugLog("Updating UI for molecules: \(uiUpdatedModels)")
|
|
||||||
DispatchQueue.main.sync {
|
|
||||||
self.updateUI(for: uiUpdatedModels)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
completionHandler?(replacedModels.map { $0.0 })
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
open func attemptToReplace(with replacementModel: MoleculeModelProtocol) -> MoleculeModelProtocol? {
|
|
||||||
guard var templateModel = getTemplateModel() else { return nil }
|
|
||||||
var replacedMolecule: MoleculeModelProtocol?
|
|
||||||
do {
|
|
||||||
replacedMolecule = try templateModel.replaceMolecule(with: replacementModel)
|
|
||||||
if replacedMolecule == nil {
|
|
||||||
MVMCoreLoggingHandler.shared()?.addError(toLog: MVMCoreErrorObject(title: nil, messageToLog: "Failed to find '\(replacementModel.id)' in the current screen.", code: ErrorCode.viewControllerProcessingJSON.rawValue, domain: ErrorDomainSystem, location: String(describing: type(of: self)))!)
|
|
||||||
}
|
|
||||||
} catch {
|
|
||||||
let coreError = MVMCoreErrorObject.createErrorObject(for: error, location: String(describing: type(of: self)))!
|
|
||||||
if let error = error as? HumanReadableDecodingErrorProtocol {
|
|
||||||
coreError.messageToLog = "Error replacing molecule \"\(replacementModel.id)\": \(error.readableDescription)"
|
|
||||||
}
|
|
||||||
MVMCoreLoggingHandler.shared()?.addError(toLog: coreError)
|
|
||||||
}
|
|
||||||
return replacedMolecule
|
|
||||||
}
|
|
||||||
|
|
||||||
//--------------------------------------------------
|
//--------------------------------------------------
|
||||||
// MARK: - MVMCoreUIDetailViewProtocol
|
// MARK: - MVMCoreUIDetailViewProtocol
|
||||||
//--------------------------------------------------
|
//--------------------------------------------------
|
||||||
|
|||||||
@ -159,6 +159,13 @@ public class AddMoleculesActionModel: ActionModelProtocol {
|
|||||||
extraParameters = try typeContainer.decodeIfPresent(JSONValueDictionary.self, forKey: .extraParameters)
|
extraParameters = try typeContainer.decodeIfPresent(JSONValueDictionary.self, forKey: .extraParameters)
|
||||||
analyticsData = try typeContainer.decodeIfPresent(JSONValueDictionary.self, forKey: .analyticsData)
|
analyticsData = try typeContainer.decodeIfPresent(JSONValueDictionary.self, forKey: .analyticsData)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public func isEqual(to model: any ModelComparisonProtocol) -> Bool {
|
||||||
|
guard let model = model as? Self else { return false }
|
||||||
|
return model.extraParameters == extraParameters
|
||||||
|
&& model.analyticsData == analyticsData
|
||||||
|
&& model.animation == animation
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public class RemoveMoleculesActionModel: ActionModelProtocol {
|
public class RemoveMoleculesActionModel: ActionModelProtocol {
|
||||||
@ -186,6 +193,13 @@ public class RemoveMoleculesActionModel: ActionModelProtocol {
|
|||||||
extraParameters = try typeContainer.decodeIfPresent(JSONValueDictionary.self, forKey: .extraParameters)
|
extraParameters = try typeContainer.decodeIfPresent(JSONValueDictionary.self, forKey: .extraParameters)
|
||||||
analyticsData = try typeContainer.decodeIfPresent(JSONValueDictionary.self, forKey: .analyticsData)
|
analyticsData = try typeContainer.decodeIfPresent(JSONValueDictionary.self, forKey: .analyticsData)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public func isEqual(to model: any ModelComparisonProtocol) -> Bool {
|
||||||
|
guard let model = model as? Self else { return false }
|
||||||
|
return model.extraParameters == extraParameters
|
||||||
|
&& model.analyticsData == analyticsData
|
||||||
|
&& model.animation == animation
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public class SwapMoleculesActionModel: ActionModelProtocol {
|
public class SwapMoleculesActionModel: ActionModelProtocol {
|
||||||
@ -213,4 +227,11 @@ public class SwapMoleculesActionModel: ActionModelProtocol {
|
|||||||
extraParameters = try typeContainer.decodeIfPresent(JSONValueDictionary.self, forKey: .extraParameters)
|
extraParameters = try typeContainer.decodeIfPresent(JSONValueDictionary.self, forKey: .extraParameters)
|
||||||
analyticsData = try typeContainer.decodeIfPresent(JSONValueDictionary.self, forKey: .analyticsData)
|
analyticsData = try typeContainer.decodeIfPresent(JSONValueDictionary.self, forKey: .analyticsData)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public func isEqual(to model: any ModelComparisonProtocol) -> Bool {
|
||||||
|
guard let model = model as? Self else { return false }
|
||||||
|
return model.extraParameters == extraParameters
|
||||||
|
&& model.analyticsData == analyticsData
|
||||||
|
&& model.animation == animation
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -20,6 +20,12 @@ public class PageGetContactBehaviorModel: PageBehaviorModelProtocol {
|
|||||||
public var shouldAllowMultipleInstances: Bool { false }
|
public var shouldAllowMultipleInstances: Bool { false }
|
||||||
|
|
||||||
public init() { }
|
public init() { }
|
||||||
|
|
||||||
|
// Default
|
||||||
|
// public func isEqual(to model: any MVMCore.ModelComparisonProtocol) -> Bool {
|
||||||
|
// guard let model = model as? Self else { return false }
|
||||||
|
// return behaviorName == model.behaviorName
|
||||||
|
//}
|
||||||
}
|
}
|
||||||
|
|
||||||
public class PageGetContactBehavior: PageVisibilityBehavior {
|
public class PageGetContactBehavior: PageVisibilityBehavior {
|
||||||
|
|||||||
@ -15,6 +15,12 @@ public class GetNotificationAuthStatusBehaviorModel: PageBehaviorModelProtocol {
|
|||||||
public var shouldAllowMultipleInstances: Bool { false }
|
public var shouldAllowMultipleInstances: Bool { false }
|
||||||
|
|
||||||
public init() { }
|
public init() { }
|
||||||
|
|
||||||
|
// Default
|
||||||
|
// public func isEqual(to model: any ModelComparisonProtocol) -> Bool {
|
||||||
|
// guard let model = model as? Self else { return false }
|
||||||
|
// return behaviorName == model.behaviorName
|
||||||
|
//}
|
||||||
}
|
}
|
||||||
|
|
||||||
public class GetNotificationAuthStatusBehavior: PageVisibilityBehavior {
|
public class GetNotificationAuthStatusBehavior: PageVisibilityBehavior {
|
||||||
|
|||||||
@ -46,6 +46,15 @@ public class PollingBehaviorModel: PageBehaviorModelProtocol {
|
|||||||
try container.encode(refreshOnFirstLoad, forKey: .refreshOnFirstLoad)
|
try container.encode(refreshOnFirstLoad, forKey: .refreshOnFirstLoad)
|
||||||
try container.encode(refreshOnShown, forKey: .refreshOnShown)
|
try container.encode(refreshOnShown, forKey: .refreshOnShown)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public func isEqual(to model: any ModelComparisonProtocol) -> Bool {
|
||||||
|
guard let model = model as? Self else { return false }
|
||||||
|
return runWhileHidden == model.runWhileHidden
|
||||||
|
&& refreshOnShown == model.refreshOnShown
|
||||||
|
&& refreshOnFirstLoad == model.refreshOnFirstLoad
|
||||||
|
&& refreshInterval == model.refreshInterval
|
||||||
|
&& refreshAction.isEqual(to: model.refreshAction)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
extension PollingBehaviorModel: CustomDebugStringConvertible {
|
extension PollingBehaviorModel: CustomDebugStringConvertible {
|
||||||
|
|||||||
@ -33,6 +33,7 @@ public extension PageBehaviorHandlerProtocol {
|
|||||||
mutating func applyBehaviors(pageBehaviorModel: PageBehaviorContainerModelProtocol, delegateObject: MVMCoreUIDelegateObject?) {
|
mutating func applyBehaviors(pageBehaviorModel: PageBehaviorContainerModelProtocol, delegateObject: MVMCoreUIDelegateObject?) {
|
||||||
// Pull the existing behaviors.
|
// Pull the existing behaviors.
|
||||||
var behaviors = (behaviors ?? []).filter { $0.transcendsPageUpdates }
|
var behaviors = (behaviors ?? []).filter { $0.transcendsPageUpdates }
|
||||||
|
|
||||||
// Create and append any new behaviors based on the incoming models.
|
// Create and append any new behaviors based on the incoming models.
|
||||||
let newBehaviors = createBehaviors(for: pageBehaviorModel.behaviors ?? [], delegateObject: delegateObject)
|
let newBehaviors = createBehaviors(for: pageBehaviorModel.behaviors ?? [], delegateObject: delegateObject)
|
||||||
behaviors.append(contentsOf: newBehaviors)
|
behaviors.append(contentsOf: newBehaviors)
|
||||||
|
|||||||
@ -33,4 +33,9 @@ public extension PageBehaviorModelProtocol {
|
|||||||
static var categoryName: String {
|
static var categoryName: String {
|
||||||
"\(PageBehaviorModelProtocol.self)"
|
"\(PageBehaviorModelProtocol.self)"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func isEqual(to model: any ModelComparisonProtocol) -> Bool {
|
||||||
|
guard let model = model as? Self else { return false }
|
||||||
|
return behaviorName == model.behaviorName
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -13,6 +13,11 @@ public class ReplaceableMoleculeBehaviorModel: PageBehaviorModelProtocol {
|
|||||||
public class var identifier: String { "replaceMoleculeBehavior" }
|
public class var identifier: String { "replaceMoleculeBehavior" }
|
||||||
public var shouldAllowMultipleInstances: Bool { true }
|
public var shouldAllowMultipleInstances: Bool { true }
|
||||||
public var moleculeIds: [String]
|
public var moleculeIds: [String]
|
||||||
|
|
||||||
|
public func isEqual(to model: any MVMCore.ModelComparisonProtocol) -> Bool {
|
||||||
|
guard let model = model as? Self else { return false }
|
||||||
|
return moleculeIds == model.moleculeIds
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public class ReplaceableMoleculeBehavior: PageMoleculeTransformationBehavior, CoreLogging {
|
public class ReplaceableMoleculeBehavior: PageMoleculeTransformationBehavior, CoreLogging {
|
||||||
@ -92,7 +97,11 @@ public class ReplaceableMoleculeBehavior: PageMoleculeTransformationBehavior, Co
|
|||||||
hasReplacement = true
|
hasReplacement = true
|
||||||
}
|
}
|
||||||
} catch {
|
} catch {
|
||||||
|
let coreError = MVMCoreErrorObject.createErrorObject(for: error, location: String(describing: type(of: self)))!
|
||||||
|
if let error = error as? HumanReadableDecodingErrorProtocol {
|
||||||
|
coreError.messageToLog = "Error replacing molecule \"\(newMolecule.id)\": \(error.readableDescription)"
|
||||||
|
}
|
||||||
|
MVMCoreLoggingHandler.shared()?.addError(toLog: coreError)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return parentMolecule
|
return parentMolecule
|
||||||
|
|||||||
@ -7,13 +7,14 @@
|
|||||||
//
|
//
|
||||||
|
|
||||||
public class ScreenBrightnessModifierBehaviorModel: PageBehaviorModelProtocol {
|
public class ScreenBrightnessModifierBehaviorModel: PageBehaviorModelProtocol {
|
||||||
|
|
||||||
public var shouldAllowMultipleInstances: Bool = false
|
public var shouldAllowMultipleInstances: Bool = false
|
||||||
public static var identifier = "screenBrightnessModifier"
|
public static var identifier = "screenBrightnessModifier"
|
||||||
@Clamping(range: 0...1) var screenBrightness: CGFloat
|
@Clamping(range: 0...1) var screenBrightness: CGFloat
|
||||||
var originalScreenBrightness: CGFloat?
|
var originalScreenBrightness: CGFloat?
|
||||||
|
|
||||||
//MARK:- Codable
|
//MARK:- Codable
|
||||||
|
|
||||||
private enum CodingKeys: String, CodingKey {
|
private enum CodingKeys: String, CodingKey {
|
||||||
case screenBrightness
|
case screenBrightness
|
||||||
}
|
}
|
||||||
@ -22,11 +23,16 @@ public class ScreenBrightnessModifierBehaviorModel: PageBehaviorModelProtocol {
|
|||||||
let typeContainer = try decoder.container(keyedBy: CodingKeys.self)
|
let typeContainer = try decoder.container(keyedBy: CodingKeys.self)
|
||||||
screenBrightness = try typeContainer.decode(CGFloat.self, forKey: .screenBrightness)
|
screenBrightness = try typeContainer.decode(CGFloat.self, forKey: .screenBrightness)
|
||||||
}
|
}
|
||||||
|
|
||||||
public func encode(to encoder: Encoder) throws {
|
public func encode(to encoder: Encoder) throws {
|
||||||
var container = encoder.container(keyedBy: CodingKeys.self)
|
var container = encoder.container(keyedBy: CodingKeys.self)
|
||||||
try container.encode(screenBrightness, forKey: .screenBrightness)
|
try container.encode(screenBrightness, forKey: .screenBrightness)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public func isEqual(to model: ModelComparisonProtocol) -> Bool {
|
||||||
|
guard let model = model as? Self else { return false }
|
||||||
|
return screenBrightness == model.screenBrightness
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public class ScreenBrightnessModifierBehavior: PageVisibilityBehavior {
|
public class ScreenBrightnessModifierBehavior: PageVisibilityBehavior {
|
||||||
|
|||||||
@ -15,7 +15,7 @@ public class RuleEqualsModel: RuleCompareModelProtocol {
|
|||||||
|
|
||||||
public static var identifier: String = "equals"
|
public static var identifier: String = "equals"
|
||||||
public var type: String = RuleEqualsModel.identifier
|
public var type: String = RuleEqualsModel.identifier
|
||||||
public var ruleId: String?
|
public var ruleId: String?
|
||||||
public var fields: [String]
|
public var fields: [String]
|
||||||
public var errorMessage: [String: String]?
|
public var errorMessage: [String: String]?
|
||||||
|
|
||||||
|
|||||||
@ -9,7 +9,7 @@
|
|||||||
import Foundation
|
import Foundation
|
||||||
import MVMCore
|
import MVMCore
|
||||||
|
|
||||||
open class NotificationModel: Codable, Identifiable {
|
open class NotificationModel: Codable, Identifiable, Equatable {
|
||||||
public var type: String
|
public var type: String
|
||||||
public var priority = Operation.QueuePriority.normal
|
public var priority = Operation.QueuePriority.normal
|
||||||
public var molecule: MoleculeModelProtocol
|
public var molecule: MoleculeModelProtocol
|
||||||
@ -115,4 +115,14 @@ open class NotificationModel: Codable, Identifiable {
|
|||||||
try container.encodeIfPresent(analyticsData, forKey: .analyticsData)
|
try container.encodeIfPresent(analyticsData, forKey: .analyticsData)
|
||||||
try container.encode(id, forKey: .id)
|
try container.encode(id, forKey: .id)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static func == (lhs: NotificationModel, rhs: NotificationModel) -> Bool {
|
||||||
|
lhs.persistent == rhs.persistent
|
||||||
|
&& lhs.priority == rhs.priority
|
||||||
|
&& lhs.type == rhs.type
|
||||||
|
&& lhs.persistent == rhs.persistent
|
||||||
|
&& lhs.dismissTime == rhs.dismissTime
|
||||||
|
&& lhs.pages == rhs.pages
|
||||||
|
&& lhs.analyticsData == rhs.analyticsData
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user