diff --git a/HabitRPG/Generated/Strings.swift b/HabitRPG/Generated/Strings.swift
index c3e3ba273..2051a4cf6 100644
--- a/HabitRPG/Generated/Strings.swift
+++ b/HabitRPG/Generated/Strings.swift
@@ -2045,6 +2045,8 @@ public enum L10n {
public static var helpFaq: String { return L10n.tr("Mainstrings", "menu.help_faq") }
/// Inventory
public static var inventory: String { return L10n.tr("Mainstrings", "menu.inventory") }
+ /// Quest Shop
+ public static var questShop: String { return L10n.tr("Mainstrings", "menu.quest_shop") }
/// Select Class
public static var selectClass: String { return L10n.tr("Mainstrings", "menu.select_class") }
/// Shops
diff --git a/HabitRPG/Storyboards/Base.lproj/Main.storyboard b/HabitRPG/Storyboards/Base.lproj/Main.storyboard
index 70c787398..744c064d6 100644
--- a/HabitRPG/Storyboards/Base.lproj/Main.storyboard
+++ b/HabitRPG/Storyboards/Base.lproj/Main.storyboard
@@ -830,13 +830,13 @@
-
+
-
+
@@ -879,23 +879,23 @@
-
+
-
+
-
+
@@ -903,7 +903,7 @@
-
+
diff --git a/HabitRPG/Strings/Base.lproj/Mainstrings.strings b/HabitRPG/Strings/Base.lproj/Mainstrings.strings
index 0a7bb62f9..09b25c072 100644
--- a/HabitRPG/Strings/Base.lproj/Mainstrings.strings
+++ b/HabitRPG/Strings/Base.lproj/Mainstrings.strings
@@ -782,11 +782,12 @@
"keep_tasks" = "Keep Tasks";
"delete_tasks" = "Delete Tasks";
"locations.market" = "Market";
-"locations.quest_shop" = "Quests";
+"locations.quest_shop" = "Quest Shop";
"locations.seasonal_shop" = "Seasonal Shop";
"locations.time_travelers_shop" = "Time Travelers";
"locations.customizations" = "Customizations";
"locations.stable" = "Stable";
+"menu.quest_shop" = "Quests";
"NPCs.alex" = "Alex the Merchant";
"NPCs.daniel" = "Daniel the inn keeper";
"NPCs.ian" = "Ian the Quest Guide";
diff --git a/HabitRPG/Strings/de.lproj/Mainstrings.strings b/HabitRPG/Strings/de.lproj/Mainstrings.strings
index fe3c8d8ec..51b329d3f 100644
--- a/HabitRPG/Strings/de.lproj/Mainstrings.strings
+++ b/HabitRPG/Strings/de.lproj/Mainstrings.strings
@@ -721,6 +721,7 @@
"locations.quest_shop" = "Quests";
"locations.seasonal_shop" = "Jahreszeitenmarkt";
"locations.stable" = "Stall";
+"menu.quest_shop" = "Quests";
"NPCs.alex" = "Alex der Händler";
"NPCs.daniel" = "Daniel der Wirt";
"NPCs.ian" = "Ian der Quest-Guide";
diff --git a/HabitRPG/TableViewDataSources/AvatarDetailViewDataSource.swift b/HabitRPG/TableViewDataSources/AvatarDetailViewDataSource.swift
index 53be5e747..816397d8d 100644
--- a/HabitRPG/TableViewDataSources/AvatarDetailViewDataSource.swift
+++ b/HabitRPG/TableViewDataSources/AvatarDetailViewDataSource.swift
@@ -163,6 +163,11 @@ class AvatarDetailViewDataSource: BaseReactiveCollectionViewDataSource Bool in
return section.items.isEmpty == false
@@ -225,7 +230,7 @@ class AvatarDetailViewDataSource: BaseReactiveCollectionViewDataSource {
@@ -15,24 +16,23 @@ class AvatarGearDetailViewDataSource: BaseReactiveCollectionViewDataSource())
var predicate: NSPredicate
- if gearType == "eyewear" || gearType == "headAccessory" {
- predicate = NSPredicate(format: "gearSet != nil && type == 'headAccessory'")
- if gearType == "eyewear" {
- predicate = NSPredicate(format: "gearSet == 'glasses' && type == 'eyewear'")
- }
+ if gearType == "headAccessory" {
+ predicate = NSPredicate(format: "gearSet == 'animal' && type == 'headAccessory'")
} else {
predicate = NSPredicate(format: "gearSet == 'animal' && type == 'back'")
}
@@ -89,23 +89,30 @@ class AvatarGearDetailViewDataSource: BaseReactiveCollectionViewDataSource String {
+ switch gearType {
+ case "headAccessory":
+ return L10n.animalEars
+ case "back":
+ return L10n.Avatar.animalTails
+ default:
+ return ""
+ }
+ }
+
private func configureSections(_ gear: [GearProtocol]) {
sections.removeAll()
sections.append(ItemSection())
+ sections[0].title = getTitle()
for gear in gear {
- if let set = gear.gearSet {
- if let index = sections.firstIndex(where: { (section) -> Bool in
- return section.key == set
- }) {
- sections[index].items.append(gear)
- } else {
- sections.append(ItemSection(key: set, title: sectionTitle(set)))
- sections.last?.items.append(gear)
+ if newCustomizationLayout {
+ if !owns(gear: gear) {
+ continue
}
- } else {
- sections[0].items.append(gear)
}
+ sections[0].items.append(gear)
}
+ sections[0].showIfEmpty = true
collectionView?.reloadData()
}
@@ -126,16 +133,28 @@ class AvatarGearDetailViewDataSource: BaseReactiveCollectionViewDataSource CGSize {
+ return CGSize(width: collectionView.frame.width, height: 80)
+ }
+
override func collectionView(_ collectionView: UICollectionView, viewForSupplementaryElementOfKind kind: String, at indexPath: IndexPath) -> UICollectionReusableView {
let view = super.collectionView(collectionView, viewForSupplementaryElementOfKind: kind, at: indexPath)
let section = visibleSections[indexPath.section]
if let headerView = view as? CustomizationHeaderView {
- headerView.label.text = section.title
- headerView.label.textColor = ThemeService.shared.theme.primaryTextColor
+ headerView.label.text = section.title?.localizedUppercase
+ headerView.label.textColor = ThemeService.shared.theme.quadTextColor
}
if let footerView = view as? CustomizationFooterView {
- footerView.isHidden = true
+ if newCustomizationLayout && indexPath.section == collectionView.numberOfSections - 1 {
+ footerView.purchaseButton.isHidden = true
+ footerView.hostingView.isHidden = false
+ let hostView = UIHostingView(rootView: CTAFooterView(type: gearType, hasItems: !sections[0].items.isEmpty))
+ footerView.hostingView.addSubview(hostView)
+ hostView.frame = CGRect(x: 0, y: 0, width: collectionView.frame.width, height: 200)
+ } else {
+ footerView.isHidden = true
+ }
}
return view
diff --git a/HabitRPG/TableViewDataSources/SeasonalShopCollectionViewDataSource.swift b/HabitRPG/TableViewDataSources/SeasonalShopCollectionViewDataSource.swift
index 080511b57..efba04dd3 100644
--- a/HabitRPG/TableViewDataSources/SeasonalShopCollectionViewDataSource.swift
+++ b/HabitRPG/TableViewDataSources/SeasonalShopCollectionViewDataSource.swift
@@ -18,6 +18,7 @@ class SeasonalShopCollectionViewDataSource: ShopCollectionViewDataSource {
}) {
let newSection = ItemSection(title: category.text)
newSection.items = category.items
+ newSection.endDate = category.endDate
sections.append(newSection)
}
collectionView?.reloadData()
diff --git a/HabitRPG/UI/General/MainMenuViewController.swift b/HabitRPG/UI/General/MainMenuViewController.swift
index eded93054..930f1b8e8 100644
--- a/HabitRPG/UI/General/MainMenuViewController.swift
+++ b/HabitRPG/UI/General/MainMenuViewController.swift
@@ -89,7 +89,7 @@ class MenuItem {
MenuItem(key: .stats, title: L10n.Titles.stats, vcInstantiator: StoryboardScene.User.attributePointsViewController.instantiate),
MenuItem(key: .achievements, title: L10n.Titles.achievements, vcInstantiator: StoryboardScene.User.achievementsCollectionViewController.instantiate),
MenuItem(key: .market, title: L10n.Locations.market, segue: StoryboardSegue.Main.showMarketSegue.rawValue),
- MenuItem(key: .questShop, title: L10n.Locations.questShop, segue: StoryboardSegue.Main.showQuestShopSegue.rawValue),
+ MenuItem(key: .questShop, title: L10n.Menu.questShop, segue: StoryboardSegue.Main.showQuestShopSegue.rawValue),
MenuItem(key: .seasonalShop, title: L10n.Locations.seasonalShop, segue: StoryboardSegue.Main.showSeasonalShopSegue.rawValue),
MenuItem(key: .customizationShop, title: L10n.Locations.customizations, segue: StoryboardSegue.Main.showCustomizationShopSegue.rawValue, isHidden: true),
MenuItem(key: .timeTravelersShop, title: L10n.Locations.timeTravelersShop, segue: StoryboardSegue.Main.showTimeTravelersSegue.rawValue),
diff --git a/HabitRPG/UI/Inventory/AvatarDetailViewController.swift b/HabitRPG/UI/Inventory/AvatarDetailViewController.swift
index 951407cbe..15d5ccd03 100644
--- a/HabitRPG/UI/Inventory/AvatarDetailViewController.swift
+++ b/HabitRPG/UI/Inventory/AvatarDetailViewController.swift
@@ -31,7 +31,7 @@ class AvatarDetailViewController: BaseCollectionViewController, UICollectionView
if let type = customizationType {
if type == "eyewear" || type == "headAccessory" || type == "back" || type == "animalTails" {
- gearDataSource = AvatarGearDetailViewDataSource(type: type)
+ gearDataSource = AvatarGearDetailViewDataSource(type: type, newCustomizationLayout: newCustomizationLayout)
gearDataSource?.collectionView = collectionView
} else {
customizationDataSource = AvatarDetailViewDataSource(type: type, group: customizationGroup, newCustomizationLayout: newCustomizationLayout)
diff --git a/HabitRPG/UI/Inventory/AvatarOverviewViewController.swift b/HabitRPG/UI/Inventory/AvatarOverviewViewController.swift
index 82177e7b3..3f5a0ae83 100644
--- a/HabitRPG/UI/Inventory/AvatarOverviewViewController.swift
+++ b/HabitRPG/UI/Inventory/AvatarOverviewViewController.swift
@@ -55,7 +55,11 @@ class AvatarOverviewViewController: BaseUIViewController, UIScrollViewDelegate {
override func applyTheme(theme: Theme) {
super.applyTheme(theme: theme)
bodySizeLabel.textColor = theme.primaryTextColor
- containerview.backgroundColor = theme.offsetBackgroundColor
+ if theme.isDark {
+ containerview.backgroundColor = .gray10
+ } else {
+ containerview.backgroundColor = theme.offsetBackgroundColor
+ }
}
override func populateText() {
@@ -97,7 +101,7 @@ class AvatarOverviewViewController: BaseUIViewController, UIScrollViewDelegate {
wheelchairView.setup(title: L10n.Avatar.wheelchair) {[weak self] in
self?.openDetailView(type: "chair")
}
- animalEarsView.setup(title: L10n.Avatar.head) {[weak self] in
+ animalEarsView.setup(title: L10n.animalEars) {[weak self] in
self?.openDetailView(type: "headAccessory")
}
backgroundView.setup(title: L10n.Avatar.background) {[weak self] in
diff --git a/HabitRPG/Views/AvatarOverviewItemView.swift b/HabitRPG/Views/AvatarOverviewItemView.swift
index fa74f31f3..373d4c19d 100644
--- a/HabitRPG/Views/AvatarOverviewItemView.swift
+++ b/HabitRPG/Views/AvatarOverviewItemView.swift
@@ -11,7 +11,11 @@ import UIKit
class AvatarOverviewItemView: UIView {
var imageView: NetworkImageView = {
let imageView = NetworkImageView()
- imageView.backgroundColor = ThemeService.shared.theme.windowBackgroundColor
+ if ThemeService.shared.theme.isDark {
+ imageView.backgroundColor = .gray50
+ } else {
+ imageView.backgroundColor = ThemeService.shared.theme.windowBackgroundColor
+ }
imageView.layer.cornerRadius = 4
imageView.contentMode = .center
return imageView