Merge branch 'feature/star' into 'develop'

Feature/star

See merge request BPHV_MIPS/mvm_core_ui!602
This commit is contained in:
Pfeil, Scott Robert 2020-10-22 09:14:33 -04:00
commit 2526464413
9 changed files with 425 additions and 0 deletions

View File

@ -199,6 +199,8 @@
94CA227D24058534002D6750 /* VerizonNHGeDS-Regular.otf in Resources */ = {isa = PBXBuildFile; fileRef = 94CA227924058533002D6750 /* VerizonNHGeDS-Regular.otf */; };
94CA227E24058534002D6750 /* VerizonNHGeDS-Bold.otf in Resources */ = {isa = PBXBuildFile; fileRef = 94CA227A24058533002D6750 /* VerizonNHGeDS-Bold.otf */; };
94F6516D2437954100631BF9 /* Tabs.swift in Sources */ = {isa = PBXBuildFile; fileRef = 94F6516C2437954100631BF9 /* Tabs.swift */; };
AA07EA912510A442009A2AE3 /* StarModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = AA07EA902510A442009A2AE3 /* StarModel.swift */; };
AA07EA932510A451009A2AE3 /* Star.swift in Sources */ = {isa = PBXBuildFile; fileRef = AA07EA922510A451009A2AE3 /* Star.swift */; };
AA0A257824766C8A00862F64 /* ListLeftVariableIconWithRightCaretBodyTextModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = AA0A257724766C8A00862F64 /* ListLeftVariableIconWithRightCaretBodyTextModel.swift */; };
AA0A257A24766CA200862F64 /* ListLeftVariableIconWithRightCaretBodyText.swift in Sources */ = {isa = PBXBuildFile; fileRef = AA0A257924766CA200862F64 /* ListLeftVariableIconWithRightCaretBodyText.swift */; };
AA104AC724472DB0004D2810 /* HeadersH1Button.swift in Sources */ = {isa = PBXBuildFile; fileRef = AA104AC624472DB0004D2810 /* HeadersH1Button.swift */; };
@ -217,6 +219,8 @@
AA2AD118244EE48C00BBFFE3 /* ListDeviceComplexLinkMediumModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = AA2AD117244EE48C00BBFFE3 /* ListDeviceComplexLinkMediumModel.swift */; };
AA3561AC24C9684400452EB1 /* ListRightVariableRightCaretAllTextAndLinksModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = AA3561AB24C9684400452EB1 /* ListRightVariableRightCaretAllTextAndLinksModel.swift */; };
AA3561AE24C96B9000452EB1 /* ListRightVariableRightCaretAllTextAndLinks.swift in Sources */ = {isa = PBXBuildFile; fileRef = AA3561AD24C96B9000452EB1 /* ListRightVariableRightCaretAllTextAndLinks.swift */; };
AA37CBD3251907200027344C /* StarsModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = AA37CBD2251907200027344C /* StarsModel.swift */; };
AA37CBD52519072F0027344C /* Stars.swift in Sources */ = {isa = PBXBuildFile; fileRef = AA37CBD42519072F0027344C /* Stars.swift */; };
AA45AA0B24BF0263007A6EA7 /* LockUpsPlanNamesModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = AA45AA0A24BF0263007A6EA7 /* LockUpsPlanNamesModel.swift */; };
AA45AA0D24BF0276007A6EA7 /* LockUpsPlanNames.swift in Sources */ = {isa = PBXBuildFile; fileRef = AA45AA0C24BF0276007A6EA7 /* LockUpsPlanNames.swift */; };
AA56A20F243C5EE900303286 /* ListTwoColumnSubsectionDividerModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = AA56A20E243C5EE900303286 /* ListTwoColumnSubsectionDividerModel.swift */; };
@ -705,6 +709,8 @@
94CA227A24058533002D6750 /* VerizonNHGeDS-Bold.otf */ = {isa = PBXFileReference; lastKnownFileType = file; path = "VerizonNHGeDS-Bold.otf"; sourceTree = "<group>"; };
94CA227B24058533002D6750 /* VerizonNHGeTX-Regular.otf */ = {isa = PBXFileReference; lastKnownFileType = file; path = "VerizonNHGeTX-Regular.otf"; sourceTree = "<group>"; };
94F6516C2437954100631BF9 /* Tabs.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Tabs.swift; sourceTree = "<group>"; };
AA07EA902510A442009A2AE3 /* StarModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = StarModel.swift; sourceTree = "<group>"; };
AA07EA922510A451009A2AE3 /* Star.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Star.swift; sourceTree = "<group>"; };
AA0A257724766C8A00862F64 /* ListLeftVariableIconWithRightCaretBodyTextModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ListLeftVariableIconWithRightCaretBodyTextModel.swift; sourceTree = "<group>"; };
AA0A257924766CA200862F64 /* ListLeftVariableIconWithRightCaretBodyText.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ListLeftVariableIconWithRightCaretBodyText.swift; sourceTree = "<group>"; };
AA104AC624472DB0004D2810 /* HeadersH1Button.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HeadersH1Button.swift; sourceTree = "<group>"; };
@ -723,6 +729,8 @@
AA2AD117244EE48C00BBFFE3 /* ListDeviceComplexLinkMediumModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ListDeviceComplexLinkMediumModel.swift; sourceTree = "<group>"; };
AA3561AB24C9684400452EB1 /* ListRightVariableRightCaretAllTextAndLinksModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ListRightVariableRightCaretAllTextAndLinksModel.swift; sourceTree = "<group>"; };
AA3561AD24C96B9000452EB1 /* ListRightVariableRightCaretAllTextAndLinks.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ListRightVariableRightCaretAllTextAndLinks.swift; sourceTree = "<group>"; };
AA37CBD2251907200027344C /* StarsModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = StarsModel.swift; sourceTree = "<group>"; };
AA37CBD42519072F0027344C /* Stars.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Stars.swift; sourceTree = "<group>"; };
AA45AA0A24BF0263007A6EA7 /* LockUpsPlanNamesModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LockUpsPlanNamesModel.swift; sourceTree = "<group>"; };
AA45AA0C24BF0276007A6EA7 /* LockUpsPlanNames.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LockUpsPlanNames.swift; sourceTree = "<group>"; };
AA56A20E243C5EE900303286 /* ListTwoColumnSubsectionDividerModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ListTwoColumnSubsectionDividerModel.swift; sourceTree = "<group>"; };
@ -1913,6 +1921,10 @@
D20492A524329CE200A5EED6 /* LoadImageView.swift */,
0A51F3E02475CB73002E08B6 /* LoadingSpinnerModel.swift */,
0A51F3E12475CB73002E08B6 /* LoadingSpinner.swift */,
AA37CBD2251907200027344C /* StarsModel.swift */,
AA37CBD42519072F0027344C /* Stars.swift */,
AA07EA902510A442009A2AE3 /* StarModel.swift */,
AA07EA922510A451009A2AE3 /* Star.swift */,
);
path = Views;
sourceTree = "<group>";
@ -2372,6 +2384,7 @@
AA1EC59724373985003D6F50 /* ListThreeColumnSpeedTestDividerModel.swift in Sources */,
BB1D17E0244EAA30001D2002 /* ListDeviceComplexButtonMediumModel.swift in Sources */,
D2CAC7D3251105A700C75681 /* MVMCoreUITopAlertExpandableView+Extension.swift in Sources */,
AA07EA932510A451009A2AE3 /* Star.swift in Sources */,
D29DF2CF21E7C104003B2FB9 /* MFLoadingViewController.m in Sources */,
D28A837B23C928DA00DFE4FC /* MoleculeListCellProtocol.swift in Sources */,
D28BA74D248589C800B75CB8 /* TabPageModelProtocol.swift in Sources */,
@ -2397,6 +2410,7 @@
D2E2A99A23D8D6B4000B42E6 /* HeadlineBodyButtonModel.swift in Sources */,
D202AFE6242A6A9C00E5BEDF /* UICollectionViewScrollPosition+Extension.swift in Sources */,
D20F3B44252E00E4004B3F56 /* PageProtocol.swift in Sources */,
AA37CBD3251907200027344C /* StarsModel.swift in Sources */,
8D084AD22410BF7600951227 /* ListOneColumnFullWidthTextBodyText.swift in Sources */,
94C0150C2421564A005811A9 /* ActionCollapseNotificationModel.swift in Sources */,
D2CAC7CB251104E100C75681 /* NotificationXButtonModel.swift in Sources */,
@ -2496,6 +2510,7 @@
01EB368F23609801006832FA /* LabelModel.swift in Sources */,
0A6682AC243531C300AD3CA1 /* Padding.swift in Sources */,
AA1EC59924373994003D6F50 /* ListThreeColumnSpeedTestDivider.swift in Sources */,
AA37CBD52519072F0027344C /* Stars.swift in Sources */,
942C378E2412F5B60066E45E /* ModalMoleculeStackTemplate.swift in Sources */,
8D8067D32444473A00203BE8 /* ListRightVariablePriceChangeAllTextAndLinks.swift in Sources */,
8D4687E4242E2DF300802879 /* ListFourColumnDataUsageListItem.swift in Sources */,
@ -2645,6 +2660,7 @@
BB2BF0EC2452A9D5001D0FC2 /* ListDeviceComplexButtonSmallModel.swift in Sources */,
943784F6236B77BB006A1E82 /* WheelAnimationHandler.swift in Sources */,
011D95A1240453D0000E3791 /* RuleEqualsModel.swift in Sources */,
AA07EA912510A442009A2AE3 /* StarModel.swift in Sources */,
D29DF2AA21E7B2F9003B2FB9 /* MVMCoreUIConstants.m in Sources */,
011D95892404249B000E3791 /* FormHolderModelProtocol.swift in Sources */,
BB54C5202434D92F0038326C /* ListRightVariableButtonAllTextAndLinks.swift in Sources */,

