From 29ff802474575293f1d231d0bbb67483bcdfeca3 Mon Sep 17 00:00:00 2001 From: Matt Bruce Date: Thu, 12 Jan 2023 13:53:42 -0600 Subject: [PATCH 01/35] inital work for Tilet Atom Signed-off-by: Matt Bruce --- MVMCoreUI.xcodeproj/project.pbxproj | 8 + .../Atomic/Atoms/Views/Label/Label.swift | 30 --- MVMCoreUI/Atomic/Atoms/Views/Tilet.swift | 188 ++++++++++++++++++ MVMCoreUI/Atomic/Atoms/Views/TiletModel.swift | 28 +++ 4 files changed, 224 insertions(+), 30 deletions(-) create mode 100644 MVMCoreUI/Atomic/Atoms/Views/Tilet.swift create mode 100644 MVMCoreUI/Atomic/Atoms/Views/TiletModel.swift diff --git a/MVMCoreUI.xcodeproj/project.pbxproj b/MVMCoreUI.xcodeproj/project.pbxproj index eb5327be..5f9b416e 100644 --- a/MVMCoreUI.xcodeproj/project.pbxproj +++ b/MVMCoreUI.xcodeproj/project.pbxproj @@ -595,6 +595,8 @@ EA5124FF2436018E0051A3A4 /* BGImageHeadlineBodyButtonModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = EA5124FE2436018E0051A3A4 /* BGImageHeadlineBodyButtonModel.swift */; }; EA7E67742758310500ABF773 /* EnableFormFieldEffectModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = EA7E67732758310500ABF773 /* EnableFormFieldEffectModel.swift */; }; EA7E67762758365300ABF773 /* UIUpdatableModelProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = EA7E67752758365300ABF773 /* UIUpdatableModelProtocol.swift */; }; + EA985C3E2970938F00F2FF2E /* Tilet.swift in Sources */ = {isa = PBXBuildFile; fileRef = EA985C3D2970938F00F2FF2E /* Tilet.swift */; }; + EA985C402970939A00F2FF2E /* TiletModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = EA985C3F2970939A00F2FF2E /* TiletModel.swift */; }; EAA0CFAF275E7D8000D65EB0 /* FormFieldEffectProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = EAA0CFAE275E7D8000D65EB0 /* FormFieldEffectProtocol.swift */; }; EAA0CFB1275E823A00D65EB0 /* HideFormFieldEffectModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = EAA0CFB0275E823A00D65EB0 /* HideFormFieldEffectModel.swift */; }; EAA0CFB3275E831E00D65EB0 /* DisableFormFieldEffectModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = EAA0CFB2275E831E00D65EB0 /* DisableFormFieldEffectModel.swift */; }; @@ -1197,6 +1199,8 @@ EA5124FE2436018E0051A3A4 /* BGImageHeadlineBodyButtonModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BGImageHeadlineBodyButtonModel.swift; sourceTree = ""; }; EA7E67732758310500ABF773 /* EnableFormFieldEffectModel.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = EnableFormFieldEffectModel.swift; sourceTree = ""; }; EA7E67752758365300ABF773 /* UIUpdatableModelProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UIUpdatableModelProtocol.swift; sourceTree = ""; }; + EA985C3D2970938F00F2FF2E /* Tilet.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Tilet.swift; sourceTree = ""; }; + EA985C3F2970939A00F2FF2E /* TiletModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TiletModel.swift; sourceTree = ""; }; EAA0CFAE275E7D8000D65EB0 /* FormFieldEffectProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FormFieldEffectProtocol.swift; sourceTree = ""; }; EAA0CFB0275E823A00D65EB0 /* HideFormFieldEffectModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HideFormFieldEffectModel.swift; sourceTree = ""; }; EAA0CFB2275E831E00D65EB0 /* DisableFormFieldEffectModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DisableFormFieldEffectModel.swift; sourceTree = ""; }; @@ -2255,6 +2259,8 @@ AA37CBD42519072F0027344C /* Stars.swift */, AA07EA902510A442009A2AE3 /* StarModel.swift */, AA07EA922510A451009A2AE3 /* Star.swift */, + EA985C3D2970938F00F2FF2E /* Tilet.swift */, + EA985C3F2970939A00F2FF2E /* TiletModel.swift */, ); path = Views; sourceTree = ""; @@ -2777,6 +2783,7 @@ D2E2A99D23DA3217000B42E6 /* UIStackViewAlignment+Extension.swift in Sources */, 01EB369423609801006832FA /* HeadlineBodyModel.swift in Sources */, D2A92884241ACB25004E01C6 /* ProgrammaticScrollViewController.swift in Sources */, + EA985C3E2970938F00F2FF2E /* Tilet.swift in Sources */, D23A90002612347A007E14CE /* PageBehaviorHandlerModelProtocol.swift in Sources */, 0A21DB7F235DECC500C160A2 /* EntryField.swift in Sources */, D2E2A99F23E07F8A000B42E6 /* PillButton.swift in Sources */, @@ -3170,6 +3177,7 @@ D29E28DD23D7404C00ACEA85 /* ContainerHelper.swift in Sources */, 012A88C2238D7BCA00FE3DA1 /* CarouselItemModel.swift in Sources */, 27F6B08C26052AFF008529AA /* ParentMoleculeModelProtocol.swift in Sources */, + EA985C402970939A00F2FF2E /* TiletModel.swift in Sources */, 0AB764D324460FA400E7FE72 /* UIPickerView+Extension.swift in Sources */, D29DF29E21E7AE3B003B2FB9 /* MFStyler.m in Sources */, 94C661D923CCF4B400D9FE5B /* LeftRightLabelModel.swift in Sources */, diff --git a/MVMCoreUI/Atomic/Atoms/Views/Label/Label.swift b/MVMCoreUI/Atomic/Atoms/Views/Label/Label.swift index 059c5637..142bc700 100644 --- a/MVMCoreUI/Atomic/Atoms/Views/Label/Label.swift +++ b/MVMCoreUI/Atomic/Atoms/Views/Label/Label.swift @@ -741,36 +741,6 @@ public typealias ActionBlock = () -> () clauses.append(ActionableClause(range: range, actionBlock: actionBlock, accessibilityID: accessibleAction?.hash ?? -1)) } - /** - Provides a text container and layout manager of how the text would appear on screen. - They are used in tandem to derive low-level TextKit results of the label. - */ - public func abstractTextContainer() -> (NSTextContainer, NSLayoutManager, NSTextStorage)? { - - // Must configure the attributed string to translate what would appear on screen to accurately analyze. - guard let attributedText = attributedText else { return nil } - - let paragraph = NSMutableParagraphStyle() - paragraph.alignment = textAlignment - - let stagedAttributedString = NSMutableAttributedString(attributedString: attributedText) - stagedAttributedString.addAttributes([NSAttributedString.Key.paragraphStyle: paragraph], range: NSRange(location: 0, length: attributedText.string.count)) - - let textStorage = NSTextStorage(attributedString: stagedAttributedString) - let layoutManager = NSLayoutManager() - let textContainer = NSTextContainer(size: .zero) - - layoutManager.addTextContainer(textContainer) - textStorage.addLayoutManager(layoutManager) - - textContainer.lineFragmentPadding = 0.0 - textContainer.lineBreakMode = lineBreakMode - textContainer.maximumNumberOfLines = numberOfLines - textContainer.size = bounds.size - - return (textContainer, layoutManager, textStorage) - } - public static func boundingRect(forCharacterRange range: NSRange, in label: Label) -> CGRect { guard let abstractContainer = label.abstractTextContainer() else { return CGRect() } diff --git a/MVMCoreUI/Atomic/Atoms/Views/Tilet.swift b/MVMCoreUI/Atomic/Atoms/Views/Tilet.swift new file mode 100644 index 00000000..d176e6aa --- /dev/null +++ b/MVMCoreUI/Atomic/Atoms/Views/Tilet.swift @@ -0,0 +1,188 @@ +// +// Tilet.swift +// MVMCoreUI +// +// Created by Matt Bruce on 1/12/23. +// Copyright © 2023 Verizon Wireless. All rights reserved. +// + +import Foundation +import MVMCore +import VDS + +/** + This class expects its height and width to be equal. + */ +open class Tilet: VDS.Tilet, MVMCoreUIViewConstrainingProtocol, MoleculeViewProtocol { + //-------------------------------------------------- + // MARK: - Properties + //-------------------------------------------------- + + var delegateObject: MVMCoreUIDelegateObject? + + public var checkboxModel: CheckboxModel? + + /// Disables all selection logic when setting the value of isSelected, reducing it to a stored property. + public var updateSelectionOnly: Bool = false + + /// Action Block called when the switch is selected. + public var actionBlock: ActionBlock? + + /** + The represented state of the Checkbox. + + Setting updateSelectionOnly to true bypasses the animation logic inherent with setting this property. + */ + override open var isSelected: Bool { + didSet { + if !updateSelectionOnly { + checkboxModel?.selected = isSelected + _ = FormValidator.validate(delegate: delegateObject?.formHolderDelegate) + updateAccessibilityLabel() + } + } + } + + //-------------------------------------------------- + // MARK: - Initializers + //-------------------------------------------------- + + override public init(frame: CGRect) { + super.init(frame: frame) + } + + /// There is currently no intention on using xib files. + required public init?(coder aDecoder: NSCoder) { + super.init(coder: aDecoder) + fatalError("xib file is not implemented for Checkbox.") + } + + public convenience required init() { + self.init(frame:.zero) + } + + public convenience init(isChecked: Bool) { + self.init(frame: .zero) + checkAndBypassAnimations(selected: isChecked) + } + + //-------------------------------------------------- + // MARK: - Lifecycle + //-------------------------------------------------- + + open override func initialSetup() { + super.initialSetup() + + publisher(for: .touchUpInside) + .sink {[weak self] toggle in + guard let self = self else { return } + self.toggleAndAction() + }.store(in: &subscribers) + + accessibilityHintEnabled = MVMCoreUIUtility.hardcodedString(withKey: "checkbox_action_hint") + updateAccessibilityLabel() + } + + //-------------------------------------------------- + // MARK: - Actions + //-------------------------------------------------- + + /// This will toggle the state of the Checkbox and execute the actionBlock if provided. + public func toggleAndAction() { + isSelected.toggle() + actionBlock?() + } + + //-------------------------------------------------- + // MARK: - Methods + //-------------------------------------------------- + + /// Programmatic means to check/uncheck the box. + /// - parameter selected: state of the check box: true = checked OR false = unchecked. + /// - parameter animated: allows the state of the checkbox to change with or without animation. + public func updateSelection(to selected: Bool, animated: Bool) { + DispatchQueue.main.async { + self.checkAndBypassAnimations(selected: selected) + } + } + + /// Adjust accessibility label based on state of Checkbox. + func updateAccessibilityLabel() { + // Attention: This needs to be addressed with the accessibility team. + // NOTE: Currently emptying description part of MVMCoreUICheckBox accessibility label to avoid crashing! + if let state = MVMCoreUIUtility.hardcodedString(withKey: isSelected ? "checkbox_checked_state" : "checkbox_unchecked_state") { + accessibilityLabel = String(format: MVMCoreUIUtility.hardcodedString(withKey: "checkbox_desc_state") ?? "%@%@", "", state) + } + } + + private func checkAndBypassAnimations(selected: Bool) { + updateSelectionOnly = true + isSelected = selected + updateSelectionOnly = false + } + + //-------------------------------------------------- + // MARK: - UITouch + //-------------------------------------------------- + + override open func accessibilityActivate() -> Bool { + guard isEnabled else { return false } + sendActions(for: .touchUpInside) + return true + } + + //-------------------------------------------------- + // MARK: - Molecular + //-------------------------------------------------- + + open func needsToBeConstrained() -> Bool { true } + + open func updateView(_ size: CGFloat) {} + + open override func reset() { + super.reset() + + isEnabled = true + checkAndBypassAnimations(selected: false) + } + + private func performCheckboxAction(with actionModel: ActionModelProtocol, delegateObject: MVMCoreUIDelegateObject?, additionalData: [AnyHashable: Any]?) { + MVMCoreUIActionHandler.performActionUnstructured(with: actionModel, sourceModel: checkboxModel, additionalData: additionalData, delegateObject: delegateObject) + } + + public func set(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable: Any]?) { + self.delegateObject = delegateObject + + guard let model = model as? CheckboxModel else { return } + checkboxModel = model + + FormValidator.setupValidation(for: model, delegate: delegateObject?.formHolderDelegate) + + if model.selected { + checkAndBypassAnimations(selected: model.selected) + } + + model.updateUI = { [weak self] in + MVMCoreDispatchUtility.performBlock(onMainThread: { + guard let self = self else { return } + self.isEnabled = model.enabled && !model.readOnly + }) + } + + isEnabled = model.enabled && !model.readOnly + + if (model.action != nil || model.offAction != nil) { + actionBlock = { [weak self] in + guard let self = self else { return } + + if let offAction = model.offAction, !self.isSelected { + self.performCheckboxAction(with: offAction, delegateObject: delegateObject, additionalData: additionalData) + + } else if let action = model.action { + self.performCheckboxAction(with: action, delegateObject: delegateObject, additionalData: additionalData) + } + } + } + } +} + diff --git a/MVMCoreUI/Atomic/Atoms/Views/TiletModel.swift b/MVMCoreUI/Atomic/Atoms/Views/TiletModel.swift new file mode 100644 index 00000000..340ee329 --- /dev/null +++ b/MVMCoreUI/Atomic/Atoms/Views/TiletModel.swift @@ -0,0 +1,28 @@ +// +// TiletModel.swift +// MVMCoreUI +// +// Created by Matt Bruce on 1/12/23. +// Copyright © 2023 Verizon Wireless. All rights reserved. +// + +import Foundation +import VDS + +open class TiletModel: MoleculeModelProtocol { + + //-------------------------------------------------- + // MARK: - Properties + //-------------------------------------------------- + public static var identifier: String = "tilet" + public var backgroundColor: Color? + public var surface: Surface = .light + public var badge: TiletBadgeModel? + public var title: TiletTitleModel? + public var subTitle: TiletSubTitleModel? + public var desriptiveIcon: TiletDescriptiveIcon? + public var directionalIcon: TiletDirectionalIcon? + public var width: Double? + public var textWidth: Double? + public var textPercentage: Double? +} From 9da436adcbc795c4f92c7aaf98f886c836f2c402 Mon Sep 17 00:00:00 2001 From: Matt Bruce Date: Thu, 12 Jan 2023 14:23:54 -0600 Subject: [PATCH 02/35] added protocol for helping in VDS, this at some point will refactor into the main Signed-off-by: Matt Bruce # Conflicts: # MVMCoreUI.xcodeproj/project.pbxproj --- MVMCoreUI.xcodeproj/project.pbxproj | 8 +++++ .../Protocols/VDSMoleculeViewProtocol.swift | 31 +++++++++++++++++++ 2 files changed, 39 insertions(+) create mode 100644 MVMCoreUI/Atomic/Protocols/VDSMoleculeViewProtocol.swift diff --git a/MVMCoreUI.xcodeproj/project.pbxproj b/MVMCoreUI.xcodeproj/project.pbxproj index eb5327be..a52b570f 100644 --- a/MVMCoreUI.xcodeproj/project.pbxproj +++ b/MVMCoreUI.xcodeproj/project.pbxproj @@ -598,6 +598,9 @@ EAA0CFAF275E7D8000D65EB0 /* FormFieldEffectProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = EAA0CFAE275E7D8000D65EB0 /* FormFieldEffectProtocol.swift */; }; EAA0CFB1275E823A00D65EB0 /* HideFormFieldEffectModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = EAA0CFB0275E823A00D65EB0 /* HideFormFieldEffectModel.swift */; }; EAA0CFB3275E831E00D65EB0 /* DisableFormFieldEffectModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = EAA0CFB2275E831E00D65EB0 /* DisableFormFieldEffectModel.swift */; }; + EAA5EEF828F5D079003B3210 /* VDS.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = EAA5EEF628F5D074003B3210 /* VDS.framework */; }; + EAA5EEFA28F5D079003B3210 /* VDSTypographyTokens.xcframework in Frameworks */ = {isa = PBXBuildFile; fileRef = EAA5EEF728F5D074003B3210 /* VDSTypographyTokens.xcframework */; }; + EAA78020290081320057DFDF /* VDSMoleculeViewProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = EAA7801F290081320057DFDF /* VDSMoleculeViewProtocol.swift */; }; EAB14BC127D935F00012AB2C /* RuleCompareModelProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = EAB14BC027D935F00012AB2C /* RuleCompareModelProtocol.swift */; }; EAB14BC327D9378D0012AB2C /* RuleAnyModelProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = EAB14BC227D9378D0012AB2C /* RuleAnyModelProtocol.swift */; }; EABFC1412763BB8D00E78B40 /* FormLabel.swift in Sources */ = {isa = PBXBuildFile; fileRef = EABFC1402763BB8D00E78B40 /* FormLabel.swift */; }; @@ -1200,6 +1203,9 @@ EAA0CFAE275E7D8000D65EB0 /* FormFieldEffectProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FormFieldEffectProtocol.swift; sourceTree = ""; }; EAA0CFB0275E823A00D65EB0 /* HideFormFieldEffectModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HideFormFieldEffectModel.swift; sourceTree = ""; }; EAA0CFB2275E831E00D65EB0 /* DisableFormFieldEffectModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DisableFormFieldEffectModel.swift; sourceTree = ""; }; + EAA5EEF628F5D074003B3210 /* VDS.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; path = VDS.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + EAA5EEF728F5D074003B3210 /* VDSTypographyTokens.xcframework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcframework; name = VDSTypographyTokens.xcframework; path = "../SharedFrameworks/VDSTypographyTokens.xcframework"; sourceTree = ""; }; + EAA7801F290081320057DFDF /* VDSMoleculeViewProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = VDSMoleculeViewProtocol.swift; sourceTree = ""; }; EAB14BC027D935F00012AB2C /* RuleCompareModelProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RuleCompareModelProtocol.swift; sourceTree = ""; }; EAB14BC227D9378D0012AB2C /* RuleAnyModelProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RuleAnyModelProtocol.swift; sourceTree = ""; }; EABFC1402763BB8D00E78B40 /* FormLabel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FormLabel.swift; sourceTree = ""; }; @@ -2452,6 +2458,7 @@ D2B9D0E3265EEE9D0084735C /* MoleculeListProtocol.swift */, 011B58EE23A2AA850085F53C /* ModelProtocols */, 27559EFB27D691D3000836C1 /* ViewMaskingProtocol.swift */, + EAA7801F290081320057DFDF /* VDSMoleculeViewProtocol.swift */, ); path = Protocols; sourceTree = ""; @@ -2778,6 +2785,7 @@ 01EB369423609801006832FA /* HeadlineBodyModel.swift in Sources */, D2A92884241ACB25004E01C6 /* ProgrammaticScrollViewController.swift in Sources */, D23A90002612347A007E14CE /* PageBehaviorHandlerModelProtocol.swift in Sources */, + EAA78020290081320057DFDF /* VDSMoleculeViewProtocol.swift in Sources */, 0A21DB7F235DECC500C160A2 /* EntryField.swift in Sources */, D2E2A99F23E07F8A000B42E6 /* PillButton.swift in Sources */, D2C5001921F8ECDD001DA659 /* MVMCoreUIViewControllerMappingObject.m in Sources */, diff --git a/MVMCoreUI/Atomic/Protocols/VDSMoleculeViewProtocol.swift b/MVMCoreUI/Atomic/Protocols/VDSMoleculeViewProtocol.swift new file mode 100644 index 00000000..0a6f3179 --- /dev/null +++ b/MVMCoreUI/Atomic/Protocols/VDSMoleculeViewProtocol.swift @@ -0,0 +1,31 @@ +// +// VDSMoleculeViewProtocol.swift +// MVMCoreUI +// +// Created by Matt Bruce on 10/19/22. +// Copyright © 2022 Verizon Wireless. All rights reserved. +// + +import Foundation +import MVMCore + +///----------------------------------------------------------------------------- +///MARK: -- VDSMoleculeViewProtocol (Contract between VDS -> Atomic) +///----------------------------------------------------------------------------- +public protocol VDSMoleculeViewProtocol: MoleculeViewProtocol, MVMCoreViewProtocol { + associatedtype ViewModel: MoleculeModelProtocol + var viewModel: ViewModel! { get set } + var delegateObject: MVMCoreUIDelegateObject? { get set } + var additionalData: [AnyHashable: Any]? { get set } + func viewModelDidUpdate() +} + +extension VDSMoleculeViewProtocol { + public func set(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable: Any]?) { + guard let castedModel = model as? ViewModel else { return } + self.delegateObject = delegateObject + viewModel = castedModel + viewModelDidUpdate() + } +} + From 47668163b86e46ca61fa23ab427d43ac25a71cc8 Mon Sep 17 00:00:00 2001 From: Matt Bruce Date: Thu, 12 Jan 2023 14:25:14 -0600 Subject: [PATCH 03/35] updated frameworks Signed-off-by: Matt Bruce --- MVMCoreUI.xcodeproj/project.pbxproj | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/MVMCoreUI.xcodeproj/project.pbxproj b/MVMCoreUI.xcodeproj/project.pbxproj index a52b570f..ec67aacb 100644 --- a/MVMCoreUI.xcodeproj/project.pbxproj +++ b/MVMCoreUI.xcodeproj/project.pbxproj @@ -595,11 +595,11 @@ EA5124FF2436018E0051A3A4 /* BGImageHeadlineBodyButtonModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = EA5124FE2436018E0051A3A4 /* BGImageHeadlineBodyButtonModel.swift */; }; EA7E67742758310500ABF773 /* EnableFormFieldEffectModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = EA7E67732758310500ABF773 /* EnableFormFieldEffectModel.swift */; }; EA7E67762758365300ABF773 /* UIUpdatableModelProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = EA7E67752758365300ABF773 /* UIUpdatableModelProtocol.swift */; }; + EA985C602970A3F000F2FF2E /* VDS.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = EA985C5F2970A3F000F2FF2E /* VDS.framework */; }; + EA985C642970A40E00F2FF2E /* VDSTypographyTokens.xcframework in Frameworks */ = {isa = PBXBuildFile; fileRef = EA985C632970A40E00F2FF2E /* VDSTypographyTokens.xcframework */; }; EAA0CFAF275E7D8000D65EB0 /* FormFieldEffectProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = EAA0CFAE275E7D8000D65EB0 /* FormFieldEffectProtocol.swift */; }; EAA0CFB1275E823A00D65EB0 /* HideFormFieldEffectModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = EAA0CFB0275E823A00D65EB0 /* HideFormFieldEffectModel.swift */; }; EAA0CFB3275E831E00D65EB0 /* DisableFormFieldEffectModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = EAA0CFB2275E831E00D65EB0 /* DisableFormFieldEffectModel.swift */; }; - EAA5EEF828F5D079003B3210 /* VDS.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = EAA5EEF628F5D074003B3210 /* VDS.framework */; }; - EAA5EEFA28F5D079003B3210 /* VDSTypographyTokens.xcframework in Frameworks */ = {isa = PBXBuildFile; fileRef = EAA5EEF728F5D074003B3210 /* VDSTypographyTokens.xcframework */; }; EAA78020290081320057DFDF /* VDSMoleculeViewProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = EAA7801F290081320057DFDF /* VDSMoleculeViewProtocol.swift */; }; EAB14BC127D935F00012AB2C /* RuleCompareModelProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = EAB14BC027D935F00012AB2C /* RuleCompareModelProtocol.swift */; }; EAB14BC327D9378D0012AB2C /* RuleAnyModelProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = EAB14BC227D9378D0012AB2C /* RuleAnyModelProtocol.swift */; }; @@ -1200,11 +1200,11 @@ EA5124FE2436018E0051A3A4 /* BGImageHeadlineBodyButtonModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BGImageHeadlineBodyButtonModel.swift; sourceTree = ""; }; EA7E67732758310500ABF773 /* EnableFormFieldEffectModel.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = EnableFormFieldEffectModel.swift; sourceTree = ""; }; EA7E67752758365300ABF773 /* UIUpdatableModelProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UIUpdatableModelProtocol.swift; sourceTree = ""; }; + EA985C5F2970A3F000F2FF2E /* VDS.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; path = VDS.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + EA985C632970A40E00F2FF2E /* VDSTypographyTokens.xcframework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcframework; name = VDSTypographyTokens.xcframework; path = ../SharedFrameworks/VDSTypographyTokens.xcframework; sourceTree = ""; }; EAA0CFAE275E7D8000D65EB0 /* FormFieldEffectProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FormFieldEffectProtocol.swift; sourceTree = ""; }; EAA0CFB0275E823A00D65EB0 /* HideFormFieldEffectModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HideFormFieldEffectModel.swift; sourceTree = ""; }; EAA0CFB2275E831E00D65EB0 /* DisableFormFieldEffectModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DisableFormFieldEffectModel.swift; sourceTree = ""; }; - EAA5EEF628F5D074003B3210 /* VDS.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; path = VDS.framework; sourceTree = BUILT_PRODUCTS_DIR; }; - EAA5EEF728F5D074003B3210 /* VDSTypographyTokens.xcframework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcframework; name = VDSTypographyTokens.xcframework; path = "../SharedFrameworks/VDSTypographyTokens.xcframework"; sourceTree = ""; }; EAA7801F290081320057DFDF /* VDSMoleculeViewProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = VDSMoleculeViewProtocol.swift; sourceTree = ""; }; EAB14BC027D935F00012AB2C /* RuleCompareModelProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RuleCompareModelProtocol.swift; sourceTree = ""; }; EAB14BC227D9378D0012AB2C /* RuleAnyModelProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RuleAnyModelProtocol.swift; sourceTree = ""; }; @@ -1220,7 +1220,9 @@ files = ( D29DF0E621E4F3C7003B2FB9 /* MVMCore.framework in Frameworks */, AFE4A1D127DFB5EE00C458D0 /* VDSColorTokens.xcframework in Frameworks */, + EA985C602970A3F000F2FF2E /* VDS.framework in Frameworks */, 187FEB2A2844D2A600BF29C2 /* VDSFormControlsTokens.xcframework in Frameworks */, + EA985C642970A40E00F2FF2E /* VDSTypographyTokens.xcframework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -2064,6 +2066,8 @@ D29DF0E421E4F3C7003B2FB9 /* Frameworks */ = { isa = PBXGroup; children = ( + EA985C632970A40E00F2FF2E /* VDSTypographyTokens.xcframework */, + EA985C5F2970A3F000F2FF2E /* VDS.framework */, 187FEB292844D2A600BF29C2 /* VDSFormControlsTokens.xcframework */, AFE4A1D027DFB5EE00C458D0 /* VDSColorTokens.xcframework */, D29DF0E521E4F3C7003B2FB9 /* MVMCore.framework */, From e8ad9d0938821c2024189d2f954ed0c4084741c0 Mon Sep 17 00:00:00 2001 From: Matt Bruce Date: Thu, 12 Jan 2023 14:28:48 -0600 Subject: [PATCH 04/35] udpated VDS protocol Signed-off-by: Matt Bruce --- MVMCoreUI/Atomic/Protocols/VDSMoleculeViewProtocol.swift | 1 + 1 file changed, 1 insertion(+) diff --git a/MVMCoreUI/Atomic/Protocols/VDSMoleculeViewProtocol.swift b/MVMCoreUI/Atomic/Protocols/VDSMoleculeViewProtocol.swift index 0a6f3179..41349f2c 100644 --- a/MVMCoreUI/Atomic/Protocols/VDSMoleculeViewProtocol.swift +++ b/MVMCoreUI/Atomic/Protocols/VDSMoleculeViewProtocol.swift @@ -24,6 +24,7 @@ extension VDSMoleculeViewProtocol { public func set(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable: Any]?) { guard let castedModel = model as? ViewModel else { return } self.delegateObject = delegateObject + self.additionalData = additionalData viewModel = castedModel viewModelDidUpdate() } From 6eb56966665d8edc2a46244893ec02a8da47d3fb Mon Sep 17 00:00:00 2001 From: Matt Bruce Date: Thu, 12 Jan 2023 14:40:55 -0600 Subject: [PATCH 05/35] updated to 3.1 for MVMCore Signed-off-by: Matt Bruce --- Scripts/build_aggregate.sh | 4 ++++ Scripts/download_dependencies.sh | 6 ++++-- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/Scripts/build_aggregate.sh b/Scripts/build_aggregate.sh index 84c7f4fb..911a4002 100755 --- a/Scripts/build_aggregate.sh +++ b/Scripts/build_aggregate.sh @@ -15,6 +15,10 @@ UNIVERSAL_OUTPUTFOLDER="${BUILD_DIR}/universal" # Update to use .xcframework sed -i '' 's|MVMCore.framework \*\/ = {isa.*};|MVMCore.xcframework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcframework; name = MVMCore.xcframework; path = ../SharedFrameworks/MVMCore.xcframework; sourceTree = ""; };|g' ./MVMCoreUI.xcodeproj/project.pbxproj sed -i '' 's/MVMCore.framework/MVMCore.xcframework/g' ./MVMCoreUI.xcodeproj/project.pbxproj + +sed -i '' 's|VDS.framework \*\/ = {isa.*};|VDS.xcframework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcframework; name = VDS.xcframework; path = ../SharedFrameworks/VDS.xcframework; sourceTree = ""; };|g' ./MVMCoreUI.xcodeproj/project.pbxproj +sed -i '' 's/VDS.framework/VDS.xcframework/g' ./MVMCoreUI.xcodeproj/project.pbxproj + sed -i '' "s|path = \.\.\/SharedFrameworks|path = ${FRAMEWORKS_DIR}|g" ./MVMCoreUI.xcodeproj/project.pbxproj # Build device archive diff --git a/Scripts/download_dependencies.sh b/Scripts/download_dependencies.sh index cc6bc209..2288409c 100755 --- a/Scripts/download_dependencies.sh +++ b/Scripts/download_dependencies.sh @@ -18,8 +18,10 @@ if [ ! -d $FRAMEWORKS_DIR ]; then mkdir -p $FRAMEWORKS_DIR fi -./Scripts/download_framework.sh $ARTIFACTORY_URL "$FRAMEWORKS_DIR/MVMCore.xcframework" BPHV_MobileFirst_IOS/com/vzw/hss/myverizon/MVMCore/3.0/MVMCore-3.0-Debug-SNAPSHOT.zip +./Scripts/download_framework.sh $ARTIFACTORY_URL "$FRAMEWORKS_DIR/MVMCore.xcframework" BPHV_MobileFirst_IOS/com/vzw/hss/myverizon/MVMCore/3.1/MVMCore-3.1-Debug-SNAPSHOT.zip -./Scripts/download_framework.sh $ARTIFACTORY_URL "$FRAMEWORKS_DIR/VDSColorTokens.xcframework" GVJV_VDS_Maven/%40vds-tokens/ios/VDSColorTokens.1.0.6.xcframework.zip +./Scripts/download_framework.sh $ARTIFACTORY_URL "$FRAMEWORKS_DIR/VDS.xcframework" BPHV_MobileFirst_IOS/com/vzw/hss/myverizon/VDS/1.0/VDS-1.0-Debug-SNAPSHOT.zip + +./Scripts/download_framework.sh $ARTIFACTORY_URL "$FRAMEWORKS_DIR/VDSColorTokens.xcframework" GVJV_VDS_Maven/@vds-tokens/ios/VDSColorTokens.1.0.6.xcframework.zip ./Scripts/download_framework.sh $ARTIFACTORY_URL "$FRAMEWORKS_DIR/VDSFormControlsTokens.xcframework" GVJV_VDS_Maven/@vds-tokens/ios/VDSFormControlsTokens.1.0.7.xcframework.zip From 27cc79c54293b578e8c680909243506e558fc25a Mon Sep 17 00:00:00 2001 From: Matt Bruce Date: Thu, 12 Jan 2023 15:06:56 -0600 Subject: [PATCH 06/35] updated tilet atom Signed-off-by: Matt Bruce --- MVMCoreUI/Atomic/Atoms/Views/Tilet.swift | 189 ++++-------------- MVMCoreUI/Atomic/Atoms/Views/TiletModel.swift | 8 +- 2 files changed, 39 insertions(+), 158 deletions(-) diff --git a/MVMCoreUI/Atomic/Atoms/Views/Tilet.swift b/MVMCoreUI/Atomic/Atoms/Views/Tilet.swift index d176e6aa..9dc5acbb 100644 --- a/MVMCoreUI/Atomic/Atoms/Views/Tilet.swift +++ b/MVMCoreUI/Atomic/Atoms/Views/Tilet.swift @@ -13,176 +13,57 @@ import VDS /** This class expects its height and width to be equal. */ -open class Tilet: VDS.Tilet, MVMCoreUIViewConstrainingProtocol, MoleculeViewProtocol { +open class Tilet: VDS.Tilet, VDSMoleculeViewProtocol { //-------------------------------------------------- // MARK: - Properties //-------------------------------------------------- - - var delegateObject: MVMCoreUIDelegateObject? - - public var checkboxModel: CheckboxModel? - - /// Disables all selection logic when setting the value of isSelected, reducing it to a stored property. - public var updateSelectionOnly: Bool = false - - /// Action Block called when the switch is selected. - public var actionBlock: ActionBlock? - - /** - The represented state of the Checkbox. - - Setting updateSelectionOnly to true bypasses the animation logic inherent with setting this property. - */ - override open var isSelected: Bool { - didSet { - if !updateSelectionOnly { - checkboxModel?.selected = isSelected - _ = FormValidator.validate(delegate: delegateObject?.formHolderDelegate) - updateAccessibilityLabel() - } - } - } + public var viewModel: TiletModel! + public var delegateObject: MVMCoreUIDelegateObject? + public var additionalData: [AnyHashable: Any]? //-------------------------------------------------- // MARK: - Initializers //-------------------------------------------------- - - override public init(frame: CGRect) { - super.init(frame: frame) - } - - /// There is currently no intention on using xib files. - required public init?(coder aDecoder: NSCoder) { - super.init(coder: aDecoder) - fatalError("xib file is not implemented for Checkbox.") - } - public convenience required init() { - self.init(frame:.zero) - } - - public convenience init(isChecked: Bool) { self.init(frame: .zero) - checkAndBypassAnimations(selected: isChecked) } - - //-------------------------------------------------- - // MARK: - Lifecycle - //-------------------------------------------------- - - open override func initialSetup() { - super.initialSetup() - publisher(for: .touchUpInside) - .sink {[weak self] toggle in - guard let self = self else { return } - self.toggleAndAction() - }.store(in: &subscribers) - - accessibilityHintEnabled = MVMCoreUIUtility.hardcodedString(withKey: "checkbox_action_hint") - updateAccessibilityLabel() - } - - //-------------------------------------------------- - // MARK: - Actions - //-------------------------------------------------- - - /// This will toggle the state of the Checkbox and execute the actionBlock if provided. - public func toggleAndAction() { - isSelected.toggle() - actionBlock?() - } - - //-------------------------------------------------- - // MARK: - Methods - //-------------------------------------------------- - - /// Programmatic means to check/uncheck the box. - /// - parameter selected: state of the check box: true = checked OR false = unchecked. - /// - parameter animated: allows the state of the checkbox to change with or without animation. - public func updateSelection(to selected: Bool, animated: Bool) { - DispatchQueue.main.async { - self.checkAndBypassAnimations(selected: selected) - } - } - - /// Adjust accessibility label based on state of Checkbox. - func updateAccessibilityLabel() { - // Attention: This needs to be addressed with the accessibility team. - // NOTE: Currently emptying description part of MVMCoreUICheckBox accessibility label to avoid crashing! - if let state = MVMCoreUIUtility.hardcodedString(withKey: isSelected ? "checkbox_checked_state" : "checkbox_unchecked_state") { - accessibilityLabel = String(format: MVMCoreUIUtility.hardcodedString(withKey: "checkbox_desc_state") ?? "%@%@", "", state) - } - } - - private func checkAndBypassAnimations(selected: Bool) { - updateSelectionOnly = true - isSelected = selected - updateSelectionOnly = false - } - - //-------------------------------------------------- - // MARK: - UITouch - //-------------------------------------------------- - - override open func accessibilityActivate() -> Bool { - guard isEnabled else { return false } - sendActions(for: .touchUpInside) - return true - } - - //-------------------------------------------------- - // MARK: - Molecular - //-------------------------------------------------- - - open func needsToBeConstrained() -> Bool { true } - open func updateView(_ size: CGFloat) {} - open override func reset() { - super.reset() - - isEnabled = true - checkAndBypassAnimations(selected: false) + open override func updateView() { + super.updateView() + //we want to overwrite the VDS color that is set in the ToggleBase + //for surface since the Atomic controls doesn't look at + //surface today for its views. We just want to show whatever + //the current parent's background color. + backgroundColor = .clear } - private func performCheckboxAction(with actionModel: ActionModelProtocol, delegateObject: MVMCoreUIDelegateObject?, additionalData: [AnyHashable: Any]?) { - MVMCoreUIActionHandler.performActionUnstructured(with: actionModel, sourceModel: checkboxModel, additionalData: additionalData, delegateObject: delegateObject) + public func viewModelDidUpdate() { + surface = viewModel.surface + titleModel = viewModel.title + subTitleModel = viewModel.subTitle + badgeModel = viewModel.badge + descriptiveIconModel = viewModel.descriptiveIcon + directionalIconModel = viewModel.directionalIcon + width = viewModel.width + textWidth = viewModel.textWidth + textPercentage = viewModel.textPercentage + } + + //Return the same height as the internal ToggleBase.toggleContainerSize.height + //since this is a class func, we can't reference it directly + public static func estimatedHeight(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?) -> CGFloat? { + nil } - public func set(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable: Any]?) { - self.delegateObject = delegateObject - - guard let model = model as? CheckboxModel else { return } - checkboxModel = model - - FormValidator.setupValidation(for: model, delegate: delegateObject?.formHolderDelegate) - - if model.selected { - checkAndBypassAnimations(selected: model.selected) - } - - model.updateUI = { [weak self] in - MVMCoreDispatchUtility.performBlock(onMainThread: { - guard let self = self else { return } - self.isEnabled = model.enabled && !model.readOnly - }) - } - - isEnabled = model.enabled && !model.readOnly - - if (model.action != nil || model.offAction != nil) { - actionBlock = { [weak self] in - guard let self = self else { return } - - if let offAction = model.offAction, !self.isSelected { - self.performCheckboxAction(with: offAction, delegateObject: delegateObject, additionalData: additionalData) - - } else if let action = model.action { - self.performCheckboxAction(with: action, delegateObject: delegateObject, additionalData: additionalData) - } - } - } - } +} + +// MARK: - MVMCoreUIViewConstrainingProtocol +extension Tilet: MVMCoreUIViewConstrainingProtocol { + + public func needsToBeConstrained() -> Bool { true } + + public func horizontalAlignment() -> UIStackView.Alignment { .trailing } } diff --git a/MVMCoreUI/Atomic/Atoms/Views/TiletModel.swift b/MVMCoreUI/Atomic/Atoms/Views/TiletModel.swift index 340ee329..6dd10735 100644 --- a/MVMCoreUI/Atomic/Atoms/Views/TiletModel.swift +++ b/MVMCoreUI/Atomic/Atoms/Views/TiletModel.swift @@ -20,9 +20,9 @@ open class TiletModel: MoleculeModelProtocol { public var badge: TiletBadgeModel? public var title: TiletTitleModel? public var subTitle: TiletSubTitleModel? - public var desriptiveIcon: TiletDescriptiveIcon? + public var descriptiveIcon: TiletDescriptiveIcon? public var directionalIcon: TiletDirectionalIcon? - public var width: Double? - public var textWidth: Double? - public var textPercentage: Double? + public var width: CGFloat? + public var textWidth: CGFloat? + public var textPercentage: CGFloat? } From 7e0d9ef0f7ab55b588abf0318ef27e4b63ddaece Mon Sep 17 00:00:00 2001 From: Matt Bruce Date: Thu, 12 Jan 2023 15:53:42 -0600 Subject: [PATCH 07/35] added registration for Tilet Signed-off-by: Matt Bruce --- MVMCoreUI/OtherHandlers/CoreUIModelMapping.swift | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/MVMCoreUI/OtherHandlers/CoreUIModelMapping.swift b/MVMCoreUI/OtherHandlers/CoreUIModelMapping.swift index 3e5357ea..49451313 100644 --- a/MVMCoreUI/OtherHandlers/CoreUIModelMapping.swift +++ b/MVMCoreUI/OtherHandlers/CoreUIModelMapping.swift @@ -71,7 +71,8 @@ open class CoreUIModelMapping: ModelMapping { ModelRegistry.register(handler: WebView.self, for: WebViewModel.self) ModelRegistry.register(handler: LoadingSpinner.self, for: LoadingSpinnerModel.self) ModelRegistry.register(handler: Video.self, for: VideoModel.self) - + ModelRegistry.register(handler: Tilet.self, for: TiletModel.self) + // MARK:- Horizontal Combination Molecules ModelRegistry.register(handler: StringAndMoleculeView.self, for: StringAndMoleculeModel.self) ModelRegistry.register(handler: ImageHeadlineBody.self, for: ImageHeadlineBodyModel.self) From 1b4d7f0f2a75a83799410a83c9123fc8e00c34bc Mon Sep 17 00:00:00 2001 From: Matt Bruce Date: Thu, 12 Jan 2023 15:54:02 -0600 Subject: [PATCH 08/35] removed bad code that i copied from the Toggle. Signed-off-by: Matt Bruce --- MVMCoreUI/Atomic/Atoms/Views/Tilet.swift | 23 ++--------------------- 1 file changed, 2 insertions(+), 21 deletions(-) diff --git a/MVMCoreUI/Atomic/Atoms/Views/Tilet.swift b/MVMCoreUI/Atomic/Atoms/Views/Tilet.swift index 9dc5acbb..59886edf 100644 --- a/MVMCoreUI/Atomic/Atoms/Views/Tilet.swift +++ b/MVMCoreUI/Atomic/Atoms/Views/Tilet.swift @@ -29,16 +29,7 @@ open class Tilet: VDS.Tilet, VDSMoleculeViewProtocol { } open func updateView(_ size: CGFloat) {} - - open override func updateView() { - super.updateView() - //we want to overwrite the VDS color that is set in the ToggleBase - //for surface since the Atomic controls doesn't look at - //surface today for its views. We just want to show whatever - //the current parent's background color. - backgroundColor = .clear - } - + public func viewModelDidUpdate() { surface = viewModel.surface titleModel = viewModel.title @@ -51,19 +42,9 @@ open class Tilet: VDS.Tilet, VDSMoleculeViewProtocol { textPercentage = viewModel.textPercentage } - //Return the same height as the internal ToggleBase.toggleContainerSize.height //since this is a class func, we can't reference it directly public static func estimatedHeight(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?) -> CGFloat? { - nil + 100 } } - -// MARK: - MVMCoreUIViewConstrainingProtocol -extension Tilet: MVMCoreUIViewConstrainingProtocol { - - public func needsToBeConstrained() -> Bool { true } - - public func horizontalAlignment() -> UIStackView.Alignment { .trailing } -} - From a2fd68be154ab22a88e531aa2296c7fa6d7518a2 Mon Sep 17 00:00:00 2001 From: Matt Bruce Date: Fri, 13 Jan 2023 08:28:24 -0600 Subject: [PATCH 09/35] updated with more properties Signed-off-by: Matt Bruce --- MVMCoreUI/Atomic/Atoms/Views/Tilet.swift | 10 ++++++---- MVMCoreUI/Atomic/Atoms/Views/TiletModel.swift | 4 +++- 2 files changed, 9 insertions(+), 5 deletions(-) diff --git a/MVMCoreUI/Atomic/Atoms/Views/Tilet.swift b/MVMCoreUI/Atomic/Atoms/Views/Tilet.swift index 59886edf..c8b4e58a 100644 --- a/MVMCoreUI/Atomic/Atoms/Views/Tilet.swift +++ b/MVMCoreUI/Atomic/Atoms/Views/Tilet.swift @@ -31,15 +31,17 @@ open class Tilet: VDS.Tilet, VDSMoleculeViewProtocol { open func updateView(_ size: CGFloat) {} public func viewModelDidUpdate() { - surface = viewModel.surface + containerBackgroundColor = viewModel.containerBackgroundColor + containerPadding = viewModel.containerPadding + aspectRatio = viewModel.aspectRatio + width = viewModel.width + textWidth = viewModel.textWidth + textPercentage = viewModel.textPercentage titleModel = viewModel.title subTitleModel = viewModel.subTitle badgeModel = viewModel.badge descriptiveIconModel = viewModel.descriptiveIcon directionalIconModel = viewModel.directionalIcon - width = viewModel.width - textWidth = viewModel.textWidth - textPercentage = viewModel.textPercentage } //since this is a class func, we can't reference it directly diff --git a/MVMCoreUI/Atomic/Atoms/Views/TiletModel.swift b/MVMCoreUI/Atomic/Atoms/Views/TiletModel.swift index 6dd10735..f0d37272 100644 --- a/MVMCoreUI/Atomic/Atoms/Views/TiletModel.swift +++ b/MVMCoreUI/Atomic/Atoms/Views/TiletModel.swift @@ -16,7 +16,9 @@ open class TiletModel: MoleculeModelProtocol { //-------------------------------------------------- public static var identifier: String = "tilet" public var backgroundColor: Color? - public var surface: Surface = .light + public var containerBackgroundColor: TileContainer.ContainerBackgroundColor = .black + public var containerPadding: TileContainer.ContainerPadding = .padding4X + public var aspectRatio: TileContainer.ContainerScalingType = .none public var badge: TiletBadgeModel? public var title: TiletTitleModel? public var subTitle: TiletSubTitleModel? From e1729d234e79ab6ecbf967c9f5616e68983445a7 Mon Sep 17 00:00:00 2001 From: Matt Bruce Date: Fri, 13 Jan 2023 09:45:56 -0600 Subject: [PATCH 10/35] refactored enums/models Signed-off-by: Matt Bruce --- MVMCoreUI/Atomic/Atoms/Views/Tilet.swift | 4 ++-- MVMCoreUI/Atomic/Atoms/Views/TiletModel.swift | 6 +++--- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/MVMCoreUI/Atomic/Atoms/Views/Tilet.swift b/MVMCoreUI/Atomic/Atoms/Views/Tilet.swift index c8b4e58a..71fe0190 100644 --- a/MVMCoreUI/Atomic/Atoms/Views/Tilet.swift +++ b/MVMCoreUI/Atomic/Atoms/Views/Tilet.swift @@ -31,8 +31,8 @@ open class Tilet: VDS.Tilet, VDSMoleculeViewProtocol { open func updateView(_ size: CGFloat) {} public func viewModelDidUpdate() { - containerBackgroundColor = viewModel.containerBackgroundColor - containerPadding = viewModel.containerPadding + color = viewModel.color + padding = viewModel.padding aspectRatio = viewModel.aspectRatio width = viewModel.width textWidth = viewModel.textWidth diff --git a/MVMCoreUI/Atomic/Atoms/Views/TiletModel.swift b/MVMCoreUI/Atomic/Atoms/Views/TiletModel.swift index f0d37272..bc5a3588 100644 --- a/MVMCoreUI/Atomic/Atoms/Views/TiletModel.swift +++ b/MVMCoreUI/Atomic/Atoms/Views/TiletModel.swift @@ -16,9 +16,9 @@ open class TiletModel: MoleculeModelProtocol { //-------------------------------------------------- public static var identifier: String = "tilet" public var backgroundColor: Color? - public var containerBackgroundColor: TileContainer.ContainerBackgroundColor = .black - public var containerPadding: TileContainer.ContainerPadding = .padding4X - public var aspectRatio: TileContainer.ContainerScalingType = .none + public var color: TileContainer.BackgroundColor = .black + public var padding: TileContainer.Padding = .padding4X + public var aspectRatio: TileContainer.AspectRatio = .none public var badge: TiletBadgeModel? public var title: TiletTitleModel? public var subTitle: TiletSubTitleModel? From 394c78f065044a028322a6cb8a3d779605cecc30 Mon Sep 17 00:00:00 2001 From: Matt Bruce Date: Fri, 13 Jan 2023 14:31:39 -0600 Subject: [PATCH 11/35] refactored for vds changes Signed-off-by: Matt Bruce --- MVMCoreUI/Atomic/Atoms/Views/TiletModel.swift | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/MVMCoreUI/Atomic/Atoms/Views/TiletModel.swift b/MVMCoreUI/Atomic/Atoms/Views/TiletModel.swift index bc5a3588..9b233e57 100644 --- a/MVMCoreUI/Atomic/Atoms/Views/TiletModel.swift +++ b/MVMCoreUI/Atomic/Atoms/Views/TiletModel.swift @@ -19,11 +19,11 @@ open class TiletModel: MoleculeModelProtocol { public var color: TileContainer.BackgroundColor = .black public var padding: TileContainer.Padding = .padding4X public var aspectRatio: TileContainer.AspectRatio = .none - public var badge: TiletBadgeModel? - public var title: TiletTitleModel? - public var subTitle: TiletSubTitleModel? - public var descriptiveIcon: TiletDescriptiveIcon? - public var directionalIcon: TiletDirectionalIcon? + public var badge: Tilet.BadgeModel? + public var title: Tilet.TitleModel? + public var subTitle: Tilet.SubTitleModel? + public var descriptiveIcon: Tilet.DescriptiveIcon? + public var directionalIcon: Tilet.DirectionalIcon? public var width: CGFloat? public var textWidth: CGFloat? public var textPercentage: CGFloat? From 60e4b6f2c23cd0fbddfff25523c0a8242e8605ea Mon Sep 17 00:00:00 2001 From: Matt Bruce Date: Tue, 17 Jan 2023 10:01:37 -0600 Subject: [PATCH 12/35] added defaults into decode func Signed-off-by: Matt Bruce --- MVMCoreUI/Atomic/Atoms/Views/TiletModel.swift | 22 ++++++++++++++++--- 1 file changed, 19 insertions(+), 3 deletions(-) diff --git a/MVMCoreUI/Atomic/Atoms/Views/TiletModel.swift b/MVMCoreUI/Atomic/Atoms/Views/TiletModel.swift index 9b233e57..c3720b2b 100644 --- a/MVMCoreUI/Atomic/Atoms/Views/TiletModel.swift +++ b/MVMCoreUI/Atomic/Atoms/Views/TiletModel.swift @@ -16,9 +16,9 @@ open class TiletModel: MoleculeModelProtocol { //-------------------------------------------------- public static var identifier: String = "tilet" public var backgroundColor: Color? - public var color: TileContainer.BackgroundColor = .black - public var padding: TileContainer.Padding = .padding4X - public var aspectRatio: TileContainer.AspectRatio = .none + public var color: TileContainer.BackgroundColor + public var padding: TileContainer.Padding + public var aspectRatio: TileContainer.AspectRatio public var badge: Tilet.BadgeModel? public var title: Tilet.TitleModel? public var subTitle: Tilet.SubTitleModel? @@ -27,4 +27,20 @@ open class TiletModel: MoleculeModelProtocol { public var width: CGFloat? public var textWidth: CGFloat? public var textPercentage: CGFloat? + + required public init(from decoder: Decoder) throws { + let container = try decoder.container(keyedBy: CodingKeys.self) + self.backgroundColor = try container.decodeIfPresent(Color.self, forKey: .backgroundColor) + self.color = try container.decodeIfPresent(TileContainer.BackgroundColor.self, forKey: .color) ?? TileContainer.BackgroundColor.black + self.padding = try container.decodeIfPresent(TileContainer.Padding.self, forKey: .padding) ?? TileContainer.Padding.padding4X + self.aspectRatio = try container.decodeIfPresent(TileContainer.AspectRatio.self, forKey: .aspectRatio) ?? TileContainer.AspectRatio.none + self.badge = try container.decodeIfPresent(Tilet.BadgeModel.self, forKey: .badge) + self.title = try container.decodeIfPresent(Tilet.TitleModel.self, forKey: .title) + self.subTitle = try container.decodeIfPresent(Tilet.SubTitleModel.self, forKey: .subTitle) + self.descriptiveIcon = try container.decodeIfPresent(Tilet.DescriptiveIcon.self, forKey: .descriptiveIcon) + self.directionalIcon = try container.decodeIfPresent(Tilet.DirectionalIcon.self, forKey: .directionalIcon) ?? Tilet.DirectionalIcon.init(size: .medium, surface: .dark) + self.width = try container.decodeIfPresent(CGFloat.self, forKey: .width) + self.textWidth = try container.decodeIfPresent(CGFloat.self, forKey: .textWidth) + self.textPercentage = try container.decodeIfPresent(CGFloat.self, forKey: .textPercentage) + } } From bff34ec1e18a59e5b52ab235ca8a59ddf1c18b00 Mon Sep 17 00:00:00 2001 From: Matt Bruce Date: Tue, 17 Jan 2023 15:16:29 -0600 Subject: [PATCH 13/35] mispelled the class, it should be Tilelet Signed-off-by: Matt Bruce --- MVMCoreUI.xcodeproj/project.pbxproj | 16 ++++++------- .../Views/{Tilet.swift => Tilelet.swift} | 4 ++-- .../{TiletModel.swift => TileletModel.swift} | 24 +++++++++---------- .../OtherHandlers/CoreUIModelMapping.swift | 2 +- 4 files changed, 23 insertions(+), 23 deletions(-) rename MVMCoreUI/Atomic/Atoms/Views/{Tilet.swift => Tilelet.swift} (93%) rename MVMCoreUI/Atomic/Atoms/Views/{TiletModel.swift => TileletModel.swift} (68%) diff --git a/MVMCoreUI.xcodeproj/project.pbxproj b/MVMCoreUI.xcodeproj/project.pbxproj index 07d944e2..361f74eb 100644 --- a/MVMCoreUI.xcodeproj/project.pbxproj +++ b/MVMCoreUI.xcodeproj/project.pbxproj @@ -595,10 +595,10 @@ EA5124FF2436018E0051A3A4 /* BGImageHeadlineBodyButtonModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = EA5124FE2436018E0051A3A4 /* BGImageHeadlineBodyButtonModel.swift */; }; EA7E67742758310500ABF773 /* EnableFormFieldEffectModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = EA7E67732758310500ABF773 /* EnableFormFieldEffectModel.swift */; }; EA7E67762758365300ABF773 /* UIUpdatableModelProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = EA7E67752758365300ABF773 /* UIUpdatableModelProtocol.swift */; }; + EA985C3E2970938F00F2FF2E /* Tilelet.swift in Sources */ = {isa = PBXBuildFile; fileRef = EA985C3D2970938F00F2FF2E /* Tilelet.swift */; }; + EA985C402970939A00F2FF2E /* TileletModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = EA985C3F2970939A00F2FF2E /* TileletModel.swift */; }; EA985C602970A3F000F2FF2E /* VDS.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = EA985C5F2970A3F000F2FF2E /* VDS.framework */; }; EA985C642970A40E00F2FF2E /* VDSTypographyTokens.xcframework in Frameworks */ = {isa = PBXBuildFile; fileRef = EA985C632970A40E00F2FF2E /* VDSTypographyTokens.xcframework */; }; - EA985C3E2970938F00F2FF2E /* Tilet.swift in Sources */ = {isa = PBXBuildFile; fileRef = EA985C3D2970938F00F2FF2E /* Tilet.swift */; }; - EA985C402970939A00F2FF2E /* TiletModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = EA985C3F2970939A00F2FF2E /* TiletModel.swift */; }; EAA0CFAF275E7D8000D65EB0 /* FormFieldEffectProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = EAA0CFAE275E7D8000D65EB0 /* FormFieldEffectProtocol.swift */; }; EAA0CFB1275E823A00D65EB0 /* HideFormFieldEffectModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = EAA0CFB0275E823A00D65EB0 /* HideFormFieldEffectModel.swift */; }; EAA0CFB3275E831E00D65EB0 /* DisableFormFieldEffectModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = EAA0CFB2275E831E00D65EB0 /* DisableFormFieldEffectModel.swift */; }; @@ -1202,10 +1202,10 @@ EA5124FE2436018E0051A3A4 /* BGImageHeadlineBodyButtonModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BGImageHeadlineBodyButtonModel.swift; sourceTree = ""; }; EA7E67732758310500ABF773 /* EnableFormFieldEffectModel.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = EnableFormFieldEffectModel.swift; sourceTree = ""; }; EA7E67752758365300ABF773 /* UIUpdatableModelProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UIUpdatableModelProtocol.swift; sourceTree = ""; }; + EA985C3D2970938F00F2FF2E /* Tilelet.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Tilelet.swift; sourceTree = ""; }; + EA985C3F2970939A00F2FF2E /* TileletModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TileletModel.swift; sourceTree = ""; }; EA985C5F2970A3F000F2FF2E /* VDS.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; path = VDS.framework; sourceTree = BUILT_PRODUCTS_DIR; }; EA985C632970A40E00F2FF2E /* VDSTypographyTokens.xcframework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcframework; name = VDSTypographyTokens.xcframework; path = ../SharedFrameworks/VDSTypographyTokens.xcframework; sourceTree = ""; }; - EA985C3D2970938F00F2FF2E /* Tilet.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Tilet.swift; sourceTree = ""; }; - EA985C3F2970939A00F2FF2E /* TiletModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TiletModel.swift; sourceTree = ""; }; EAA0CFAE275E7D8000D65EB0 /* FormFieldEffectProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FormFieldEffectProtocol.swift; sourceTree = ""; }; EAA0CFB0275E823A00D65EB0 /* HideFormFieldEffectModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HideFormFieldEffectModel.swift; sourceTree = ""; }; EAA0CFB2275E831E00D65EB0 /* DisableFormFieldEffectModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DisableFormFieldEffectModel.swift; sourceTree = ""; }; @@ -2269,8 +2269,8 @@ AA37CBD42519072F0027344C /* Stars.swift */, AA07EA902510A442009A2AE3 /* StarModel.swift */, AA07EA922510A451009A2AE3 /* Star.swift */, - EA985C3D2970938F00F2FF2E /* Tilet.swift */, - EA985C3F2970939A00F2FF2E /* TiletModel.swift */, + EA985C3D2970938F00F2FF2E /* Tilelet.swift */, + EA985C3F2970939A00F2FF2E /* TileletModel.swift */, ); path = Views; sourceTree = ""; @@ -2794,7 +2794,7 @@ D2E2A99D23DA3217000B42E6 /* UIStackViewAlignment+Extension.swift in Sources */, 01EB369423609801006832FA /* HeadlineBodyModel.swift in Sources */, D2A92884241ACB25004E01C6 /* ProgrammaticScrollViewController.swift in Sources */, - EA985C3E2970938F00F2FF2E /* Tilet.swift in Sources */, + EA985C3E2970938F00F2FF2E /* Tilelet.swift in Sources */, D23A90002612347A007E14CE /* PageBehaviorHandlerModelProtocol.swift in Sources */, EAA78020290081320057DFDF /* VDSMoleculeViewProtocol.swift in Sources */, 0A21DB7F235DECC500C160A2 /* EntryField.swift in Sources */, @@ -3189,7 +3189,7 @@ D29E28DD23D7404C00ACEA85 /* ContainerHelper.swift in Sources */, 012A88C2238D7BCA00FE3DA1 /* CarouselItemModel.swift in Sources */, 27F6B08C26052AFF008529AA /* ParentMoleculeModelProtocol.swift in Sources */, - EA985C402970939A00F2FF2E /* TiletModel.swift in Sources */, + EA985C402970939A00F2FF2E /* TileletModel.swift in Sources */, 0AB764D324460FA400E7FE72 /* UIPickerView+Extension.swift in Sources */, D29DF29E21E7AE3B003B2FB9 /* MFStyler.m in Sources */, 94C661D923CCF4B400D9FE5B /* LeftRightLabelModel.swift in Sources */, diff --git a/MVMCoreUI/Atomic/Atoms/Views/Tilet.swift b/MVMCoreUI/Atomic/Atoms/Views/Tilelet.swift similarity index 93% rename from MVMCoreUI/Atomic/Atoms/Views/Tilet.swift rename to MVMCoreUI/Atomic/Atoms/Views/Tilelet.swift index 71fe0190..4d7a32e1 100644 --- a/MVMCoreUI/Atomic/Atoms/Views/Tilet.swift +++ b/MVMCoreUI/Atomic/Atoms/Views/Tilelet.swift @@ -13,11 +13,11 @@ import VDS /** This class expects its height and width to be equal. */ -open class Tilet: VDS.Tilet, VDSMoleculeViewProtocol { +open class Tilelet: VDS.Tilelet, VDSMoleculeViewProtocol { //-------------------------------------------------- // MARK: - Properties //-------------------------------------------------- - public var viewModel: TiletModel! + public var viewModel: TileletModel! public var delegateObject: MVMCoreUIDelegateObject? public var additionalData: [AnyHashable: Any]? diff --git a/MVMCoreUI/Atomic/Atoms/Views/TiletModel.swift b/MVMCoreUI/Atomic/Atoms/Views/TileletModel.swift similarity index 68% rename from MVMCoreUI/Atomic/Atoms/Views/TiletModel.swift rename to MVMCoreUI/Atomic/Atoms/Views/TileletModel.swift index c3720b2b..f9a35c43 100644 --- a/MVMCoreUI/Atomic/Atoms/Views/TiletModel.swift +++ b/MVMCoreUI/Atomic/Atoms/Views/TileletModel.swift @@ -9,21 +9,21 @@ import Foundation import VDS -open class TiletModel: MoleculeModelProtocol { +open class TileletModel: MoleculeModelProtocol { //-------------------------------------------------- // MARK: - Properties //-------------------------------------------------- - public static var identifier: String = "tilet" + public static var identifier: String = "tilelet" public var backgroundColor: Color? public var color: TileContainer.BackgroundColor public var padding: TileContainer.Padding public var aspectRatio: TileContainer.AspectRatio - public var badge: Tilet.BadgeModel? - public var title: Tilet.TitleModel? - public var subTitle: Tilet.SubTitleModel? - public var descriptiveIcon: Tilet.DescriptiveIcon? - public var directionalIcon: Tilet.DirectionalIcon? + public var badge: Tilelet.BadgeModel? + public var title: Tilelet.TitleModel? + public var subTitle: Tilelet.SubTitleModel? + public var descriptiveIcon: Tilelet.DescriptiveIcon? + public var directionalIcon: Tilelet.DirectionalIcon? public var width: CGFloat? public var textWidth: CGFloat? public var textPercentage: CGFloat? @@ -34,11 +34,11 @@ open class TiletModel: MoleculeModelProtocol { self.color = try container.decodeIfPresent(TileContainer.BackgroundColor.self, forKey: .color) ?? TileContainer.BackgroundColor.black self.padding = try container.decodeIfPresent(TileContainer.Padding.self, forKey: .padding) ?? TileContainer.Padding.padding4X self.aspectRatio = try container.decodeIfPresent(TileContainer.AspectRatio.self, forKey: .aspectRatio) ?? TileContainer.AspectRatio.none - self.badge = try container.decodeIfPresent(Tilet.BadgeModel.self, forKey: .badge) - self.title = try container.decodeIfPresent(Tilet.TitleModel.self, forKey: .title) - self.subTitle = try container.decodeIfPresent(Tilet.SubTitleModel.self, forKey: .subTitle) - self.descriptiveIcon = try container.decodeIfPresent(Tilet.DescriptiveIcon.self, forKey: .descriptiveIcon) - self.directionalIcon = try container.decodeIfPresent(Tilet.DirectionalIcon.self, forKey: .directionalIcon) ?? Tilet.DirectionalIcon.init(size: .medium, surface: .dark) + self.badge = try container.decodeIfPresent(Tilelet.BadgeModel.self, forKey: .badge) + self.title = try container.decodeIfPresent(Tilelet.TitleModel.self, forKey: .title) + self.subTitle = try container.decodeIfPresent(Tilelet.SubTitleModel.self, forKey: .subTitle) + self.descriptiveIcon = try container.decodeIfPresent(Tilelet.DescriptiveIcon.self, forKey: .descriptiveIcon) + self.directionalIcon = try container.decodeIfPresent(Tilelet.DirectionalIcon.self, forKey: .directionalIcon) self.width = try container.decodeIfPresent(CGFloat.self, forKey: .width) self.textWidth = try container.decodeIfPresent(CGFloat.self, forKey: .textWidth) self.textPercentage = try container.decodeIfPresent(CGFloat.self, forKey: .textPercentage) diff --git a/MVMCoreUI/OtherHandlers/CoreUIModelMapping.swift b/MVMCoreUI/OtherHandlers/CoreUIModelMapping.swift index 49451313..c27553ec 100644 --- a/MVMCoreUI/OtherHandlers/CoreUIModelMapping.swift +++ b/MVMCoreUI/OtherHandlers/CoreUIModelMapping.swift @@ -71,7 +71,7 @@ open class CoreUIModelMapping: ModelMapping { ModelRegistry.register(handler: WebView.self, for: WebViewModel.self) ModelRegistry.register(handler: LoadingSpinner.self, for: LoadingSpinnerModel.self) ModelRegistry.register(handler: Video.self, for: VideoModel.self) - ModelRegistry.register(handler: Tilet.self, for: TiletModel.self) + ModelRegistry.register(handler: Tilelet.self, for: TileletModel.self) // MARK:- Horizontal Combination Molecules ModelRegistry.register(handler: StringAndMoleculeView.self, for: StringAndMoleculeModel.self) From bfcd559ac40498806867bd0abddc2ec300d101f5 Mon Sep 17 00:00:00 2001 From: Matt Bruce Date: Wed, 25 Jan 2023 12:19:50 -0600 Subject: [PATCH 14/35] updated models Signed-off-by: Matt Bruce --- MVMCoreUI/Atomic/Atoms/Views/Tilelet.swift | 4 +- .../Atomic/Atoms/Views/TileletModel.swift | 109 +++++++++++++++++- 2 files changed, 107 insertions(+), 6 deletions(-) diff --git a/MVMCoreUI/Atomic/Atoms/Views/Tilelet.swift b/MVMCoreUI/Atomic/Atoms/Views/Tilelet.swift index 4d7a32e1..101fd1f1 100644 --- a/MVMCoreUI/Atomic/Atoms/Views/Tilelet.swift +++ b/MVMCoreUI/Atomic/Atoms/Views/Tilelet.swift @@ -37,8 +37,8 @@ open class Tilelet: VDS.Tilelet, VDSMoleculeViewProtocol { width = viewModel.width textWidth = viewModel.textWidth textPercentage = viewModel.textPercentage - titleModel = viewModel.title - subTitleModel = viewModel.subTitle + titleModel = viewModel.titleModel + subTitleModel = viewModel.subTitleModel badgeModel = viewModel.badge descriptiveIconModel = viewModel.descriptiveIcon directionalIconModel = viewModel.directionalIcon diff --git a/MVMCoreUI/Atomic/Atoms/Views/TileletModel.swift b/MVMCoreUI/Atomic/Atoms/Views/TileletModel.swift index f9a35c43..64991c50 100644 --- a/MVMCoreUI/Atomic/Atoms/Views/TileletModel.swift +++ b/MVMCoreUI/Atomic/Atoms/Views/TileletModel.swift @@ -20,8 +20,8 @@ open class TileletModel: MoleculeModelProtocol { public var padding: TileContainer.Padding public var aspectRatio: TileContainer.AspectRatio public var badge: Tilelet.BadgeModel? - public var title: Tilelet.TitleModel? - public var subTitle: Tilelet.SubTitleModel? + public var title: LabelModel? + public var subTitle: LabelModel? public var descriptiveIcon: Tilelet.DescriptiveIcon? public var directionalIcon: Tilelet.DirectionalIcon? public var width: CGFloat? @@ -35,12 +35,113 @@ open class TileletModel: MoleculeModelProtocol { self.padding = try container.decodeIfPresent(TileContainer.Padding.self, forKey: .padding) ?? TileContainer.Padding.padding4X self.aspectRatio = try container.decodeIfPresent(TileContainer.AspectRatio.self, forKey: .aspectRatio) ?? TileContainer.AspectRatio.none self.badge = try container.decodeIfPresent(Tilelet.BadgeModel.self, forKey: .badge) - self.title = try container.decodeIfPresent(Tilelet.TitleModel.self, forKey: .title) - self.subTitle = try container.decodeIfPresent(Tilelet.SubTitleModel.self, forKey: .subTitle) + self.title = try container.decodeIfPresent(LabelModel.self, forKey: .title) + self.subTitle = try container.decodeIfPresent(LabelModel.self, forKey: .subTitle) self.descriptiveIcon = try container.decodeIfPresent(Tilelet.DescriptiveIcon.self, forKey: .descriptiveIcon) self.directionalIcon = try container.decodeIfPresent(Tilelet.DirectionalIcon.self, forKey: .directionalIcon) self.width = try container.decodeIfPresent(CGFloat.self, forKey: .width) self.textWidth = try container.decodeIfPresent(CGFloat.self, forKey: .textWidth) self.textPercentage = try container.decodeIfPresent(CGFloat.self, forKey: .textPercentage) } + + public var titleModel: Tilelet.TitleModel? { + guard let title else { return nil } + let style = title.fontStyle?.vdsTextStyle + if let style, let found = Tilelet.TitleModel.TextStyle(rawValue: style.rawValue) { + return .init(text: title.text, textStyle: found) + } else { + return .init(text: title.text) + } + } + + public var subTitleModel: Tilelet.SubTitleModel? { + guard let subTitle else { return nil } + let style = subTitle.fontStyle?.vdsTextStyle + if let style, let found = Tilelet.SubTitleModel.TextStyle(rawValue: style.rawValue) { + return .init(text: subTitle.text, textStyle: found) + } else { + return .init(text: subTitle.text) + } + } +} + +extension Styler.Font { + public var vdsTextStyle: VDS.TextStyle? { + let raw = "\(self)" + let newRaw = raw.prefix(1).lowercased() + raw.dropFirst() + guard let style = VDS.TextStyle(rawValue: newRaw) else { return nil } + return style + } +} + +extension TileContainer.BackgroundColor: Codable {} +extension TileContainer.Padding: Codable {} +extension TileContainer.AspectRatio: Codable {} +extension Surface: Codable {} +extension Badge.FillColor: Codable {} +extension Icon.Name: Codable {} +extension Icon.Size: Codable {} + +extension Tilelet.BadgeModel: Codable { + private enum CodingKeys: String, CodingKey { + case text, fillColor, surface, numberOfLines, maxWidth + } + + public init(from decoder: Decoder) throws { + let container = try decoder.container(keyedBy: CodingKeys.self) + let text = try container.decode(String.self, forKey: .text) + let fillColor = try container.decodeIfPresent(Badge.FillColor.self, forKey: .fillColor) ?? .red + let surface = try container.decodeIfPresent(Surface.self, forKey: .surface) ?? .light + let numberOfLines = try container.decodeIfPresent(Int.self, forKey: .numberOfLines) ?? 0 + let maxWidth = try container.decodeIfPresent(CGFloat.self, forKey: .maxWidth) + self.init(text: text, fillColor: fillColor, surface: surface, numberOfLines: numberOfLines, maxWidth: maxWidth) + } + + public func encode(to encoder: Encoder) throws { + var container = encoder.container(keyedBy: CodingKeys.self) + try container.encode(fillColor, forKey: .fillColor) + try container.encode(surface, forKey: .surface) + try container.encode(numberOfLines, forKey: .numberOfLines) + try container.encodeIfPresent(maxWidth, forKey: .maxWidth) + } +} + +extension Tilelet.DescriptiveIcon: Codable { + private enum CodingKeys: String, CodingKey { + case name, size, surface + } + + public init(from decoder: Decoder) throws { + let container = try decoder.container(keyedBy: CodingKeys.self) + let name = try container.decode(Icon.Name.self, forKey: .name) + let size = try container.decodeIfPresent(Icon.Size.self, forKey: .size) ?? .medium + let surface = try container.decodeIfPresent(Surface.self, forKey: .surface) ?? .dark + self.init(name: name, size: size, surface: surface) + } + + public func encode(to encoder: Encoder) throws { + var container = encoder.container(keyedBy: CodingKeys.self) + try container.encode(name, forKey: .name) + try container.encode(size, forKey: .size) + try container.encode(surface, forKey: .surface) + } +} + +extension Tilelet.DirectionalIcon: Codable { + private enum CodingKeys: String, CodingKey { + case size, surface + } + + public init(from decoder: Decoder) throws { + let container = try decoder.container(keyedBy: CodingKeys.self) + let size = try container.decodeIfPresent(Icon.Size.self, forKey: .size) ?? .medium + let surface = try container.decodeIfPresent(Surface.self, forKey: .surface) ?? .dark + self.init(size: size, surface: surface) + } + + public func encode(to encoder: Encoder) throws { + var container = encoder.container(keyedBy: CodingKeys.self) + try container.encode(size, forKey: .size) + try container.encode(surface, forKey: .surface) + } } From e28cc4fc5bb88e349ae991b621f3579514df5413 Mon Sep 17 00:00:00 2001 From: Matt Bruce Date: Wed, 25 Jan 2023 13:04:19 -0600 Subject: [PATCH 15/35] added VDS initial extensions Signed-off-by: Matt Bruce --- MVMCoreUI.xcodeproj/project.pbxproj | 12 +++ .../Atomic/Extensions/VDS-Enums+Codable.swift | 18 +++++ .../Atomic/Extensions/VDS-TextStyle.swift | 31 ++++++++ .../Extensions/VDS-Tilelet+Codable.swift | 75 +++++++++++++++++++ 4 files changed, 136 insertions(+) create mode 100644 MVMCoreUI/Atomic/Extensions/VDS-Enums+Codable.swift create mode 100644 MVMCoreUI/Atomic/Extensions/VDS-TextStyle.swift create mode 100644 MVMCoreUI/Atomic/Extensions/VDS-Tilelet+Codable.swift diff --git a/MVMCoreUI.xcodeproj/project.pbxproj b/MVMCoreUI.xcodeproj/project.pbxproj index 361f74eb..5855f95f 100644 --- a/MVMCoreUI.xcodeproj/project.pbxproj +++ b/MVMCoreUI.xcodeproj/project.pbxproj @@ -599,6 +599,9 @@ EA985C402970939A00F2FF2E /* TileletModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = EA985C3F2970939A00F2FF2E /* TileletModel.swift */; }; EA985C602970A3F000F2FF2E /* VDS.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = EA985C5F2970A3F000F2FF2E /* VDS.framework */; }; EA985C642970A40E00F2FF2E /* VDSTypographyTokens.xcframework in Frameworks */ = {isa = PBXBuildFile; fileRef = EA985C632970A40E00F2FF2E /* VDSTypographyTokens.xcframework */; }; + EA985C852981AA9C00F2FF2E /* VDS-Enums+Codable.swift in Sources */ = {isa = PBXBuildFile; fileRef = EA985C842981AA9C00F2FF2E /* VDS-Enums+Codable.swift */; }; + EA985C872981AB0F00F2FF2E /* VDS-Tilelet+Codable.swift in Sources */ = {isa = PBXBuildFile; fileRef = EA985C862981AB0F00F2FF2E /* VDS-Tilelet+Codable.swift */; }; + EA985C892981AB7100F2FF2E /* VDS-TextStyle.swift in Sources */ = {isa = PBXBuildFile; fileRef = EA985C882981AB7100F2FF2E /* VDS-TextStyle.swift */; }; EAA0CFAF275E7D8000D65EB0 /* FormFieldEffectProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = EAA0CFAE275E7D8000D65EB0 /* FormFieldEffectProtocol.swift */; }; EAA0CFB1275E823A00D65EB0 /* HideFormFieldEffectModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = EAA0CFB0275E823A00D65EB0 /* HideFormFieldEffectModel.swift */; }; EAA0CFB3275E831E00D65EB0 /* DisableFormFieldEffectModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = EAA0CFB2275E831E00D65EB0 /* DisableFormFieldEffectModel.swift */; }; @@ -1206,6 +1209,9 @@ EA985C3F2970939A00F2FF2E /* TileletModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TileletModel.swift; sourceTree = ""; }; EA985C5F2970A3F000F2FF2E /* VDS.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; path = VDS.framework; sourceTree = BUILT_PRODUCTS_DIR; }; EA985C632970A40E00F2FF2E /* VDSTypographyTokens.xcframework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcframework; name = VDSTypographyTokens.xcframework; path = ../SharedFrameworks/VDSTypographyTokens.xcframework; sourceTree = ""; }; + EA985C842981AA9C00F2FF2E /* VDS-Enums+Codable.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "VDS-Enums+Codable.swift"; sourceTree = ""; }; + EA985C862981AB0F00F2FF2E /* VDS-Tilelet+Codable.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "VDS-Tilelet+Codable.swift"; sourceTree = ""; }; + EA985C882981AB7100F2FF2E /* VDS-TextStyle.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "VDS-TextStyle.swift"; sourceTree = ""; }; EAA0CFAE275E7D8000D65EB0 /* FormFieldEffectProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FormFieldEffectProtocol.swift; sourceTree = ""; }; EAA0CFB0275E823A00D65EB0 /* HideFormFieldEffectModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HideFormFieldEffectModel.swift; sourceTree = ""; }; EAA0CFB2275E831E00D65EB0 /* DisableFormFieldEffectModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DisableFormFieldEffectModel.swift; sourceTree = ""; }; @@ -1617,6 +1623,9 @@ D2ED27E7254B0CE600A1C293 /* UIAlertControllerStyle+Extension.swift */, D2E0FFF726AF68530085D696 /* UITableViewRowAnimation+Extension.swift */, 4457904D27ECE989002B1E1E /* UIImageRenderingMode+Extension.swift */, + EA985C842981AA9C00F2FF2E /* VDS-Enums+Codable.swift */, + EA985C862981AB0F00F2FF2E /* VDS-Tilelet+Codable.swift */, + EA985C882981AB7100F2FF2E /* VDS-TextStyle.swift */, ); path = Extensions; sourceTree = ""; @@ -2752,6 +2761,7 @@ D253BB8A24574CC5002DE544 /* StackModel.swift in Sources */, EAB14BC127D935F00012AB2C /* RuleCompareModelProtocol.swift in Sources */, 011D95A924057AC7000E3791 /* FormGroupWatcherFieldProtocol.swift in Sources */, + EA985C892981AB7100F2FF2E /* VDS-TextStyle.swift in Sources */, BB2BF0EA2452A9BB001D0FC2 /* ListDeviceComplexButtonSmall.swift in Sources */, D20C700B250BFDE40095B21C /* MVMCoreUITopAlertView+Extension.swift in Sources */, D236E5B4241FEB1000C38625 /* ListTwoColumnPriceDescription.swift in Sources */, @@ -2776,6 +2786,7 @@ 012A88AD238C418100FE3DA1 /* TemplateProtocol.swift in Sources */, BB6C6AC1242232DF005F7224 /* ListOneColumnTextWithWhitespaceDividerTall.swift in Sources */, 32D2609724C19E2100B56344 /* LockupsPlanSMLXLModel.swift in Sources */, + EA985C872981AB0F00F2FF2E /* VDS-Tilelet+Codable.swift in Sources */, D2092351244F7BE80044AD09 /* ThreeLayerCenterTemplateModel.swift in Sources */, D21B7F77243BB70700051ABF /* MoleculeCollectionItemModel.swift in Sources */, AAB9C10A243496DD00151545 /* RadioSwatch.swift in Sources */, @@ -3103,6 +3114,7 @@ BB2FB3BB247E7EBC00DF73CD /* TagCollectionViewCell.swift in Sources */, 012A88C6238DA34000FE3DA1 /* ModuleMoleculeModel.swift in Sources */, 94C2D9A123872BCC0006CF46 /* LabelAttributeUnderlineModel.swift in Sources */, + EA985C852981AA9C00F2FF2E /* VDS-Enums+Codable.swift in Sources */, AAB8549824DC01BD00477C40 /* ListThreeColumnBillHistoryDividerModel.swift in Sources */, D20A9A5E2243D3E300ADE781 /* TwoButtonView.swift in Sources */, D2B1E3E522F37D6A0065F95C /* ImageHeadlineBody.swift in Sources */, diff --git a/MVMCoreUI/Atomic/Extensions/VDS-Enums+Codable.swift b/MVMCoreUI/Atomic/Extensions/VDS-Enums+Codable.swift new file mode 100644 index 00000000..6c143d9c --- /dev/null +++ b/MVMCoreUI/Atomic/Extensions/VDS-Enums+Codable.swift @@ -0,0 +1,18 @@ +// +// VDS-Enums+Codable.swift +// MVMCoreUI +// +// Created by Matt Bruce on 1/25/23. +// Copyright © 2023 Verizon Wireless. All rights reserved. +// + +import Foundation +import VDS + +extension Surface: Codable {} +extension Badge.FillColor: Codable {} +extension Icon.Name: Codable {} +extension Icon.Size: Codable {} +extension TileContainer.BackgroundColor: Codable {} +extension TileContainer.Padding: Codable {} +extension TileContainer.AspectRatio: Codable {} diff --git a/MVMCoreUI/Atomic/Extensions/VDS-TextStyle.swift b/MVMCoreUI/Atomic/Extensions/VDS-TextStyle.swift new file mode 100644 index 00000000..09fc5dcd --- /dev/null +++ b/MVMCoreUI/Atomic/Extensions/VDS-TextStyle.swift @@ -0,0 +1,31 @@ +// +// VDS-TextStyle.swift +// MVMCoreUI +// +// Created by Matt Bruce on 1/25/23. +// Copyright © 2023 Verizon Wireless. All rights reserved. +// + +import Foundation +import VDS + +extension Styler.Font { + //Converts Legacy Font to a VDS.TextStyle + public func vdsTextStyle() -> VDS.TextStyle? { + let updatedRaw = rawValue.replacingOccurrences(of: "Regular", with: "") + let newRaw = updatedRaw.prefix(1).lowercased() + updatedRaw.dropFirst() + guard let style = VDS.TextStyle(rawValue: newRaw) else { return nil } + return style + } + + public func vdsSubsetStyle() -> T? { + guard let style = vdsTextStyle() else { return nil } + guard let rawValue = style.rawValue as? T.RawValue, + let found = T(rawValue: rawValue) else { + print("Style: \(style.rawValue) is not in enum \(T.self)\ronly these cases exist:\r\(T.allCases)") + return nil + } + return found + } +} + diff --git a/MVMCoreUI/Atomic/Extensions/VDS-Tilelet+Codable.swift b/MVMCoreUI/Atomic/Extensions/VDS-Tilelet+Codable.swift new file mode 100644 index 00000000..17bca4b5 --- /dev/null +++ b/MVMCoreUI/Atomic/Extensions/VDS-Tilelet+Codable.swift @@ -0,0 +1,75 @@ +// +// VDS-Tilelet+Codable.swift +// MVMCoreUI +// +// Created by Matt Bruce on 1/25/23. +// Copyright © 2023 Verizon Wireless. All rights reserved. +// + +import Foundation +import VDS + +extension Tilelet.BadgeModel: Codable { + private enum CodingKeys: String, CodingKey { + case text, fillColor, surface, numberOfLines, maxWidth + } + + public init(from decoder: Decoder) throws { + let container = try decoder.container(keyedBy: CodingKeys.self) + let text = try container.decode(String.self, forKey: .text) + let fillColor = try container.decodeIfPresent(Badge.FillColor.self, forKey: .fillColor) ?? .red + let surface = try container.decodeIfPresent(Surface.self, forKey: .surface) ?? .light + let numberOfLines = try container.decodeIfPresent(Int.self, forKey: .numberOfLines) ?? 0 + let maxWidth = try container.decodeIfPresent(CGFloat.self, forKey: .maxWidth) + self.init(text: text, fillColor: fillColor, surface: surface, numberOfLines: numberOfLines, maxWidth: maxWidth) + } + + public func encode(to encoder: Encoder) throws { + var container = encoder.container(keyedBy: CodingKeys.self) + try container.encode(fillColor, forKey: .fillColor) + try container.encode(surface, forKey: .surface) + try container.encode(numberOfLines, forKey: .numberOfLines) + try container.encodeIfPresent(maxWidth, forKey: .maxWidth) + } +} + +extension Tilelet.DescriptiveIcon: Codable { + private enum CodingKeys: String, CodingKey { + case name, size, surface + } + + public init(from decoder: Decoder) throws { + let container = try decoder.container(keyedBy: CodingKeys.self) + let name = try container.decode(Icon.Name.self, forKey: .name) + let size = try container.decodeIfPresent(Icon.Size.self, forKey: .size) ?? .medium + let surface = try container.decodeIfPresent(Surface.self, forKey: .surface) ?? .dark + self.init(name: name, size: size, surface: surface) + } + + public func encode(to encoder: Encoder) throws { + var container = encoder.container(keyedBy: CodingKeys.self) + try container.encode(name, forKey: .name) + try container.encode(size, forKey: .size) + try container.encode(surface, forKey: .surface) + } +} + +extension Tilelet.DirectionalIcon: Codable { + private enum CodingKeys: String, CodingKey { + case size, surface + } + + public init(from decoder: Decoder) throws { + let container = try decoder.container(keyedBy: CodingKeys.self) + let size = try container.decodeIfPresent(Icon.Size.self, forKey: .size) ?? .medium + let surface = try container.decodeIfPresent(Surface.self, forKey: .surface) ?? .dark + self.init(size: size, surface: surface) + } + + public func encode(to encoder: Encoder) throws { + var container = encoder.container(keyedBy: CodingKeys.self) + try container.encode(size, forKey: .size) + try container.encode(surface, forKey: .surface) + } +} + From 268fdc5c2a7f3e40765f4da20d7a8ee5d2fa44c9 Mon Sep 17 00:00:00 2001 From: Matt Bruce Date: Wed, 25 Jan 2023 13:04:33 -0600 Subject: [PATCH 16/35] updated model against extensions for now Signed-off-by: Matt Bruce --- .../Atomic/Atoms/Views/TileletModel.swift | 93 ++----------------- 1 file changed, 6 insertions(+), 87 deletions(-) diff --git a/MVMCoreUI/Atomic/Atoms/Views/TileletModel.swift b/MVMCoreUI/Atomic/Atoms/Views/TileletModel.swift index 64991c50..4cd032f9 100644 --- a/MVMCoreUI/Atomic/Atoms/Views/TileletModel.swift +++ b/MVMCoreUI/Atomic/Atoms/Views/TileletModel.swift @@ -46,9 +46,9 @@ open class TileletModel: MoleculeModelProtocol { public var titleModel: Tilelet.TitleModel? { guard let title else { return nil } - let style = title.fontStyle?.vdsTextStyle - if let style, let found = Tilelet.TitleModel.TextStyle(rawValue: style.rawValue) { - return .init(text: title.text, textStyle: found) + let style: Tilelet.TitleModel.TextStyle? = title.fontStyle?.vdsSubsetStyle() + if let style { + return .init(text: title.text, textStyle: style) } else { return .init(text: title.text) } @@ -56,92 +56,11 @@ open class TileletModel: MoleculeModelProtocol { public var subTitleModel: Tilelet.SubTitleModel? { guard let subTitle else { return nil } - let style = subTitle.fontStyle?.vdsTextStyle - if let style, let found = Tilelet.SubTitleModel.TextStyle(rawValue: style.rawValue) { - return .init(text: subTitle.text, textStyle: found) + let style: Tilelet.SubTitleModel.TextStyle? = subTitle.fontStyle?.vdsSubsetStyle() + if let style { + return .init(text: subTitle.text, textStyle: style) } else { return .init(text: subTitle.text) } } } - -extension Styler.Font { - public var vdsTextStyle: VDS.TextStyle? { - let raw = "\(self)" - let newRaw = raw.prefix(1).lowercased() + raw.dropFirst() - guard let style = VDS.TextStyle(rawValue: newRaw) else { return nil } - return style - } -} - -extension TileContainer.BackgroundColor: Codable {} -extension TileContainer.Padding: Codable {} -extension TileContainer.AspectRatio: Codable {} -extension Surface: Codable {} -extension Badge.FillColor: Codable {} -extension Icon.Name: Codable {} -extension Icon.Size: Codable {} - -extension Tilelet.BadgeModel: Codable { - private enum CodingKeys: String, CodingKey { - case text, fillColor, surface, numberOfLines, maxWidth - } - - public init(from decoder: Decoder) throws { - let container = try decoder.container(keyedBy: CodingKeys.self) - let text = try container.decode(String.self, forKey: .text) - let fillColor = try container.decodeIfPresent(Badge.FillColor.self, forKey: .fillColor) ?? .red - let surface = try container.decodeIfPresent(Surface.self, forKey: .surface) ?? .light - let numberOfLines = try container.decodeIfPresent(Int.self, forKey: .numberOfLines) ?? 0 - let maxWidth = try container.decodeIfPresent(CGFloat.self, forKey: .maxWidth) - self.init(text: text, fillColor: fillColor, surface: surface, numberOfLines: numberOfLines, maxWidth: maxWidth) - } - - public func encode(to encoder: Encoder) throws { - var container = encoder.container(keyedBy: CodingKeys.self) - try container.encode(fillColor, forKey: .fillColor) - try container.encode(surface, forKey: .surface) - try container.encode(numberOfLines, forKey: .numberOfLines) - try container.encodeIfPresent(maxWidth, forKey: .maxWidth) - } -} - -extension Tilelet.DescriptiveIcon: Codable { - private enum CodingKeys: String, CodingKey { - case name, size, surface - } - - public init(from decoder: Decoder) throws { - let container = try decoder.container(keyedBy: CodingKeys.self) - let name = try container.decode(Icon.Name.self, forKey: .name) - let size = try container.decodeIfPresent(Icon.Size.self, forKey: .size) ?? .medium - let surface = try container.decodeIfPresent(Surface.self, forKey: .surface) ?? .dark - self.init(name: name, size: size, surface: surface) - } - - public func encode(to encoder: Encoder) throws { - var container = encoder.container(keyedBy: CodingKeys.self) - try container.encode(name, forKey: .name) - try container.encode(size, forKey: .size) - try container.encode(surface, forKey: .surface) - } -} - -extension Tilelet.DirectionalIcon: Codable { - private enum CodingKeys: String, CodingKey { - case size, surface - } - - public init(from decoder: Decoder) throws { - let container = try decoder.container(keyedBy: CodingKeys.self) - let size = try container.decodeIfPresent(Icon.Size.self, forKey: .size) ?? .medium - let surface = try container.decodeIfPresent(Surface.self, forKey: .surface) ?? .dark - self.init(size: size, surface: surface) - } - - public func encode(to encoder: Encoder) throws { - var container = encoder.container(keyedBy: CodingKeys.self) - try container.encode(size, forKey: .size) - try container.encode(surface, forKey: .surface) - } -} From 0da39e621b9f145380a19a992fbf17969617a7f8 Mon Sep 17 00:00:00 2001 From: Matt Bruce Date: Thu, 26 Jan 2023 15:17:44 -0600 Subject: [PATCH 17/35] updated for tintColor for ImageAttribute Signed-off-by: Matt Bruce --- .../Atomic/Atoms/Views/Label/LabelAttributeImageModel.swift | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/MVMCoreUI/Atomic/Atoms/Views/Label/LabelAttributeImageModel.swift b/MVMCoreUI/Atomic/Atoms/Views/Label/LabelAttributeImageModel.swift index d6ec1b74..03d0ff08 100644 --- a/MVMCoreUI/Atomic/Atoms/Views/Label/LabelAttributeImageModel.swift +++ b/MVMCoreUI/Atomic/Atoms/Views/Label/LabelAttributeImageModel.swift @@ -17,6 +17,7 @@ class LabelAttributeImageModel: LabelAttributeModel { var size: CGFloat? var name: String? var URL: String? + var tintColor: Color? //-------------------------------------------------- // MARK: - Initializer @@ -34,6 +35,7 @@ class LabelAttributeImageModel: LabelAttributeModel { case size case name case URL + case tintColor } //-------------------------------------------------- @@ -55,6 +57,7 @@ class LabelAttributeImageModel: LabelAttributeModel { size = try typeContainer.decodeIfPresent(CGFloat.self, forKey: .size) name = try typeContainer.decodeIfPresent(String.self, forKey: .name) URL = try typeContainer.decodeIfPresent(String.self, forKey: .URL) + tintColor = try typeContainer.decodeIfPresent(Color.self, forKey: .tintColor) try super.init(from: decoder) } @@ -64,5 +67,6 @@ class LabelAttributeImageModel: LabelAttributeModel { try container.encodeIfPresent(size, forKey: .size) try container.encodeIfPresent(name, forKey: .name) try container.encodeIfPresent(URL, forKey: .URL) + try container.encodeIfPresent(tintColor, forKey: .tintColor) } } From 0e957dce2e390a2fabbf12042d748a73ccb63920 Mon Sep 17 00:00:00 2001 From: Matt Bruce Date: Fri, 27 Jan 2023 10:07:35 -0600 Subject: [PATCH 18/35] added temporary model Signed-off-by: Matt Bruce --- MVMCoreUI.xcodeproj/project.pbxproj | 4 + .../Extensions/VDS-LabelAttributeModel.swift | 205 ++++++++++++++++++ 2 files changed, 209 insertions(+) create mode 100644 MVMCoreUI/Atomic/Extensions/VDS-LabelAttributeModel.swift diff --git a/MVMCoreUI.xcodeproj/project.pbxproj b/MVMCoreUI.xcodeproj/project.pbxproj index 5855f95f..104eef80 100644 --- a/MVMCoreUI.xcodeproj/project.pbxproj +++ b/MVMCoreUI.xcodeproj/project.pbxproj @@ -602,6 +602,7 @@ EA985C852981AA9C00F2FF2E /* VDS-Enums+Codable.swift in Sources */ = {isa = PBXBuildFile; fileRef = EA985C842981AA9C00F2FF2E /* VDS-Enums+Codable.swift */; }; EA985C872981AB0F00F2FF2E /* VDS-Tilelet+Codable.swift in Sources */ = {isa = PBXBuildFile; fileRef = EA985C862981AB0F00F2FF2E /* VDS-Tilelet+Codable.swift */; }; EA985C892981AB7100F2FF2E /* VDS-TextStyle.swift in Sources */ = {isa = PBXBuildFile; fileRef = EA985C882981AB7100F2FF2E /* VDS-TextStyle.swift */; }; + EA985C8B2983259900F2FF2E /* VDS-LabelAttributeModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = EA985C8A2983259900F2FF2E /* VDS-LabelAttributeModel.swift */; }; EAA0CFAF275E7D8000D65EB0 /* FormFieldEffectProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = EAA0CFAE275E7D8000D65EB0 /* FormFieldEffectProtocol.swift */; }; EAA0CFB1275E823A00D65EB0 /* HideFormFieldEffectModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = EAA0CFB0275E823A00D65EB0 /* HideFormFieldEffectModel.swift */; }; EAA0CFB3275E831E00D65EB0 /* DisableFormFieldEffectModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = EAA0CFB2275E831E00D65EB0 /* DisableFormFieldEffectModel.swift */; }; @@ -1212,6 +1213,7 @@ EA985C842981AA9C00F2FF2E /* VDS-Enums+Codable.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "VDS-Enums+Codable.swift"; sourceTree = ""; }; EA985C862981AB0F00F2FF2E /* VDS-Tilelet+Codable.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "VDS-Tilelet+Codable.swift"; sourceTree = ""; }; EA985C882981AB7100F2FF2E /* VDS-TextStyle.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "VDS-TextStyle.swift"; sourceTree = ""; }; + EA985C8A2983259900F2FF2E /* VDS-LabelAttributeModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "VDS-LabelAttributeModel.swift"; sourceTree = ""; }; EAA0CFAE275E7D8000D65EB0 /* FormFieldEffectProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FormFieldEffectProtocol.swift; sourceTree = ""; }; EAA0CFB0275E823A00D65EB0 /* HideFormFieldEffectModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HideFormFieldEffectModel.swift; sourceTree = ""; }; EAA0CFB2275E831E00D65EB0 /* DisableFormFieldEffectModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DisableFormFieldEffectModel.swift; sourceTree = ""; }; @@ -1626,6 +1628,7 @@ EA985C842981AA9C00F2FF2E /* VDS-Enums+Codable.swift */, EA985C862981AB0F00F2FF2E /* VDS-Tilelet+Codable.swift */, EA985C882981AB7100F2FF2E /* VDS-TextStyle.swift */, + EA985C8A2983259900F2FF2E /* VDS-LabelAttributeModel.swift */, ); path = Extensions; sourceTree = ""; @@ -2992,6 +2995,7 @@ FD99130028E21E4900542CC3 /* RuleNotEqualsModel.swift in Sources */, BBC0C4FD24811DBC0087C44F /* Tag.swift in Sources */, 94C2D9842386F3F80006CF46 /* LabelAttributeModel.swift in Sources */, + EA985C8B2983259900F2FF2E /* VDS-LabelAttributeModel.swift in Sources */, 944589212385D6E900DE9FD4 /* DashLineModel.swift in Sources */, D2E2A99623D8CF85000B42E6 /* HeadlineBodyLinkToggleModel.swift in Sources */, C6FA7D5323C77A4A00A3614A /* StringAndMoleculeStack.swift in Sources */, diff --git a/MVMCoreUI/Atomic/Extensions/VDS-LabelAttributeModel.swift b/MVMCoreUI/Atomic/Extensions/VDS-LabelAttributeModel.swift new file mode 100644 index 00000000..4eab03b2 --- /dev/null +++ b/MVMCoreUI/Atomic/Extensions/VDS-LabelAttributeModel.swift @@ -0,0 +1,205 @@ +// +// VDS-LabelAttributeModel.swift +// MVMCoreUI +// +// Created by Matt Bruce on 1/26/23. +// Copyright © 2023 Verizon Wireless. All rights reserved. +// + +import Foundation +import VDS +import Combine + +//Meant to be used to convert Any Array of type LabelAttributeModel +extension Array where Element: MVMCoreUI.LabelAttributeModel { + public func toVDSLabelAttributeModel(delegateObject: MVMCoreUIDelegateObject?, additionalData: [AnyHashable: Any]?) -> [any VDS.LabelAttributeModel] { + var attributes: [any VDS.LabelAttributeModel] = [] + forEach { atomicLabelAttribute in + if let attr = atomicLabelAttribute as? (any VDSLabelAttributeConvertable), + let vds = attr.convertToVDSLabelAttirbute(delegateObject: delegateObject, + additionalData: additionalData){ + attributes.append(vds) + } + } + return attributes + } +} + +//VDS Convertable Protocol and Extensions +public protocol VDSLabelAttributeConvertable { + associatedtype LabelAttributeType: VDS.LabelAttributeModel + func convertToVDSLabelAttirbute(delegateObject: MVMCoreUIDelegateObject?, additionalData: [AnyHashable: Any]?) -> LabelAttributeType? +} + +extension LabelAttributeUnderlineModel: VDSLabelAttributeConvertable { + + public func convertToVDSLabelAttirbute(delegateObject: MVMCoreUIDelegateObject?, additionalData: [AnyHashable: Any]?) -> UnderlineLabelAttribute? { + guard let style = UnderlineLabelAttribute.Style(rawValue: style.rawValue) else { return nil } + + var pattern: UnderlineLabelAttribute.Pattern? + if let attrPattern = pattern { + pattern = UnderlineLabelAttribute.Pattern(rawValue: attrPattern.rawValue) + } + + return VDS.UnderlineLabelAttribute(location: location, + length: length, + style: style, + color: color?.uiColor, + pattern: pattern) + } +} + +extension LabelAttributeActionModel: VDSLabelAttributeConvertable { + public func convertToVDSLabelAttirbute(delegateObject: MVMCoreUIDelegateObject?, additionalData: [AnyHashable: Any]?) -> ActionLabelAttribute? { + var vdsAttribute = VDS.ActionLabelAttribute(location: location, length: length) + vdsAttribute.subscriber = vdsAttribute.action.sink { [weak self] in + guard let self else { return } + MVMCoreUIActionHandler.performActionUnstructured(with: self.action, + sourceModel: nil, + additionalData: additionalData, + delegateObject: delegateObject) + } + return vdsAttribute + } +} + +extension LabelAttributeFontModel: VDSLabelAttributeConvertable { + public func convertToVDSLabelAttirbute(delegateObject: MVMCoreUIDelegateObject?, additionalData: [AnyHashable: Any]?) -> TextStyleLabelAttribute? { + + var textStyle: TextStyle? + if let found = style?.vdsTextStyle() { + textStyle = found + } else if let name, let found = TextStyle(rawValue: name) { + textStyle = found + } + + guard let textStyle else { return nil } + + return TextStyleLabelAttribute(location: location, + length: length, + textStyle: textStyle) + } +} + +extension LabelAttributeColorModel: VDSLabelAttributeConvertable { + public func convertToVDSLabelAttirbute(delegateObject: MVMCoreUIDelegateObject?, additionalData: [AnyHashable: Any]?) -> ColorLabelAttribute? { + guard let textColor else { return nil } + return ColorLabelAttribute(location: location, + length: length, + color: textColor.uiColor) + } +} + +extension LabelAttributeStrikeThroughModel: VDSLabelAttributeConvertable { + public func convertToVDSLabelAttirbute(delegateObject: MVMCoreUIDelegateObject?, additionalData: [AnyHashable: Any]?) -> StrikeThroughLabelAttribute? { + return StrikeThroughLabelAttribute(location: location, + length: length) + } +} + +extension LabelAttributeImageModel: VDSLabelAttributeConvertable { + public func convertToVDSLabelAttirbute(delegateObject: MVMCoreUIDelegateObject?, additionalData: [AnyHashable: Any]?) -> AtomicImageLabelAttribute? { + var frame: CGRect? + if let size { + frame = CGRect(x: 0, y: 0, width: size, height: size) + } + return AtomicImageLabelAttribute(location: location, + length: length, + imageName: name, + imageURL: URL, + frame: frame, + tintColor: tintColor?.uiColor) + } +} + +//Custom Atomic Additions for the ImageAttachment +public class AtomicImageLabelAttribute: AttachmentLabelAttributeModel { + //-------------------------------------------------- + // MARK: - Enums + //-------------------------------------------------- + public enum Error: Swift.Error { + case bundleNotFound + case imageNotFound(String) + case imageNotSet + } + + //-------------------------------------------------- + // MARK: - Public Properties + //-------------------------------------------------- + public var id = UUID() + public var location: Int + public var length: Int = 1 + public var imageName: String? + public var imageURL: String? + public var image: UIImage? + public var frame: CGRect? + public var tintColor: UIColor? + + //-------------------------------------------------- + // MARK: - Public Properties + //-------------------------------------------------- + public init(location: Int, length: Int = 1, imageName: String? = nil, imageURL: String? = nil, + image: UIImage? = nil, frame: CGRect? = nil, tintColor: UIColor?) { + self.location = location + self.length = length + self.imageName = imageName + self.imageURL = imageURL + self.image = image + self.frame = frame + self.tintColor = tintColor + fetchImage() + } + + //-------------------------------------------------- + // MARK: - Equatable + //-------------------------------------------------- + public static func == (lhs: AtomicImageLabelAttribute, rhs: AtomicImageLabelAttribute) -> Bool { + lhs.isEqual(rhs) + } + + public func isEqual(_ equatable: AtomicImageLabelAttribute) -> Bool { + return id == equatable.id && range == equatable.range && imageName == equatable.imageName && imageURL == equatable.imageURL + } + + //-------------------------------------------------- + // MARK: - Private Functions + //-------------------------------------------------- + private func fetchImage() { + if image != nil { return } + + //get a local asset + if let imageName { + if let coreImage = MVMCoreCache.shared()?.getImageFromRegisteredBundles(imageName) { + image = coreImage + } + + if let vdsImage = BundleManager.shared.image(for: imageName) { + image = vdsImage + } + }//get from url + else if let imageURL { + DispatchQueue.global(qos: .default).async { + MVMCoreCache.shared()?.getImage(imageURL, useWidth: false, widthForS7: 0, useHeight: false, heightForS7: 0, localFallbackImageName: nil) { [weak self] image, data, _ in + DispatchQueue.main.sync { + self?.image = image + } + } + } + } + } + + //-------------------------------------------------- + // MARK: - Public Functions + //-------------------------------------------------- + public func getAttachment() throws -> NSTextAttachment { + if let image { + let attachment = NSTextAttachment() + attachment.image = tintColor != nil ? image.withTintColor(tintColor!) : image + attachment.bounds = frame ?? .init(x: 0, y: 0, width: image.size.width, height: image.size.height) + return attachment + } else { + throw Error.imageNotSet + } + } +} + From ba13a9a8f4fb64f8c763de96b226420620f720a3 Mon Sep 17 00:00:00 2001 From: Matt Bruce Date: Fri, 27 Jan 2023 10:11:04 -0600 Subject: [PATCH 19/35] updated to convert the Atomic LabelAttribute to VDS LabelAttribute Signed-off-by: Matt Bruce --- MVMCoreUI/Atomic/Atoms/Views/Tilelet.swift | 4 ++-- MVMCoreUI/Atomic/Atoms/Views/TileletModel.swift | 9 +++++---- 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/MVMCoreUI/Atomic/Atoms/Views/Tilelet.swift b/MVMCoreUI/Atomic/Atoms/Views/Tilelet.swift index 101fd1f1..bd50714f 100644 --- a/MVMCoreUI/Atomic/Atoms/Views/Tilelet.swift +++ b/MVMCoreUI/Atomic/Atoms/Views/Tilelet.swift @@ -37,8 +37,8 @@ open class Tilelet: VDS.Tilelet, VDSMoleculeViewProtocol { width = viewModel.width textWidth = viewModel.textWidth textPercentage = viewModel.textPercentage - titleModel = viewModel.titleModel - subTitleModel = viewModel.subTitleModel + titleModel = viewModel.titleModel(delegateObject: delegateObject, additionalData: additionalData) + subTitleModel = viewModel.subTitleModel(delegateObject: delegateObject, additionalData: additionalData) badgeModel = viewModel.badge descriptiveIconModel = viewModel.descriptiveIcon directionalIconModel = viewModel.directionalIcon diff --git a/MVMCoreUI/Atomic/Atoms/Views/TileletModel.swift b/MVMCoreUI/Atomic/Atoms/Views/TileletModel.swift index 4cd032f9..b349eeb5 100644 --- a/MVMCoreUI/Atomic/Atoms/Views/TileletModel.swift +++ b/MVMCoreUI/Atomic/Atoms/Views/TileletModel.swift @@ -44,17 +44,18 @@ open class TileletModel: MoleculeModelProtocol { self.textPercentage = try container.decodeIfPresent(CGFloat.self, forKey: .textPercentage) } - public var titleModel: Tilelet.TitleModel? { + public func titleModel(delegateObject: MVMCoreUIDelegateObject?, additionalData: [AnyHashable: Any]?) -> Tilelet.TitleModel? { guard let title else { return nil } + let attrs = title.attributes?.toVDSLabelAttributeModel(delegateObject: delegateObject, additionalData: additionalData) let style: Tilelet.TitleModel.TextStyle? = title.fontStyle?.vdsSubsetStyle() if let style { - return .init(text: title.text, textStyle: style) + return .init(text: title.text, textAttributes: attrs, textStyle: style) } else { - return .init(text: title.text) + return .init(text: title.text, textAttributes: attrs) } } - public var subTitleModel: Tilelet.SubTitleModel? { + public func subTitleModel(delegateObject: MVMCoreUIDelegateObject?, additionalData: [AnyHashable: Any]?) -> Tilelet.SubTitleModel? { guard let subTitle else { return nil } let style: Tilelet.SubTitleModel.TextStyle? = subTitle.fontStyle?.vdsSubsetStyle() if let style { From 44905b0228a5714fb519f6a0896b02662f9c8f15 Mon Sep 17 00:00:00 2001 From: "Subramaniam, Ramya" Date: Mon, 13 Feb 2023 15:50:45 +0530 Subject: [PATCH 20/35] updating tilelet molecule as actionable --- MVMCoreUI/Atomic/Atoms/Views/Tilelet.swift | 29 +++++++++++++++ .../Atomic/Atoms/Views/TileletModel.swift | 36 +++++++++++++++++++ 2 files changed, 65 insertions(+) diff --git a/MVMCoreUI/Atomic/Atoms/Views/Tilelet.swift b/MVMCoreUI/Atomic/Atoms/Views/Tilelet.swift index bd50714f..75f8fd72 100644 --- a/MVMCoreUI/Atomic/Atoms/Views/Tilelet.swift +++ b/MVMCoreUI/Atomic/Atoms/Views/Tilelet.swift @@ -21,6 +21,8 @@ open class Tilelet: VDS.Tilelet, VDSMoleculeViewProtocol { public var delegateObject: MVMCoreUIDelegateObject? public var additionalData: [AnyHashable: Any]? + public var tapAction: ActionBlock? + //-------------------------------------------------- // MARK: - Initializers //-------------------------------------------------- @@ -30,6 +32,21 @@ open class Tilelet: VDS.Tilelet, VDSMoleculeViewProtocol { open func updateView(_ size: CGFloat) {} + + //-------------------------------------------------- + // MARK: - Actions + //-------------------------------------------------- + + open override func sendAction(_ action: Selector, to target: Any?, for event: UIEvent?) { + super.sendAction(action, to: target, for: event) + tapAction?() + } + + open override func sendActions(for controlEvents: UIControl.Event) { + super.sendActions(for: controlEvents) + tapAction?() + } + public func viewModelDidUpdate() { color = viewModel.color padding = viewModel.padding @@ -42,11 +59,23 @@ open class Tilelet: VDS.Tilelet, VDSMoleculeViewProtocol { badgeModel = viewModel.badge descriptiveIconModel = viewModel.descriptiveIcon directionalIconModel = viewModel.directionalIcon + if let action = viewModel.action { + tapAction = { [weak self] in + guard let self = self else { return } + MVMCoreUIActionHandler.performActionUnstructured(with: action, sourceModel: self.viewModel, additionalData: self.additionalData, delegateObject: self.delegateObject) + } + } } //since this is a class func, we can't reference it directly public static func estimatedHeight(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?) -> CGFloat? { 100 } + //-------------------------------------------------- + // MARK: - Touch Event + //-------------------------------------------------- + public override func touchesEnded(_ touches: Set, with event: UIEvent?) { + sendActions(for: .touchUpInside) + } } diff --git a/MVMCoreUI/Atomic/Atoms/Views/TileletModel.swift b/MVMCoreUI/Atomic/Atoms/Views/TileletModel.swift index b349eeb5..c6685364 100644 --- a/MVMCoreUI/Atomic/Atoms/Views/TileletModel.swift +++ b/MVMCoreUI/Atomic/Atoms/Views/TileletModel.swift @@ -27,7 +27,24 @@ open class TileletModel: MoleculeModelProtocol { public var width: CGFloat? public var textWidth: CGFloat? public var textPercentage: CGFloat? + public var action: ActionModelProtocol? + private enum CodingKeys: String, CodingKey { + case moleculeName + case backgroundColor + case color + case padding + case aspectRatio + case badge + case title + case subTitle + case descriptiveIcon + case directionalIcon + case width + case textWidth + case textPercentage + case action + } required public init(from decoder: Decoder) throws { let container = try decoder.container(keyedBy: CodingKeys.self) self.backgroundColor = try container.decodeIfPresent(Color.self, forKey: .backgroundColor) @@ -42,6 +59,7 @@ open class TileletModel: MoleculeModelProtocol { self.width = try container.decodeIfPresent(CGFloat.self, forKey: .width) self.textWidth = try container.decodeIfPresent(CGFloat.self, forKey: .textWidth) self.textPercentage = try container.decodeIfPresent(CGFloat.self, forKey: .textPercentage) + action = try container.decodeModelIfPresent(codingKey: .action) } public func titleModel(delegateObject: MVMCoreUIDelegateObject?, additionalData: [AnyHashable: Any]?) -> Tilelet.TitleModel? { @@ -64,4 +82,22 @@ open class TileletModel: MoleculeModelProtocol { return .init(text: subTitle.text) } } + + public func encode(to encoder: Encoder) throws { + var container = encoder.container(keyedBy: CodingKeys.self) + try container.encode(moleculeName, forKey: .moleculeName) + try container.encodeIfPresent(backgroundColor, forKey: .backgroundColor) + try container.encodeIfPresent(color, forKey: .color) + try container.encodeIfPresent(padding, forKey: .padding) + try container.encodeIfPresent(aspectRatio, forKey: .aspectRatio) + try container.encodeIfPresent(badge, forKey: .badge) + try container.encodeIfPresent(title, forKey: .title) + try container.encodeIfPresent(subTitle, forKey: .subTitle) + try container.encodeIfPresent(descriptiveIcon, forKey: .descriptiveIcon) + try container.encodeIfPresent(directionalIcon, forKey: .directionalIcon) + try container.encodeIfPresent(width, forKey: .width) + try container.encodeIfPresent(textWidth, forKey: .textWidth) + try container.encodeIfPresent(textPercentage, forKey: .textPercentage) + try container.encodeModelIfPresent(action, forKey: .action) + } } From fdabe5eb860e2c9050671d34c85adaff60868b69 Mon Sep 17 00:00:00 2001 From: Matt Bruce Date: Tue, 14 Feb 2023 08:46:44 -0600 Subject: [PATCH 21/35] updated to use combine Signed-off-by: Matt Bruce --- MVMCoreUI/Atomic/Atoms/Views/Tilelet.swift | 61 ++++++++++++---------- 1 file changed, 34 insertions(+), 27 deletions(-) diff --git a/MVMCoreUI/Atomic/Atoms/Views/Tilelet.swift b/MVMCoreUI/Atomic/Atoms/Views/Tilelet.swift index 75f8fd72..838f3d4f 100644 --- a/MVMCoreUI/Atomic/Atoms/Views/Tilelet.swift +++ b/MVMCoreUI/Atomic/Atoms/Views/Tilelet.swift @@ -13,7 +13,7 @@ import VDS /** This class expects its height and width to be equal. */ -open class Tilelet: VDS.Tilelet, VDSMoleculeViewProtocol { +open class Tilelet: VDS.Tilelet, VDSMoleculeViewProtocol{ //-------------------------------------------------- // MARK: - Properties //-------------------------------------------------- @@ -21,32 +21,33 @@ open class Tilelet: VDS.Tilelet, VDSMoleculeViewProtocol { public var delegateObject: MVMCoreUIDelegateObject? public var additionalData: [AnyHashable: Any]? - public var tapAction: ActionBlock? - //-------------------------------------------------- // MARK: - Initializers //-------------------------------------------------- public convenience required init() { self.init(frame: .zero) } - - open func updateView(_ size: CGFloat) {} - + open override func initialSetup() { + super.initialSetup() + publisher(for: .touchUpInside) + .sink {[weak self] control in + self?.executeAction() + }.store(in: &subscribers) + } + //-------------------------------------------------- - // MARK: - Actions + // MARK: - Private //-------------------------------------------------- - - open override func sendAction(_ action: Selector, to target: Any?, for event: UIEvent?) { - super.sendAction(action, to: target, for: event) - tapAction?() - } - - open override func sendActions(for controlEvents: UIControl.Event) { - super.sendActions(for: controlEvents) - tapAction?() + private func executeAction(){ + if let action = viewModel.action { + MVMCoreUIActionHandler.performActionUnstructured(with: action, sourceModel: viewModel, additionalData: additionalData, delegateObject: delegateObject) + } } + //-------------------------------------------------- + // MARK: - Public + //-------------------------------------------------- public func viewModelDidUpdate() { color = viewModel.color padding = viewModel.padding @@ -59,23 +60,29 @@ open class Tilelet: VDS.Tilelet, VDSMoleculeViewProtocol { badgeModel = viewModel.badge descriptiveIconModel = viewModel.descriptiveIcon directionalIconModel = viewModel.directionalIcon - if let action = viewModel.action { - tapAction = { [weak self] in - guard let self = self else { return } - MVMCoreUIActionHandler.performActionUnstructured(with: action, sourceModel: self.viewModel, additionalData: self.additionalData, delegateObject: self.delegateObject) - } - } } - + + //-------------------------------------------------- + // MARK: - MVMCoreViewProtocol + //-------------------------------------------------- + open func updateView(_ size: CGFloat) {} + + //-------------------------------------------------- + // MARK: - MoleculeViewProtocol + //-------------------------------------------------- //since this is a class func, we can't reference it directly public static func estimatedHeight(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?) -> CGFloat? { 100 } + //-------------------------------------------------- - // MARK: - Touch Event + // MARK: - Overrides //-------------------------------------------------- - - public override func touchesEnded(_ touches: Set, with event: UIEvent?) { - sendActions(for: .touchUpInside) + open override func layoutSubviews() { + super.layoutSubviews() + // Accounts for any collection size changes + DispatchQueue.main.async { + self.delegateObject?.moleculeDelegate?.moleculeLayoutUpdated(self) + } } } From 2bc62fb268ea912e286288ec00827b93907cd748 Mon Sep 17 00:00:00 2001 From: Matt Bruce Date: Tue, 14 Feb 2023 09:17:50 -0600 Subject: [PATCH 22/35] refactored to only add actions when the model has them Signed-off-by: Matt Bruce --- MVMCoreUI/Atomic/Atoms/Views/Tilelet.swift | 40 +++++++++++++--------- 1 file changed, 23 insertions(+), 17 deletions(-) diff --git a/MVMCoreUI/Atomic/Atoms/Views/Tilelet.swift b/MVMCoreUI/Atomic/Atoms/Views/Tilelet.swift index 838f3d4f..72b3a07a 100644 --- a/MVMCoreUI/Atomic/Atoms/Views/Tilelet.swift +++ b/MVMCoreUI/Atomic/Atoms/Views/Tilelet.swift @@ -9,6 +9,7 @@ import Foundation import MVMCore import VDS +import Combine /** This class expects its height and width to be equal. @@ -21,6 +22,11 @@ open class Tilelet: VDS.Tilelet, VDSMoleculeViewProtocol{ public var delegateObject: MVMCoreUIDelegateObject? public var additionalData: [AnyHashable: Any]? + //even though we have a local set, others could be + //subscribing to other events, we use this one specically + //for the action so that we can ensure there is only 1 being used + private var actionSubscriber: AnyCancellable? + //-------------------------------------------------- // MARK: - Initializers //-------------------------------------------------- @@ -28,23 +34,6 @@ open class Tilelet: VDS.Tilelet, VDSMoleculeViewProtocol{ self.init(frame: .zero) } - open override func initialSetup() { - super.initialSetup() - publisher(for: .touchUpInside) - .sink {[weak self] control in - self?.executeAction() - }.store(in: &subscribers) - } - - //-------------------------------------------------- - // MARK: - Private - //-------------------------------------------------- - private func executeAction(){ - if let action = viewModel.action { - MVMCoreUIActionHandler.performActionUnstructured(with: action, sourceModel: viewModel, additionalData: additionalData, delegateObject: delegateObject) - } - } - //-------------------------------------------------- // MARK: - Public //-------------------------------------------------- @@ -60,6 +49,23 @@ open class Tilelet: VDS.Tilelet, VDSMoleculeViewProtocol{ badgeModel = viewModel.badge descriptiveIconModel = viewModel.descriptiveIcon directionalIconModel = viewModel.directionalIcon + + //setup action + if let action = viewModel.action { + //add the subscriber + actionSubscriber = publisher(for: .touchUpInside) + .sink {[weak self] control in + guard let self else { return } + MVMCoreUIActionHandler.performActionUnstructured(with: action, + sourceModel: self.viewModel, + additionalData: self.additionalData, + delegateObject: self.delegateObject) + } + }//if there is no action but there was a subscriber, kill it + else if let actionSubscriber { + actionSubscriber.cancel() + self.actionSubscriber = nil + } } //-------------------------------------------------- From db0afbb15dcae59fcef81cbcc1da9a2b570ba957 Mon Sep 17 00:00:00 2001 From: Matt Bruce Date: Tue, 14 Feb 2023 13:56:09 -0600 Subject: [PATCH 23/35] added weak self Signed-off-by: Matt Bruce --- MVMCoreUI/Atomic/Atoms/Views/Tilelet.swift | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/MVMCoreUI/Atomic/Atoms/Views/Tilelet.swift b/MVMCoreUI/Atomic/Atoms/Views/Tilelet.swift index 72b3a07a..8b7fc312 100644 --- a/MVMCoreUI/Atomic/Atoms/Views/Tilelet.swift +++ b/MVMCoreUI/Atomic/Atoms/Views/Tilelet.swift @@ -49,7 +49,6 @@ open class Tilelet: VDS.Tilelet, VDSMoleculeViewProtocol{ badgeModel = viewModel.badge descriptiveIconModel = viewModel.descriptiveIcon directionalIconModel = viewModel.directionalIcon - //setup action if let action = viewModel.action { //add the subscriber @@ -87,7 +86,8 @@ open class Tilelet: VDS.Tilelet, VDSMoleculeViewProtocol{ open override func layoutSubviews() { super.layoutSubviews() // Accounts for any collection size changes - DispatchQueue.main.async { + DispatchQueue.main.async { [weak self] in + guard let self else { return } self.delegateObject?.moleculeDelegate?.moleculeLayoutUpdated(self) } } From 904cdf3798d8b83c4f0750e43295efe22d1136da Mon Sep 17 00:00:00 2001 From: Sumanth Nadigadda Date: Wed, 22 Feb 2023 20:24:18 +0530 Subject: [PATCH 24/35] Introducing shouldFinishProcessingLoad call to behavior to check if we can continue to load the viewcontroller --- MVMCoreUI/BaseControllers/ViewController.swift | 9 +++++++++ .../Protocols/PageBehaviorHandlerProtocol.swift | 4 ++++ MVMCoreUI/Behaviors/Protocols/PageBehaviorProtocol.swift | 2 ++ 3 files changed, 15 insertions(+) diff --git a/MVMCoreUI/BaseControllers/ViewController.swift b/MVMCoreUI/BaseControllers/ViewController.swift index c6c64f3a..cab9d9ce 100644 --- a/MVMCoreUI/BaseControllers/ViewController.swift +++ b/MVMCoreUI/BaseControllers/ViewController.swift @@ -146,6 +146,15 @@ import MVMCore } } + ///Check with behavior if it can continue + let conditionSatisfied = conditionSatisfyingBehaviours { (behavior: PageMoleculeTransformationBehavior) in + return behavior.shouldFinishProcessingLoad(loadObject) + } + + if conditionSatisfied == false { + return conditionSatisfied + } + return true } diff --git a/MVMCoreUI/Behaviors/Protocols/PageBehaviorHandlerProtocol.swift b/MVMCoreUI/Behaviors/Protocols/PageBehaviorHandlerProtocol.swift index 971a052b..dcd8a2eb 100644 --- a/MVMCoreUI/Behaviors/Protocols/PageBehaviorHandlerProtocol.swift +++ b/MVMCoreUI/Behaviors/Protocols/PageBehaviorHandlerProtocol.swift @@ -44,4 +44,8 @@ public extension PageBehaviorHandlerProtocol { func executeBehaviors(_ behaviorBlock: (_ behavior: T) -> Void) { behaviors?.compactMap { $0 as? T }.forEach { behaviorBlock($0) } } + + func conditionSatisfyingBehaviours(_ behaviourBlock: (_ behavior: T) -> Bool) -> Bool { + return behaviors?.compactMap({$0 as? T}).allSatisfy({ return behaviourBlock($0) }) ?? false + } } diff --git a/MVMCoreUI/Behaviors/Protocols/PageBehaviorProtocol.swift b/MVMCoreUI/Behaviors/Protocols/PageBehaviorProtocol.swift index d5f65323..c8b05055 100644 --- a/MVMCoreUI/Behaviors/Protocols/PageBehaviorProtocol.swift +++ b/MVMCoreUI/Behaviors/Protocols/PageBehaviorProtocol.swift @@ -32,6 +32,7 @@ public protocol PageMoleculeTransformationBehavior: PageBehaviorProtocol { func didSetupMolecule(view: MoleculeViewProtocol, withModel: MoleculeModelProtocol) func willSetupNavigationBar(with model: NavigationItemModelProtocol, updating view: UINavigationBar) func didSetupNavigationBar(view: UINavigationBar, with model: NavigationItemModelProtocol) + func shouldFinishProcessingLoad(_ loadObject: MVMCoreLoadObject) -> Bool } public extension PageMoleculeTransformationBehavior { @@ -41,6 +42,7 @@ public extension PageMoleculeTransformationBehavior { func didSetupMolecule(view: MoleculeViewProtocol, withModel: MoleculeModelProtocol) {} func willSetupNavigationBar(with model: NavigationItemModelProtocol, updating view: UINavigationBar) {} func didSetupNavigationBar(view: UINavigationBar, with model: NavigationItemModelProtocol) {} + func shouldFinishProcessingLoad(_ loadObject: MVMCoreLoadObject) -> Bool { return true } } public protocol PageVisibilityBehavior: PageBehaviorProtocol { From 29c73f2ccc883370b0295b433e8cdbc8339caaa0 Mon Sep 17 00:00:00 2001 From: Sumanth Nadigadda Date: Wed, 22 Feb 2023 23:19:57 +0530 Subject: [PATCH 25/35] Making the shouldFinishProcessingLoad method in behavior to throw --- .../BaseControllers/ViewController.swift | 21 ++++++++++++------- .../PageBehaviorHandlerProtocol.swift | 4 ++-- .../Protocols/PageBehaviorProtocol.swift | 4 ++-- 3 files changed, 17 insertions(+), 12 deletions(-) diff --git a/MVMCoreUI/BaseControllers/ViewController.swift b/MVMCoreUI/BaseControllers/ViewController.swift index cab9d9ce..dddb918e 100644 --- a/MVMCoreUI/BaseControllers/ViewController.swift +++ b/MVMCoreUI/BaseControllers/ViewController.swift @@ -146,15 +146,20 @@ import MVMCore } } - ///Check with behavior if it can continue - let conditionSatisfied = conditionSatisfyingBehaviours { (behavior: PageMoleculeTransformationBehavior) in - return behavior.shouldFinishProcessingLoad(loadObject) + ///Check with behavior if it can continue + do{ + let conditionSatisfied = try executeThrowingBehaviors {(behavior: PageMoleculeTransformationBehavior) in + return try behavior.shouldFinishProcessingLoad(loadObject) + } + if conditionSatisfied == false { + return conditionSatisfied + } + } catch let behaviorError { + if let errorObject = MVMCoreErrorObject.createErrorObject(for: behaviorError, location: MVMCoreLoadHandler.sharedGlobal()?.errorLocation(forRequest: loadObject)) { + error.pointee = errorObject + } } - - if conditionSatisfied == false { - return conditionSatisfied - } - + return true } diff --git a/MVMCoreUI/Behaviors/Protocols/PageBehaviorHandlerProtocol.swift b/MVMCoreUI/Behaviors/Protocols/PageBehaviorHandlerProtocol.swift index dcd8a2eb..b0d49b69 100644 --- a/MVMCoreUI/Behaviors/Protocols/PageBehaviorHandlerProtocol.swift +++ b/MVMCoreUI/Behaviors/Protocols/PageBehaviorHandlerProtocol.swift @@ -45,7 +45,7 @@ public extension PageBehaviorHandlerProtocol { behaviors?.compactMap { $0 as? T }.forEach { behaviorBlock($0) } } - func conditionSatisfyingBehaviours(_ behaviourBlock: (_ behavior: T) -> Bool) -> Bool { - return behaviors?.compactMap({$0 as? T}).allSatisfy({ return behaviourBlock($0) }) ?? false + func executeThrowingBehaviors(_ behaviourBlock: (_ behavior: T) throws -> Bool) throws -> Bool { + return try behaviors?.compactMap({$0 as? T}).allSatisfy({ return try behaviourBlock($0) }) ?? false } } diff --git a/MVMCoreUI/Behaviors/Protocols/PageBehaviorProtocol.swift b/MVMCoreUI/Behaviors/Protocols/PageBehaviorProtocol.swift index c8b05055..543ee60c 100644 --- a/MVMCoreUI/Behaviors/Protocols/PageBehaviorProtocol.swift +++ b/MVMCoreUI/Behaviors/Protocols/PageBehaviorProtocol.swift @@ -32,7 +32,7 @@ public protocol PageMoleculeTransformationBehavior: PageBehaviorProtocol { func didSetupMolecule(view: MoleculeViewProtocol, withModel: MoleculeModelProtocol) func willSetupNavigationBar(with model: NavigationItemModelProtocol, updating view: UINavigationBar) func didSetupNavigationBar(view: UINavigationBar, with model: NavigationItemModelProtocol) - func shouldFinishProcessingLoad(_ loadObject: MVMCoreLoadObject) -> Bool + func shouldFinishProcessingLoad(_ loadObject: MVMCoreLoadObject) throws -> Bool } public extension PageMoleculeTransformationBehavior { @@ -42,7 +42,7 @@ public extension PageMoleculeTransformationBehavior { func didSetupMolecule(view: MoleculeViewProtocol, withModel: MoleculeModelProtocol) {} func willSetupNavigationBar(with model: NavigationItemModelProtocol, updating view: UINavigationBar) {} func didSetupNavigationBar(view: UINavigationBar, with model: NavigationItemModelProtocol) {} - func shouldFinishProcessingLoad(_ loadObject: MVMCoreLoadObject) -> Bool { return true } + func shouldFinishProcessingLoad(_ loadObject: MVMCoreLoadObject) throws -> Bool { return true } } public protocol PageVisibilityBehavior: PageBehaviorProtocol { From d647dc9d18d08e27263946a63ee759ef8bd4ecd3 Mon Sep 17 00:00:00 2001 From: Sumanth Nadigadda Date: Thu, 23 Feb 2023 20:54:35 +0530 Subject: [PATCH 26/35] shouldFinishProcessingLoad Behavior flow - Minor changes --- MVMCoreUI/BaseControllers/ViewController.swift | 6 ++---- .../Behaviors/Protocols/PageBehaviorHandlerProtocol.swift | 2 +- 2 files changed, 3 insertions(+), 5 deletions(-) diff --git a/MVMCoreUI/BaseControllers/ViewController.swift b/MVMCoreUI/BaseControllers/ViewController.swift index dddb918e..fe7eee30 100644 --- a/MVMCoreUI/BaseControllers/ViewController.swift +++ b/MVMCoreUI/BaseControllers/ViewController.swift @@ -148,12 +148,10 @@ import MVMCore ///Check with behavior if it can continue do{ - let conditionSatisfied = try executeThrowingBehaviors {(behavior: PageMoleculeTransformationBehavior) in + let allFinishedProcessingLoad = try executeThrowingBehaviors {(behavior: PageMoleculeTransformationBehavior) in return try behavior.shouldFinishProcessingLoad(loadObject) } - if conditionSatisfied == false { - return conditionSatisfied - } + guard allFinishedProcessingLoad else { return false } } catch let behaviorError { if let errorObject = MVMCoreErrorObject.createErrorObject(for: behaviorError, location: MVMCoreLoadHandler.sharedGlobal()?.errorLocation(forRequest: loadObject)) { error.pointee = errorObject diff --git a/MVMCoreUI/Behaviors/Protocols/PageBehaviorHandlerProtocol.swift b/MVMCoreUI/Behaviors/Protocols/PageBehaviorHandlerProtocol.swift index b0d49b69..9e5c6a6d 100644 --- a/MVMCoreUI/Behaviors/Protocols/PageBehaviorHandlerProtocol.swift +++ b/MVMCoreUI/Behaviors/Protocols/PageBehaviorHandlerProtocol.swift @@ -46,6 +46,6 @@ public extension PageBehaviorHandlerProtocol { } func executeThrowingBehaviors(_ behaviourBlock: (_ behavior: T) throws -> Bool) throws -> Bool { - return try behaviors?.compactMap({$0 as? T}).allSatisfy({ return try behaviourBlock($0) }) ?? false + return try behaviors?.compactMap({$0 as? T}).allSatisfy({ return try behaviourBlock($0) }) ?? true } } From ee7e180684dbc6af7531480712c15b569d02052a Mon Sep 17 00:00:00 2001 From: Kyle Matthew Hedden Date: Sat, 25 Feb 2023 00:23:04 -0500 Subject: [PATCH 27/35] wrapper function to add additoinal request data to error objects. begin working on better silentError handling. --- MVMCoreUI/BaseControllers/ViewController.swift | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/MVMCoreUI/BaseControllers/ViewController.swift b/MVMCoreUI/BaseControllers/ViewController.swift index c6c64f3a..02611511 100644 --- a/MVMCoreUI/BaseControllers/ViewController.swift +++ b/MVMCoreUI/BaseControllers/ViewController.swift @@ -133,7 +133,7 @@ import MVMCore } catch let parsingError { // Log all parsing errors and fail load. handleLoggingFor(parsingError: parsingError) - if let errorObject = MVMCoreErrorObject.createErrorObject(for: parsingError, location: MVMCoreLoadHandler.sharedGlobal()?.errorLocation(forRequest: loadObject)) { + if let errorObject = MVMCoreLoadHandler.sharedGlobal()?.error(for: loadObject, causedBy: parsingError) { errorObject.messageToDisplay = MVMCoreGetterUtility.hardcodedString(withKey: HardcodedErrorUnableToProcess) error.pointee = errorObject } @@ -200,7 +200,8 @@ import MVMCore } guard modulesRequired.count == 0 else { - if let errorObject = MVMCoreErrorObject(title: nil, message: MVMCoreGetterUtility.hardcodedString(withKey: HardcodedErrorCritical), messageToLog: modulesRequired.description, code: ErrorCode.requiredModuleNotPresent.rawValue, domain: ErrorDomainNative, location: MVMCoreLoadHandler.sharedGlobal()?.errorLocation(forRequest: loadObject!)) { + if let loadObject = loadObject, let errorObject = MVMCoreLoadHandler.sharedGlobal()?.error(for: loadObject, withTitle:nil, message: MVMCoreGetterUtility.hardcodedString(withKey: HardcodedErrorCritical), code: ErrorCode.requiredModuleNotPresent.rawValue, domain: ErrorDomainNative) { + errorObject.messageToLog = modulesRequired.description error.pointee = errorObject } return false From 6c0f0993a0d75ab4af7482951f46ac4e8814d9a3 Mon Sep 17 00:00:00 2001 From: Kyle Matthew Hedden Date: Mon, 6 Mar 2023 15:58:33 -0500 Subject: [PATCH 28/35] Crash fix for missing UserMessage. Suppress alertToShow dialogs when a native error screen is present. Pipe template parsing description messages to error object. Provide a messageToLog for invalid openURL calls. --- .../BaseControllers/ViewController.swift | 21 ++++++++++--------- 1 file changed, 11 insertions(+), 10 deletions(-) diff --git a/MVMCoreUI/BaseControllers/ViewController.swift b/MVMCoreUI/BaseControllers/ViewController.swift index 02611511..d9e0065c 100644 --- a/MVMCoreUI/BaseControllers/ViewController.swift +++ b/MVMCoreUI/BaseControllers/ViewController.swift @@ -132,9 +132,9 @@ import MVMCore try parsePageJSON() } catch let parsingError { // Log all parsing errors and fail load. - handleLoggingFor(parsingError: parsingError) if let errorObject = MVMCoreLoadHandler.sharedGlobal()?.error(for: loadObject, causedBy: parsingError) { errorObject.messageToDisplay = MVMCoreGetterUtility.hardcodedString(withKey: HardcodedErrorUnableToProcess) + errorObject.messageToLog = describe(parsingError: parsingError) error.pointee = errorObject } return false @@ -149,37 +149,38 @@ import MVMCore return true } - func handleLoggingFor(parsingError: Error) { + func describe(parsingError: Error) -> String { if let registryError = parsingError as? ModelRegistry.Error { switch (registryError) { case .decoderErrorModelNotMapped(let identifier, let codingKey, let codingPath) where identifier != nil && codingKey != nil && codingPath != nil: - MVMCoreLoggingHandler.shared()?.handleDebugMessage("Error parsing template: Model identifier \"\(identifier!)\" is not mapped for \"\(codingKey!.stringValue)\" @ \(codingPath!.map { return $0.stringValue })") + return "Error parsing template. Model identifier \"\(identifier!)\" is not mapped for \"\(codingKey!.stringValue)\" @ \(codingPath!.map { return $0.stringValue })" case .decoderErrorObjectNotPresent(let codingKey, codingPath: let codingPath): - MVMCoreLoggingHandler.shared()?.handleDebugMessage("Error parsing template: Required model \"\(codingKey.stringValue)\" was not found @ \(codingPath.map { return $0.stringValue })") + return "Error parsing template. Required model \"\(codingKey.stringValue)\" was not found @ \(codingPath.map { return $0.stringValue })" default: - MVMCoreLoggingHandler.shared()?.handleDebugMessage("Error parsing template: Registry error: \(registryError)") + return "Error parsing template. Registry error: \((registryError as NSError).localizedFailureReason ?? registryError.localizedDescription)" } } if let decodingError = parsingError as? DecodingError { switch (decodingError) { case .keyNotFound(let codingKey, let context): - MVMCoreLoggingHandler.shared()?.handleDebugMessage("Error parsing template: Key \(codingKey.stringValue) was not found @ \(context.codingPath.map { return $0.stringValue })") + return "Error parsing template. Key \(codingKey.stringValue) was not found @ \(context.codingPath.map { return $0.stringValue })" case .valueNotFound(_, let context): - MVMCoreLoggingHandler.shared()?.handleDebugMessage("Error parsing template: Value not found @ \(context.codingPath.map { return $0.stringValue })") + return "Error parsing template. Value not found @ \(context.codingPath.map { return $0.stringValue })" case .typeMismatch(_, let context): - MVMCoreLoggingHandler.shared()?.handleDebugMessage("Error parsing template: Type mismatch @ \(context.codingPath.map { return $0.stringValue })") + return "Error parsing template. Type mismatch @ \(context.codingPath.map { return $0.stringValue })" case .dataCorrupted(let context): - MVMCoreLoggingHandler.shared()?.handleDebugMessage("Error parsing template: Data corrupted @ \(context.codingPath.map { return $0.stringValue })") + return "Error parsing template. Data corrupted @ \(context.codingPath.map { return $0.stringValue })" @unknown default: - MVMCoreLoggingHandler.shared()?.handleDebugMessage("Error parsing template: \(parsingError)") + return "Error parsing template. \((parsingError as NSError).localizedFailureReason ?? parsingError.localizedDescription)" } } + return "Error parsing template. \((parsingError as NSError).localizedFailureReason ?? parsingError.localizedDescription)" } open func parsePageJSON() throws { } From 210e7592973a106a517bdbd2d6071ec2f34b9a04 Mon Sep 17 00:00:00 2001 From: Matt Bruce Date: Tue, 7 Mar 2023 11:17:12 -0600 Subject: [PATCH 29/35] updated to use new tilelet onClickSubscriber Signed-off-by: Matt Bruce --- MVMCoreUI/Atomic/Atoms/Views/Tilelet.swift | 13 ++----------- 1 file changed, 2 insertions(+), 11 deletions(-) diff --git a/MVMCoreUI/Atomic/Atoms/Views/Tilelet.swift b/MVMCoreUI/Atomic/Atoms/Views/Tilelet.swift index 8b7fc312..c87e091c 100644 --- a/MVMCoreUI/Atomic/Atoms/Views/Tilelet.swift +++ b/MVMCoreUI/Atomic/Atoms/Views/Tilelet.swift @@ -21,12 +21,7 @@ open class Tilelet: VDS.Tilelet, VDSMoleculeViewProtocol{ public var viewModel: TileletModel! public var delegateObject: MVMCoreUIDelegateObject? public var additionalData: [AnyHashable: Any]? - - //even though we have a local set, others could be - //subscribing to other events, we use this one specically - //for the action so that we can ensure there is only 1 being used - private var actionSubscriber: AnyCancellable? - + //-------------------------------------------------- // MARK: - Initializers //-------------------------------------------------- @@ -52,7 +47,7 @@ open class Tilelet: VDS.Tilelet, VDSMoleculeViewProtocol{ //setup action if let action = viewModel.action { //add the subscriber - actionSubscriber = publisher(for: .touchUpInside) + onClickSubscriber = publisher(for: .touchUpInside) .sink {[weak self] control in guard let self else { return } MVMCoreUIActionHandler.performActionUnstructured(with: action, @@ -60,10 +55,6 @@ open class Tilelet: VDS.Tilelet, VDSMoleculeViewProtocol{ additionalData: self.additionalData, delegateObject: self.delegateObject) } - }//if there is no action but there was a subscriber, kill it - else if let actionSubscriber { - actionSubscriber.cancel() - self.actionSubscriber = nil } } From 289a31af241d521b3d1517296fac3b8b23e70686 Mon Sep 17 00:00:00 2001 From: Kyle Matthew Hedden Date: Mon, 13 Mar 2023 19:45:58 -0400 Subject: [PATCH 30/35] Prevent double logging and double error popup. --- MVMCoreUI/BaseControllers/ViewController.swift | 3 ++- MVMCoreUI/OtherHandlers/MVMCoreUIActionHandler.swift | 1 + 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/MVMCoreUI/BaseControllers/ViewController.swift b/MVMCoreUI/BaseControllers/ViewController.swift index d9e0065c..339868fe 100644 --- a/MVMCoreUI/BaseControllers/ViewController.swift +++ b/MVMCoreUI/BaseControllers/ViewController.swift @@ -155,7 +155,7 @@ import MVMCore case .decoderErrorModelNotMapped(let identifier, let codingKey, let codingPath) where identifier != nil && codingKey != nil && codingPath != nil: return "Error parsing template. Model identifier \"\(identifier!)\" is not mapped for \"\(codingKey!.stringValue)\" @ \(codingPath!.map { return $0.stringValue })" - case .decoderErrorObjectNotPresent(let codingKey, codingPath: let codingPath): + case .decoderErrorObjectNotPresent(let codingKey, let codingPath): return "Error parsing template. Required model \"\(codingKey.stringValue)\" was not found @ \(codingPath.map { return $0.stringValue })" default: @@ -475,6 +475,7 @@ import MVMCore open func handleAction(error: Error, model: ActionModelProtocol, additionalData: [AnyHashable : Any]?, delegateObject: DelegateObject?) { let errorObject = MVMCoreErrorObject.createErrorObject(for: error, location: MVMCoreActionHandler.getErrorLocation(with: delegateObject?.actionDelegate, actionType: model.actionType))! + errorObject.silentError = (error as? MVMCoreErrorObject)?.silentError ?? false // Prefer incoming settings, then default to loud. MVMCoreUIActionHandler.shared()?.defaultHandleActionError(errorObject, additionalData: additionalData) } diff --git a/MVMCoreUI/OtherHandlers/MVMCoreUIActionHandler.swift b/MVMCoreUI/OtherHandlers/MVMCoreUIActionHandler.swift index 24d57f8d..3de8fdde 100644 --- a/MVMCoreUI/OtherHandlers/MVMCoreUIActionHandler.swift +++ b/MVMCoreUI/OtherHandlers/MVMCoreUIActionHandler.swift @@ -41,6 +41,7 @@ import SafariServices open override func defaultHandleActionError(_ error: MVMCoreErrorObject, additionalData: [AnyHashable : Any]?) { super.defaultHandleActionError(error, additionalData: additionalData) guard !error.silentError else { return } + error.silentError = true // Silence if this error is triggered again. (Legacy action handler flow.) Task(priority: .userInitiated) { @MainActor in let alertObject = MVMCoreAlertObject.init(popupAlertWithError: error, isGreedy: false)! MVMCoreAlertHandler.shared()?.showAlert(with: alertObject) From 04e85db91e05d67fc9d43c215f25ca0ec06ebe5d Mon Sep 17 00:00:00 2001 From: Kyle Matthew Hedden Date: Wed, 15 Mar 2023 09:04:58 -0400 Subject: [PATCH 31/35] code review --- MVMCoreUI/BaseControllers/ViewController.swift | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/MVMCoreUI/BaseControllers/ViewController.swift b/MVMCoreUI/BaseControllers/ViewController.swift index 339868fe..18f1e67c 100644 --- a/MVMCoreUI/BaseControllers/ViewController.swift +++ b/MVMCoreUI/BaseControllers/ViewController.swift @@ -165,13 +165,13 @@ import MVMCore if let decodingError = parsingError as? DecodingError { switch (decodingError) { case .keyNotFound(let codingKey, let context): - return "Error parsing template. Key \(codingKey.stringValue) was not found @ \(context.codingPath.map { return $0.stringValue })" + return "Error parsing template. Required key \(codingKey.stringValue) was not found @ \(context.codingPath.map { return $0.stringValue })" case .valueNotFound(_, let context): return "Error parsing template. Value not found @ \(context.codingPath.map { return $0.stringValue })" case .typeMismatch(_, let context): - return "Error parsing template. Type mismatch @ \(context.codingPath.map { return $0.stringValue })" + return "Error parsing template. Value type mismatch @ \(context.codingPath.map { return $0.stringValue })" case .dataCorrupted(let context): return "Error parsing template. Data corrupted @ \(context.codingPath.map { return $0.stringValue })" @@ -475,7 +475,14 @@ import MVMCore open func handleAction(error: Error, model: ActionModelProtocol, additionalData: [AnyHashable : Any]?, delegateObject: DelegateObject?) { let errorObject = MVMCoreErrorObject.createErrorObject(for: error, location: MVMCoreActionHandler.getErrorLocation(with: delegateObject?.actionDelegate, actionType: model.actionType))! - errorObject.silentError = (error as? MVMCoreErrorObject)?.silentError ?? false // Prefer incoming settings, then default to loud. + + switch (model) { + case let model as ActionOpenPageModel: + errorObject.silentError = model.background ?? false + default: + errorObject.silentError = false + } + MVMCoreUIActionHandler.shared()?.defaultHandleActionError(errorObject, additionalData: additionalData) } From 2ecfa6e9249217999dfc15e1ff56485a435d1cad Mon Sep 17 00:00:00 2001 From: Sumanth Nadigadda Date: Tue, 21 Mar 2023 22:28:02 +0530 Subject: [PATCH 32/35] Return false in shouldFinishProcessing flow in case behavior has thrown any error --- MVMCoreUI/BaseControllers/ViewController.swift | 1 + 1 file changed, 1 insertion(+) diff --git a/MVMCoreUI/BaseControllers/ViewController.swift b/MVMCoreUI/BaseControllers/ViewController.swift index fe7eee30..fc176da5 100644 --- a/MVMCoreUI/BaseControllers/ViewController.swift +++ b/MVMCoreUI/BaseControllers/ViewController.swift @@ -156,6 +156,7 @@ import MVMCore if let errorObject = MVMCoreErrorObject.createErrorObject(for: behaviorError, location: MVMCoreLoadHandler.sharedGlobal()?.errorLocation(forRequest: loadObject)) { error.pointee = errorObject } + return false } return true From bd4639afa5e555a118ea3b0f2c3a668be0058884 Mon Sep 17 00:00:00 2001 From: Keerthy Date: Thu, 23 Mar 2023 23:57:46 +0530 Subject: [PATCH 33/35] added missing children --- .../LeftVariable/ListLeftVariableCheckboxBodyTextModel.swift | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/MVMCoreUI/Atomic/Molecules/DesignedComponents/List/LeftVariable/ListLeftVariableCheckboxBodyTextModel.swift b/MVMCoreUI/Atomic/Molecules/DesignedComponents/List/LeftVariable/ListLeftVariableCheckboxBodyTextModel.swift index 16d75035..a459d46c 100644 --- a/MVMCoreUI/Atomic/Molecules/DesignedComponents/List/LeftVariable/ListLeftVariableCheckboxBodyTextModel.swift +++ b/MVMCoreUI/Atomic/Molecules/DesignedComponents/List/LeftVariable/ListLeftVariableCheckboxBodyTextModel.swift @@ -16,6 +16,10 @@ open class ListLeftVariableCheckboxBodyTextModel: ListItemModel, MoleculeModelPr public var checkbox: CheckboxModel public var headlineBody: HeadlineBodyModel + public var children: [MoleculeModelProtocol] { + [checkbox, headlineBody] + } + //-------------------------------------------------- // MARK: - Initializer //-------------------------------------------------- From fcd2b2041eb42da27e0bc248a0bbf9b7b146215b Mon Sep 17 00:00:00 2001 From: Krishna Kishore Bandaru Date: Fri, 24 Mar 2023 11:57:57 +0530 Subject: [PATCH 34/35] added ParentMoleculeModelProtocol --- .../LeftVariable/ListLeftVariableCheckboxBodyTextModel.swift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/MVMCoreUI/Atomic/Molecules/DesignedComponents/List/LeftVariable/ListLeftVariableCheckboxBodyTextModel.swift b/MVMCoreUI/Atomic/Molecules/DesignedComponents/List/LeftVariable/ListLeftVariableCheckboxBodyTextModel.swift index a459d46c..3ed92e02 100644 --- a/MVMCoreUI/Atomic/Molecules/DesignedComponents/List/LeftVariable/ListLeftVariableCheckboxBodyTextModel.swift +++ b/MVMCoreUI/Atomic/Molecules/DesignedComponents/List/LeftVariable/ListLeftVariableCheckboxBodyTextModel.swift @@ -7,7 +7,7 @@ // -open class ListLeftVariableCheckboxBodyTextModel: ListItemModel, MoleculeModelProtocol { +open class ListLeftVariableCheckboxBodyTextModel: ListItemModel, MoleculeModelProtocol, ParentMoleculeModelProtocol { //-------------------------------------------------- // MARK: - Properties //-------------------------------------------------- From 2b957cc4af4d81167e0db1165746659961c22fc7 Mon Sep 17 00:00:00 2001 From: Krishna Kishore Bandaru Date: Tue, 28 Mar 2023 18:50:45 +0530 Subject: [PATCH 35/35] updated access specifier to public --- MVMCoreUI/Atomic/Atoms/Selectors/Checkbox.swift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/MVMCoreUI/Atomic/Atoms/Selectors/Checkbox.swift b/MVMCoreUI/Atomic/Atoms/Selectors/Checkbox.swift index 9efc554a..f771dddf 100644 --- a/MVMCoreUI/Atomic/Atoms/Selectors/Checkbox.swift +++ b/MVMCoreUI/Atomic/Atoms/Selectors/Checkbox.swift @@ -314,7 +314,7 @@ import MVMCore } /// Adjust accessibility label based on state of Checkbox. - func updateAccessibilityLabel() { + public func updateAccessibilityLabel() { // Attention: This needs to be addressed with the accessibility team. // NOTE: Currently emptying description part of MVMCoreUICheckBox accessibility label to avoid crashing! if let state = MVMCoreUIUtility.hardcodedString(withKey: isSelected ? "checkbox_checked_state" : "checkbox_unchecked_state") {