Reorganized the MonsterDetail view to get around the 10 items per group limit.
Adds layout for resistances, immunities, and languages.
This commit is contained in:
@@ -42,6 +42,10 @@
|
||||
E2BD703125B3BBB90058ED69 /* MCStepperField.swift in Sources */ = {isa = PBXBuildFile; fileRef = E2BD703025B3BBB90058ED69 /* MCStepperField.swift */; };
|
||||
E2CB0DB326080C0500142591 /* EditSkill.swift in Sources */ = {isa = PBXBuildFile; fileRef = E2CB0DB226080C0500142591 /* EditSkill.swift */; };
|
||||
E2CB0DB826081A2F00142591 /* MCAbilityScorePicker.swift in Sources */ = {isa = PBXBuildFile; fileRef = E2CB0DB726081A2F00142591 /* MCAbilityScorePicker.swift */; };
|
||||
E2CB0DC026086E3C00142591 /* ChallengeRating.swift in Sources */ = {isa = PBXBuildFile; fileRef = E2CB0DBF26086E3C00142591 /* ChallengeRating.swift */; };
|
||||
E2CB0DC526086E5F00142591 /* SizeType.swift in Sources */ = {isa = PBXBuildFile; fileRef = E2CB0DC426086E5F00142591 /* SizeType.swift */; };
|
||||
E2CB0DCA26086E8300142591 /* ArmorType.swift in Sources */ = {isa = PBXBuildFile; fileRef = E2CB0DC926086E8300142591 /* ArmorType.swift */; };
|
||||
E2CB0DD72608720000142591 /* StringHelper.swift in Sources */ = {isa = PBXBuildFile; fileRef = E2CB0DD62608720000142591 /* StringHelper.swift */; };
|
||||
E2D473FD25B532C900CB36D7 /* Color+Hex.swift in Sources */ = {isa = PBXBuildFile; fileRef = E2D473FC25B532C900CB36D7 /* Color+Hex.swift */; };
|
||||
/* End PBXBuildFile section */
|
||||
|
||||
@@ -104,6 +108,10 @@
|
||||
E2BD703025B3BBB90058ED69 /* MCStepperField.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MCStepperField.swift; sourceTree = "<group>"; };
|
||||
E2CB0DB226080C0500142591 /* EditSkill.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EditSkill.swift; sourceTree = "<group>"; };
|
||||
E2CB0DB726081A2F00142591 /* MCAbilityScorePicker.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MCAbilityScorePicker.swift; sourceTree = "<group>"; };
|
||||
E2CB0DBF26086E3C00142591 /* ChallengeRating.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ChallengeRating.swift; sourceTree = "<group>"; };
|
||||
E2CB0DC426086E5F00142591 /* SizeType.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SizeType.swift; sourceTree = "<group>"; };
|
||||
E2CB0DC926086E8300142591 /* ArmorType.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ArmorType.swift; sourceTree = "<group>"; };
|
||||
E2CB0DD62608720000142591 /* StringHelper.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = StringHelper.swift; sourceTree = "<group>"; };
|
||||
E2D473FC25B532C900CB36D7 /* Color+Hex.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Color+Hex.swift"; sourceTree = "<group>"; };
|
||||
/* End PBXFileReference section */
|
||||
|
||||
@@ -137,7 +145,10 @@
|
||||
children = (
|
||||
E20209E725D8DEC100EFE733 /* AbilityScore.swift */,
|
||||
E20209F325D8E04300EFE733 /* AdvantageType.swift */,
|
||||
E2CB0DC926086E8300142591 /* ArmorType.swift */,
|
||||
E2CB0DBF26086E3C00142591 /* ChallengeRating.swift */,
|
||||
E20209F225D8E04300EFE733 /* ProficiencyType.swift */,
|
||||
E2CB0DC426086E5F00142591 /* SizeType.swift */,
|
||||
);
|
||||
path = Enums;
|
||||
sourceTree = "<group>";
|
||||
@@ -248,6 +259,7 @@
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
E2D473FC25B532C900CB36D7 /* Color+Hex.swift */,
|
||||
E2CB0DD62608720000142591 /* StringHelper.swift */,
|
||||
);
|
||||
path = Helpers;
|
||||
sourceTree = "<group>";
|
||||
@@ -393,8 +405,10 @@
|
||||
E257100925B1B2480055B23B /* MonsterDetail.swift in Sources */,
|
||||
E2D473FD25B532C900CB36D7 /* Color+Hex.swift in Sources */,
|
||||
E2B5285925B3028700AAA69E /* EditMonster.swift in Sources */,
|
||||
E2CB0DD72608720000142591 /* StringHelper.swift in Sources */,
|
||||
E2570FF525B1ADEB0055B23B /* Dashboard.swift in Sources */,
|
||||
E2CB0DB826081A2F00142591 /* MCAbilityScorePicker.swift in Sources */,
|
||||
E2CB0DC026086E3C00142591 /* ChallengeRating.swift in Sources */,
|
||||
E257100425B1AF4A0055B23B /* SearchBar.swift in Sources */,
|
||||
E20209F525D8E04300EFE733 /* AdvantageType.swift in Sources */,
|
||||
E24ACE6A2607F715009BF703 /* EditSkills.swift in Sources */,
|
||||
@@ -402,8 +416,10 @@
|
||||
E2570FFF25B1AE180055B23B /* Library.swift in Sources */,
|
||||
E2BD703125B3BBB90058ED69 /* MCStepperField.swift in Sources */,
|
||||
E2CB0DB326080C0500142591 /* EditSkill.swift in Sources */,
|
||||
E2CB0DCA26086E8300142591 /* ArmorType.swift in Sources */,
|
||||
E24ACE562607EE94009BF703 /* EditArmor.swift in Sources */,
|
||||
E20209F425D8E04300EFE733 /* ProficiencyType.swift in Sources */,
|
||||
E2CB0DC526086E5F00142591 /* SizeType.swift in Sources */,
|
||||
E2570FFA25B1AE020055B23B /* Collections.swift in Sources */,
|
||||
E24ACE5B2607F0F2009BF703 /* EditSpeed.swift in Sources */,
|
||||
E2570FB925B1AC520055B23B /* MonsterCardsApp.swift in Sources */,
|
||||
|
||||
40
MonsterCards/Helpers/StringHelper.swift
Normal file
40
MonsterCards/Helpers/StringHelper.swift
Normal file
@@ -0,0 +1,40 @@
|
||||
//
|
||||
// StringHelper.swift
|
||||
// MonsterCards
|
||||
//
|
||||
// Created by Tom Hicks on 3/21/21.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
|
||||
class StringHelper {
|
||||
static func oxfordJoin(
|
||||
_ strings: [String],
|
||||
_ separator: String,
|
||||
_ lastSeparator: String,
|
||||
_ onlySeparator: String
|
||||
) -> String {
|
||||
let numStrings = strings.count
|
||||
if (numStrings < 1) {
|
||||
return "";
|
||||
} else if (numStrings == 2) {
|
||||
return strings[0] + onlySeparator + strings[1]
|
||||
} else {
|
||||
var joined = ""
|
||||
var index = 0
|
||||
let lastIndex = numStrings - 1
|
||||
|
||||
strings.forEach {
|
||||
if index > 0 && index < lastIndex {
|
||||
joined.append(separator)
|
||||
} else if (index > 0 && index >= lastIndex) {
|
||||
joined.append(lastSeparator)
|
||||
}
|
||||
joined.append($0)
|
||||
index = index + 1
|
||||
}
|
||||
|
||||
return joined
|
||||
}
|
||||
}
|
||||
}
|
||||
50
MonsterCards/Models/Enums/ArmorType.swift
Normal file
50
MonsterCards/Models/Enums/ArmorType.swift
Normal file
@@ -0,0 +1,50 @@
|
||||
//
|
||||
// ArmorType.swift
|
||||
// MonsterCards
|
||||
//
|
||||
// Created by Tom Hicks on 3/21/21.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
|
||||
enum ArmorType: String, CaseIterable, Identifiable {
|
||||
case none = "none"
|
||||
case naturalArmor = "natural armor"
|
||||
case mageArmor = "mage armor"
|
||||
case padded = "padded"
|
||||
case leather = "leather"
|
||||
case studdedLeather = "studded"
|
||||
case hide = "hide"
|
||||
case chainShirt = "chain shirt"
|
||||
case scaleMail = "scale mail"
|
||||
case breastplate = "breastplate"
|
||||
case halfPlate = "half plate"
|
||||
case ringMail = "ring mail"
|
||||
case chainMail = "chain mail"
|
||||
case splintMail = "splint"
|
||||
case plateMail = "plate"
|
||||
case other = "other"
|
||||
|
||||
var id: ArmorType { self }
|
||||
|
||||
var displayName: String {
|
||||
switch self {
|
||||
case .none: return "None"
|
||||
case .naturalArmor: return "Natural Armor"
|
||||
case .mageArmor: return "Mage Armor"
|
||||
case .padded: return "Padded"
|
||||
case .leather: return "Leather"
|
||||
case .studdedLeather: return "Studded Leather"
|
||||
case .hide: return "Hide"
|
||||
case .chainShirt: return "Chain Shirt"
|
||||
case .scaleMail: return "Scale Mail"
|
||||
case .breastplate: return "Breastplate"
|
||||
case .halfPlate: return "Half Plate"
|
||||
case .ringMail: return "Ring Mail"
|
||||
case .chainMail: return "Chain Mail"
|
||||
case .splintMail: return "Splint Mail"
|
||||
case .plateMail: return "Plate Mail"
|
||||
case .other: return "Other"
|
||||
}
|
||||
}
|
||||
}
|
||||
53
MonsterCards/Models/Enums/ChallengeRating.swift
Normal file
53
MonsterCards/Models/Enums/ChallengeRating.swift
Normal file
@@ -0,0 +1,53 @@
|
||||
//
|
||||
// ChallengeRating.swift
|
||||
// MonsterCards
|
||||
//
|
||||
// Created by Tom Hicks on 3/21/21.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
|
||||
enum ChallengeRating: String, CaseIterable, Identifiable {
|
||||
case zero = "0"
|
||||
case oneEighth = "1/8"
|
||||
case oneQuarter = "1/4"
|
||||
case oneHalf = "1/2"
|
||||
case one = "1"
|
||||
case two = "2"
|
||||
case three = "3"
|
||||
case four = "4"
|
||||
case five = "5"
|
||||
case six = "6"
|
||||
case seven = "7"
|
||||
case eight = "8"
|
||||
case nine = "9"
|
||||
case ten = "10"
|
||||
case eleven = "11"
|
||||
case twelve = "12"
|
||||
case thirteen = "13"
|
||||
case fourteen = "14"
|
||||
case fifteen = "15"
|
||||
case sixteen = "16"
|
||||
case seventeen = "17"
|
||||
case eighteen = "18"
|
||||
case nineteen = "19"
|
||||
case twenty = "20"
|
||||
case twentyOne = "21"
|
||||
case twentyTwo = "22"
|
||||
case twentyThree = "23"
|
||||
case twentyFour = "24"
|
||||
case twentyFive = "25"
|
||||
case twentySix = "26"
|
||||
case twentySeven = "27"
|
||||
case twentyEight = "28"
|
||||
case twentyNine = "29"
|
||||
case thirty = "30"
|
||||
case custom = "*"
|
||||
|
||||
var id: ChallengeRating { self }
|
||||
|
||||
// Probably don't need this
|
||||
var displayName: String {
|
||||
return rawValue
|
||||
}
|
||||
}
|
||||
30
MonsterCards/Models/Enums/SizeType.swift
Normal file
30
MonsterCards/Models/Enums/SizeType.swift
Normal file
@@ -0,0 +1,30 @@
|
||||
//
|
||||
// SizeType.swift
|
||||
// MonsterCards
|
||||
//
|
||||
// Created by Tom Hicks on 3/21/21.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
|
||||
enum SizeType: String, CaseIterable, Identifiable {
|
||||
case tiny = "tiny"
|
||||
case small = "small"
|
||||
case medium = "medium"
|
||||
case large = "large"
|
||||
case huge = "huge"
|
||||
case gargantuan = "gargantuan"
|
||||
|
||||
var id: SizeType { self }
|
||||
|
||||
var displayName: String {
|
||||
switch self {
|
||||
case .tiny: return "Tiny"
|
||||
case .small: return "Small"
|
||||
case .medium: return "Medium"
|
||||
case .large: return "Large"
|
||||
case .huge: return "Huge"
|
||||
case .gargantuan: return "gargantuan"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -625,115 +625,84 @@ public class Monster: NSManagedObject {
|
||||
}
|
||||
}
|
||||
|
||||
// MARK: OTHER
|
||||
|
||||
var damageVulnerabilitiesArray: [String] {
|
||||
get {
|
||||
return ["Fire", "Poison", "Psychic"]
|
||||
}
|
||||
}
|
||||
|
||||
var damageVulnerabilitiesDescription: String {
|
||||
get {
|
||||
let sortedVulnerabilities = self.damageVulnerabilitiesArray.sorted()
|
||||
|
||||
return StringHelper.oxfordJoin(sortedVulnerabilities, ", ", ", and ", " and ")
|
||||
}
|
||||
}
|
||||
|
||||
var damageResistancesArray: [String] {
|
||||
get {
|
||||
return ["Ice", "Electric"]
|
||||
}
|
||||
}
|
||||
|
||||
var damageResistancesDescription: String {
|
||||
get {
|
||||
let sortedResistances = self.damageResistancesArray.sorted()
|
||||
return StringHelper.oxfordJoin(sortedResistances, ", ", ", and ", " and ")
|
||||
}
|
||||
}
|
||||
|
||||
var damageImmunitiesArray: [String] {
|
||||
get {
|
||||
return ["Slashing"]
|
||||
}
|
||||
}
|
||||
|
||||
var damageImmunitiesDescription: String {
|
||||
get {
|
||||
let sortedImmunities = self.damageImmunitiesArray.sorted()
|
||||
return StringHelper.oxfordJoin(sortedImmunities, ", ", ", and ", " and ")
|
||||
}
|
||||
}
|
||||
|
||||
var conditionImmunitiesArray: [String] {
|
||||
get {
|
||||
return []
|
||||
}
|
||||
}
|
||||
|
||||
var conditionImmunitiesDescription: String {
|
||||
get {
|
||||
let sortedImmunities = self.conditionImmunitiesArray.sorted()
|
||||
return StringHelper.oxfordJoin(sortedImmunities, ", ", ", and ", " and ")
|
||||
}
|
||||
}
|
||||
|
||||
var languagesArray: [String] {
|
||||
get {
|
||||
return ["Common", "Goblin"]
|
||||
}
|
||||
}
|
||||
|
||||
var languagesDescription: String {
|
||||
get {
|
||||
let sortedLanguages = self.languagesArray.sorted()
|
||||
return StringHelper.oxfordJoin(sortedLanguages, ", ", ", and ", " and ")
|
||||
}
|
||||
}
|
||||
|
||||
var challengeRatingDescription: String {
|
||||
get {
|
||||
return "";
|
||||
}
|
||||
}
|
||||
|
||||
// MARK: End
|
||||
|
||||
}
|
||||
|
||||
enum ArmorType: String, CaseIterable, Identifiable {
|
||||
case none = "none"
|
||||
case naturalArmor = "natural armor"
|
||||
case mageArmor = "mage armor"
|
||||
case padded = "padded"
|
||||
case leather = "leather"
|
||||
case studdedLeather = "studded"
|
||||
case hide = "hide"
|
||||
case chainShirt = "chain shirt"
|
||||
case scaleMail = "scale mail"
|
||||
case breastplate = "breastplate"
|
||||
case halfPlate = "half plate"
|
||||
case ringMail = "ring mail"
|
||||
case chainMail = "chain mail"
|
||||
case splintMail = "splint"
|
||||
case plateMail = "plate"
|
||||
case other = "other"
|
||||
|
||||
var id: ArmorType { self }
|
||||
|
||||
var displayName: String {
|
||||
switch self {
|
||||
case .none: return "None"
|
||||
case .naturalArmor: return "Natural Armor"
|
||||
case .mageArmor: return "Mage Armor"
|
||||
case .padded: return "Padded"
|
||||
case .leather: return "Leather"
|
||||
case .studdedLeather: return "Studded Leather"
|
||||
case .hide: return "Hide"
|
||||
case .chainShirt: return "Chain Shirt"
|
||||
case .scaleMail: return "Scale Mail"
|
||||
case .breastplate: return "Breastplate"
|
||||
case .halfPlate: return "Half Plate"
|
||||
case .ringMail: return "Ring Mail"
|
||||
case .chainMail: return "Chain Mail"
|
||||
case .splintMail: return "Splint Mail"
|
||||
case .plateMail: return "Plate Mail"
|
||||
case .other: return "Other"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
enum SizeType: String, CaseIterable, Identifiable {
|
||||
case tiny = "tiny"
|
||||
case small = "small"
|
||||
case medium = "medium"
|
||||
case large = "large"
|
||||
case huge = "huge"
|
||||
case gargantuan = "gargantuan"
|
||||
|
||||
var id: SizeType { self }
|
||||
|
||||
var displayName: String {
|
||||
switch self {
|
||||
case .tiny: return "Tiny"
|
||||
case .small: return "Small"
|
||||
case .medium: return "Medium"
|
||||
case .large: return "Large"
|
||||
case .huge: return "Huge"
|
||||
case .gargantuan: return "gargantuan"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
enum ChallengeRating: String, CaseIterable, Identifiable {
|
||||
case zero = "0"
|
||||
case oneEighth = "1/8"
|
||||
case oneQuarter = "1/4"
|
||||
case oneHalf = "1/2"
|
||||
case one = "1"
|
||||
case two = "2"
|
||||
case three = "3"
|
||||
case four = "4"
|
||||
case five = "5"
|
||||
case six = "6"
|
||||
case seven = "7"
|
||||
case eight = "8"
|
||||
case nine = "9"
|
||||
case ten = "10"
|
||||
case eleven = "11"
|
||||
case twelve = "12"
|
||||
case thirteen = "13"
|
||||
case fourteen = "14"
|
||||
case fifteen = "15"
|
||||
case sixteen = "16"
|
||||
case seventeen = "17"
|
||||
case eighteen = "18"
|
||||
case nineteen = "19"
|
||||
case twenty = "20"
|
||||
case twentyOne = "21"
|
||||
case twentyTwo = "22"
|
||||
case twentyThree = "23"
|
||||
case twentyFour = "24"
|
||||
case twentyFive = "25"
|
||||
case twentySix = "26"
|
||||
case twentySeven = "27"
|
||||
case twentyEight = "28"
|
||||
case twentyNine = "29"
|
||||
case thirty = "30"
|
||||
case custom = "*"
|
||||
|
||||
var id: ChallengeRating { self }
|
||||
|
||||
// Probably don't need this
|
||||
var displayName: String {
|
||||
return rawValue
|
||||
}
|
||||
}
|
||||
|
||||
@@ -70,41 +70,33 @@ struct SmallAbilityScore: View {
|
||||
}
|
||||
}
|
||||
|
||||
struct MonsterDetail: View {
|
||||
let kTextColor: Color = Color(hex: 0x982818)
|
||||
|
||||
struct BasicInfoView: View {
|
||||
@ObservedObject var monster: Monster
|
||||
|
||||
var body: some View {
|
||||
ScrollView {
|
||||
VStack (alignment: .leading) {
|
||||
let monsterMeta = monster.meta
|
||||
let monsterArmorClassDescription = monster.armorClassDescription
|
||||
let monsterHitPoints = monster.hitPoints
|
||||
let monsterSpeed = monster.speed
|
||||
|
||||
if (!monsterMeta.isEmpty) {
|
||||
// meta: "(large humanoid (elf) lawful evil"
|
||||
if (!monsterMeta.isEmpty) {
|
||||
Text(monsterMeta)
|
||||
.font(.subheadline)
|
||||
.foregroundColor(.secondary)
|
||||
}
|
||||
|
||||
// TODO: Find a way to hide unnecessarry dividiers.
|
||||
// if sections 0, 1, 2, and 3 are present there should be a divider between each of them
|
||||
// if section 1 is not present there should be one and only one divider between sections 0 and 2 as well as the one between 2 and 3
|
||||
// if sections 1 and 2 are not present there should be a single divider between sections 0 and 3
|
||||
SectionDivider()
|
||||
|
||||
if (!monsterArmorClassDescription.isEmpty) {
|
||||
// AC
|
||||
if (!monsterArmorClassDescription.isEmpty) {
|
||||
LabeledField("Armor Class") {
|
||||
Text(monsterArmorClassDescription)// armor class
|
||||
}
|
||||
}
|
||||
|
||||
if (!monsterHitPoints.isEmpty) {
|
||||
// HP
|
||||
if (!monsterHitPoints.isEmpty) {
|
||||
LabeledField("Hit Points") {
|
||||
Text(monsterHitPoints) // hit points
|
||||
}
|
||||
@@ -116,7 +108,13 @@ struct MonsterDetail: View {
|
||||
Text(monsterSpeed) // speed
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
struct AbilityScoresView: View {
|
||||
@ObservedObject var monster: Monster
|
||||
|
||||
var body: some View {
|
||||
SectionDivider()
|
||||
|
||||
// Ability Scores
|
||||
@@ -128,23 +126,119 @@ struct MonsterDetail: View {
|
||||
SmallAbilityScore("WIS", monster.wisdomScore, monster.wisdomModifier)
|
||||
SmallAbilityScore("CHA", monster.charismaScore, monster.charismaModifier)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
SectionDivider()
|
||||
struct ResistancesAndImmunitiesView: View {
|
||||
@ObservedObject var monster: Monster
|
||||
|
||||
var body: some View {
|
||||
let monsterDamageVulnerabilitiesDescription = monster.damageVulnerabilitiesDescription
|
||||
let monsterDamageResistancesDescription = monster.damageResistancesDescription
|
||||
let monsterDamageImmunitiesDescription = monster.damageImmunitiesDescription
|
||||
let monsterConditionImmunitiesDescription = monster.conditionImmunitiesDescription
|
||||
|
||||
// Damage Vulnerabilities
|
||||
if (!monsterDamageVulnerabilitiesDescription.isEmpty) {
|
||||
LabeledField("Damage Vulnerabilities") {
|
||||
Text(monsterDamageVulnerabilitiesDescription)
|
||||
}
|
||||
}
|
||||
|
||||
// Damage Resistances
|
||||
if (!monsterDamageResistancesDescription.isEmpty) {
|
||||
LabeledField("Damage Resistances") {
|
||||
Text(monsterDamageResistancesDescription)
|
||||
}
|
||||
}
|
||||
|
||||
// Damage Immunities
|
||||
if (!monsterDamageImmunitiesDescription.isEmpty) {
|
||||
LabeledField("Damage Immunities") {
|
||||
Text(monsterDamageImmunitiesDescription)
|
||||
}
|
||||
}
|
||||
|
||||
// Condition Immunities
|
||||
if (!monsterConditionImmunitiesDescription.isEmpty) {
|
||||
LabeledField("Condition Immunities") {
|
||||
Text(monsterConditionImmunitiesDescription)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
struct SavingThrowsAndSkillsView: View {
|
||||
@ObservedObject var monster: Monster
|
||||
|
||||
var body: some View {
|
||||
let savingThrowsDescription = monster.savingThrowsDescription
|
||||
let skillsDescription = monster.skillsDescription
|
||||
|
||||
// Saving Throws
|
||||
if (!savingThrowsDescription.isEmpty) {
|
||||
LabeledField("Saving Throws") {
|
||||
Text(savingThrowsDescription)
|
||||
}
|
||||
}
|
||||
|
||||
let skillsDescription = monster.skillsDescription
|
||||
// Skills
|
||||
if (!skillsDescription.isEmpty) {
|
||||
LabeledField("Skills") {
|
||||
Text(skillsDescription)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
struct MonsterDetail: View {
|
||||
let kTextColor: Color = Color(hex: 0x982818)
|
||||
|
||||
@ObservedObject var monster: Monster
|
||||
|
||||
var body: some View {
|
||||
ScrollView {
|
||||
VStack (alignment: .leading) {
|
||||
let monsterLanguagesDescription = monster.languagesDescription
|
||||
let monsterChallengeRatingDescription = monster.challengeRatingDescription
|
||||
|
||||
BasicInfoView(monster: monster)
|
||||
|
||||
// TODO: Find a way to hide unnecessarry dividiers.
|
||||
// if sections 0, 1, 2, and 3 are present there should be a divider between each of them
|
||||
// if section 1 is not present there should be one and only one divider between sections 0 and 2 as well as the one between 2 and 3
|
||||
// if sections 1 and 2 are not present there should be a single divider between sections 0 and 3
|
||||
|
||||
|
||||
AbilityScoresView(monster: monster)
|
||||
|
||||
SectionDivider()
|
||||
|
||||
SavingThrowsAndSkillsView(monster: monster)
|
||||
|
||||
ResistancesAndImmunitiesView(monster: monster)
|
||||
|
||||
// Languages
|
||||
if (!monsterLanguagesDescription.isEmpty) {
|
||||
LabeledField("Languages") {
|
||||
Text(monsterLanguagesDescription)
|
||||
}
|
||||
}
|
||||
|
||||
// Challenge Rating
|
||||
if (!monsterChallengeRatingDescription.isEmpty) {
|
||||
LabeledField("Challenge Rating") {
|
||||
Text(monsterChallengeRatingDescription)
|
||||
}
|
||||
}
|
||||
|
||||
// Abilities
|
||||
|
||||
// Actions
|
||||
|
||||
// Legendary Actions
|
||||
|
||||
}
|
||||
.padding(.horizontal)
|
||||
.foregroundColor(kTextColor)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user