View File

@ -0,0 +1,160 @@
//
// Star.swift
// MVMCoreUI
//
// Created by Lekshmi S on 15/09/20.
// Copyright © 2020 Verizon Wireless. All rights reserved.
//
@objcMembers open class Star: View {
//--------------------------------------------------
// MARK: - Properties
//--------------------------------------------------
private var starLayer: CAShapeLayer?
private var progressLayer: CAShapeLayer?
private let maskLayer = CAShapeLayer()
public var starModel: StarModel? {
return model as? StarModel
}
@Percent public var percent = 0 {
didSet {
updateAccessibilityLabel()
setNeedsDisplay()
}
}
public var size: CGFloat = 30 {
didSet {
widthConstraint?.constant = size
setNeedsDisplay()
}
}
public var fillColor = UIColor.mvmBlack {
didSet {
setNeedsDisplay()
}
}
public var borderColor: CGColor = UIColor.mvmBlack.cgColor {
didSet {
setNeedsDisplay()
}
}
//--------------------------------------------------
// MARK: - Constraints
//--------------------------------------------------
public var widthConstraint: NSLayoutConstraint?
public var heightConstraint: NSLayoutConstraint?
//------------------------------------------------------
// MARK: - State Handling
//------------------------------------------------------
open override func draw(_ rect: CGRect) {
//Draw progress
progressLayer?.removeFromSuperlayer()
let progress = drawProgress()
layer.addSublayer(progress)
progressLayer = progress
//Draw the star
starLayer?.removeFromSuperlayer()
let star = drawStar()
layer.addSublayer(star)
starLayer = star
//Mask the star
maskLayer.removeFromSuperlayer()
maskLayer.path = star.path
layer.mask = maskLayer
}
func drawProgress() -> CAShapeLayer {
let shapeLayer = CAShapeLayer()
let width = bounds.size.width * percent / 100.0
shapeLayer.path = UIBezierPath(rect: CGRect(x: 0, y: 0, width: width, height: bounds.height)).cgPath
shapeLayer.fillColor = fillColor.cgColor
return shapeLayer
}
func drawStar() -> CAShapeLayer {
let shapeLayer = CAShapeLayer()
shapeLayer.frame = bounds
let starPath = UIBezierPath()
let center = shapeLayer.position
let theta = .pi / CGFloat(5.0)
let outerRadius = center.x * 1.039
let excessRadius = outerRadius - center.x
let innerRadius = CGFloat(outerRadius * 0.382)
let leftEdgePointX = (center.x + cos(4.0 * theta) * outerRadius) + excessRadius
let horizontalOffset = leftEdgePointX / 2.0
let offsetCenter = CGPoint(x: center.x - horizontalOffset, y: center.y)
for i in 0 ..< 10 {
let radius = i % 2 == 0 ? outerRadius : innerRadius
let pointX = offsetCenter.x + cos(CGFloat(i) * theta) * radius
let pointY = offsetCenter.y + sin(CGFloat(i) * theta) * radius
let point = CGPoint(x: pointX, y: pointY)
if i == 0 {
starPath.move(to: point)
} else {
starPath.addLine(to: point)
}
}
starPath.close()
// Rotate the path so the star points up as expected
var pathTransform = CGAffineTransform.identity
pathTransform = pathTransform.translatedBy(x: center.x, y: center.y)
pathTransform = pathTransform.rotated(by: CGFloat(-.pi / 2.0))
pathTransform = pathTransform.translatedBy(x: -center.x, y: -center.y)
starPath.apply(pathTransform)
shapeLayer.path = starPath.cgPath
shapeLayer.fillColor = UIColor.clear.cgColor
shapeLayer.opacity = 1.0
shapeLayer.lineWidth = 1
shapeLayer.strokeColor = borderColor
return shapeLayer
}
//--------------------------------------------------
// MARK: - MoleculeViewProtocol
//--------------------------------------------------
open override func reset() {
super.reset()
borderColor = UIColor.mvmBlack.cgColor
fillColor = .mvmBlack
percent = 0
}
public override func set(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable: Any]?) {
super.set(with: model, delegateObject, additionalData)
guard let model = model as? StarModel else { return }
percent = model.percent
if let fillColor = model.fillColor?.uiColor {
self.fillColor = fillColor
}
if let borderColor = model.borderColor?.cgColor {
self.borderColor = borderColor
}
size = model.size
updateAccessibilityLabel()
}
//--------------------------------------------------
// MARK: - MVMCoreViewProtocol
//--------------------------------------------------
open override func setupView() {
super.setupView()
backgroundColor = .clear
widthConstraint = widthAnchor.constraint(equalToConstant: 30)
widthConstraint?.isActive = true
heightConstraint = heightAnchor.constraint(equalTo: widthAnchor, multiplier: 1)
heightConstraint?.isActive = true
isAccessibilityElement = true
updateAccessibilityLabel()
}
// MARK: - Accessibility
func updateAccessibilityLabel() {
accessibilityLabel = MVMCoreUIUtility.hardcodedString(withKey: "star")
accessibilityValue = String(format: MVMCoreUIUtility.hardcodedString(withKey: "star_percent") ?? "", Int(percent))
}
}

View File

@ -0,0 +1,59 @@
//
// StarModel.swift
// MVMCoreUI
//
// Created by Lekshmi S on 15/09/20.
// Copyright © 2020 Verizon Wireless. All rights reserved.
//
open class StarModel: MoleculeModelProtocol {
//--------------------------------------------------
// MARK: - Properties
//--------------------------------------------------
public static var identifier: String = "star"
public var backgroundColor: Color?
@Percent public var percent: CGFloat = 0
public var borderColor: Color?
public var fillColor: Color?
public var size: CGFloat = 30.0
//--------------------------------------------------
// MARK: - Keys
//--------------------------------------------------
private enum CodingKeys: String, CodingKey {
case moleculeName
case backgroundColor
case percent
case borderColor
case fillColor
case size
}
//--------------------------------------------------
// MARK: - Codec
//--------------------------------------------------
required public init(from decoder: Decoder) throws {
let typeContainer = try decoder.container(keyedBy: CodingKeys.self)
if let percent = try typeContainer.decodeIfPresent(CGFloat.self, forKey: .percent) {
self.percent = percent
}
backgroundColor = try typeContainer.decodeIfPresent(Color.self, forKey: .backgroundColor)
borderColor = try typeContainer.decodeIfPresent(Color.self, forKey: .borderColor)
fillColor = try typeContainer.decodeIfPresent(Color.self, forKey: .fillColor)
if let size = try typeContainer.decodeIfPresent(CGFloat.self, forKey: .size) {
self.size = size
}
}
public func encode(to encoder: Encoder) throws {
var container = encoder.container(keyedBy: CodingKeys.self)
try container.encodeIfPresent(backgroundColor, forKey: .backgroundColor)
try container.encode(moleculeName, forKey: .moleculeName)
try container.encode(percent, forKey: .percent)
try container.encodeIfPresent(borderColor, forKey: .borderColor)
try container.encodeIfPresent(fillColor, forKey: .fillColor)
try container.encode(size, forKey: .size)
}
}

View File

@ -0,0 +1,108 @@
//
// Stars.swift
// MVMCoreUI
//
// Created by Lekshmi S on 21/09/20.
// Copyright © 2020 Verizon Wireless. All rights reserved.
//
open class Stars: View {
//--------------------------------------------------
// MARK: - Properties
//--------------------------------------------------
private var stack = UIStackView()
public var starsModel: StarsModel? {
return model as? StarsModel
}
private var delegateObject: MVMCoreUIDelegateObject?
private let itemSpacing: CGFloat = 3.0
private var heightConstraint: NSLayoutConstraint?
private var starsFilledValue: Float = 0
//--------------------------------------------------
// MARK: - MVMCoreViewProtocol
//--------------------------------------------------
open override func setupView() {
super.setupView()
stack.translatesAutoresizingMaskIntoConstraints = false
stack.axis = .horizontal
stack.spacing = itemSpacing
addSubview(stack)
NSLayoutConstraint.constraintPinSubview(toSuperview: stack)
heightConstraint = heightAnchor.constraint(equalToConstant: 30)
heightConstraint?.isActive = true
isAccessibilityElement = true
updateAccessibilityLabel()
}
@objc override open func updateView(_ size: CGFloat) {
super.updateView(size)
stack.updateView(size)
}
//--------------------------------------------------
// MARK: - MoleculeViewProtocol
//--------------------------------------------------
open override func set(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable: Any]?) {
super.set(with: model, delegateObject, additionalData)
self.delegateObject = delegateObject
createStars()
updateStars()
updateAccessibilityLabel()
}
public override func reset() {
stack.subviews.forEach({$0.removeFromSuperview()})
super.reset()
}
//------------------------------------------------------
// MARK: - Methods
//------------------------------------------------------
func createStars() {
guard let starsModel = starsModel else { return }
for starModel in starsModel.stars {
let star = Star(model: starModel, delegateObject, nil)
star.isAccessibilityElement = false
stack.addArrangedSubview(star)
}
heightConstraint?.constant = starsModel.size
}
func updateStars() {
guard let starsModel = starsModel else { return }
let percentRequiredToFillStarFully = CGFloat(100/(stack.arrangedSubviews.count))
let numberOfFilledStars = Int(starsModel.percent/percentRequiredToFillStarFully)
starsFilledValue = Float(numberOfFilledStars)
for case let (index, star as Star) in stack.arrangedSubviews.enumerated() {
//Star model colors should take priority over stars.
if let borderColor = starsModel.borderColor?.cgColor, star.starModel?.borderColor == nil {
star.borderColor = borderColor
}
if let fillColor = starsModel.fillColor?.uiColor, star.starModel?.fillColor == nil {
star.fillColor = fillColor
}
if let backgroundColor = starsModel.starBackgroundColor?.uiColor, star.starModel?.backgroundColor == nil {
star.backgroundColor = backgroundColor
}
//Fill the stars based on percentage. Ex: if there were 4 stars, 75 percent is 3 full stars
if index < numberOfFilledStars {
star.percent = 100
} else if index == numberOfFilledStars {
let remainingProgress = (starsModel.percent).truncatingRemainder(dividingBy: percentRequiredToFillStarFully)
let fillPercent = remainingProgress/percentRequiredToFillStarFully
starsFilledValue += Float(fillPercent)
star.percent = fillPercent * 100
} else {
star.percent = 0
}
star.size = starsModel.size
}
}
// MARK: - Accessibility
func updateAccessibilityLabel() {
accessibilityLabel = String(format: MVMCoreUIUtility.hardcodedString(withKey: "stars_filled") ?? "", starsFilledValue, stack.arrangedSubviews.count)
}
}

View File

@ -0,0 +1,66 @@
//
// StarsModel.swift
// MVMCoreUI
//
// Created by Lekshmi S on 21/09/20.
// Copyright © 2020 Verizon Wireless. All rights reserved.
//
@objcMembers public class StarsModel: MoleculeModelProtocol {
//--------------------------------------------------
// MARK: - Properties
//--------------------------------------------------
public static var identifier: String = "stars"
public var backgroundColor: Color?
public var starBackgroundColor: Color?
public var stars: [StarModel]
@Percent public var percent: CGFloat = 0
public var borderColor: Color?
public var fillColor: Color?
public var size: CGFloat = 30.0
//--------------------------------------------------
// MARK: - Keys
//--------------------------------------------------
private enum CodingKeys: String, CodingKey {
case moleculeName
case backgroundColor
case starBackgroundColor
case stars
case percent
case borderColor
case fillColor
case size
}
//--------------------------------------------------
// MARK: - Codec
//--------------------------------------------------
required public init(from decoder: Decoder) throws {
let typeContainer = try decoder.container(keyedBy: CodingKeys.self)
stars = try typeContainer.decode([StarModel].self, forKey: .stars)
backgroundColor = try typeContainer.decodeIfPresent(Color.self, forKey: .backgroundColor)
starBackgroundColor = try typeContainer.decodeIfPresent(Color.self, forKey: .starBackgroundColor)
if let percent = try typeContainer.decodeIfPresent(CGFloat.self, forKey: .percent) {
self.percent = percent
}
borderColor = try typeContainer.decodeIfPresent(Color.self, forKey: .borderColor)
fillColor = try typeContainer.decodeIfPresent(Color.self, forKey: .fillColor)
if let size = try typeContainer.decodeIfPresent(CGFloat.self, forKey: .size) {
self.size = size
}
}
public func encode(to encoder: Encoder) throws {
var container = encoder.container(keyedBy: CodingKeys.self)
try container.encode(moleculeName, forKey: .moleculeName)
try container.encode(stars, forKey: .stars)
try container.encodeIfPresent(backgroundColor, forKey: .backgroundColor)
try container.encodeIfPresent(starBackgroundColor, forKey: .starBackgroundColor)
try container.encodeIfPresent(borderColor, forKey: .borderColor)
try container.encodeIfPresent(fillColor, forKey: .fillColor)
try container.encode(percent, forKey: .percent)
try container.encode(size, forKey: .size)
}
}

View File

@ -88,6 +88,8 @@ import Foundation
MoleculeObjectMapping.shared()?.register(viewClass: Tags.self, viewModelClass: TagsModel.self)
MoleculeObjectMapping.shared()?.register(viewClass: Tag.self, viewModelClass: TagModel.self)
MoleculeObjectMapping.shared()?.register(viewClass: Heart.self, viewModelClass: HeartModel.self)
MoleculeObjectMapping.shared()?.register(viewClass: Stars.self, viewModelClass: StarsModel.self)
MoleculeObjectMapping.shared()?.register(viewClass: Star.self, viewModelClass: StarModel.self)
// MARK:- Other Atoms

View File

@ -87,3 +87,8 @@
"CountDownHours" = " hours";
"CountDownMins" = " mins";
"CountDownSecs" = " secs";
// MARK: Star
"star" = "Star";
"star_percent" = "%d percent progress";
"stars_filled" = "%.1f out of %d stars";

View File

@ -66,3 +66,7 @@
"CountDownHours" = " horas";
"CountDownMins" = " min";
"CountDownSecs" = " seg";
// Star
"star" = "Estrella";
"star_percent" = "%@ porcentaje de progreso";
"stars_filled" = "%.1f de %d estrellas";

View File

@ -70,3 +70,8 @@
"CountDownHours" = " horas";
"CountDownMins" = " min";
"CountDownSecs" = " seg";
// Star
"star" = "Estrella";
"star_percent" = "%@ porcentaje de progreso";
"stars_filled" = "%.1f de %d estrellas";