Skip to content

Commit

Permalink
Fix old customization views
Browse files Browse the repository at this point in the history
  • Loading branch information
phillipthelen committed Jun 10, 2024
1 parent 5462f4c commit 962dc34
Show file tree
Hide file tree
Showing 18 changed files with 629 additions and 48 deletions.
2 changes: 2 additions & 0 deletions HabitRPG/Generated/Storyboard Scenes.swift
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,8 @@ internal enum StoryboardScene {

internal static let avatarDetailViewController = SceneType<Habitica.AvatarDetailViewController>(storyboard: Main.self, identifier: "avatarDetailViewController")

internal static let oldAvatarDetailViewController = SceneType<Habitica.OldAvatarDetailViewController>(storyboard: Main.self, identifier: "oldAvatarDetailViewController")

internal static let spellTaskNavigationController = SceneType<UIKit.UINavigationController>(storyboard: Main.self, identifier: "spellTaskNavigationController")

internal static let tagNavigationController = SceneType<Habitica.ThemedNavigationController>(storyboard: Main.self, identifier: "tagNavigationController")
Expand Down
1 change: 1 addition & 0 deletions HabitRPG/Generated/Storyboard Segues.swift
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ internal enum StoryboardSegue {
case mountDetailSegue = "MountDetailSegue"
case newsSegue = "NewsSegue"
case notificationsSegue = "NotificationsSegue"
case oldDetailSegue = "OldDetailSegue"
case partySegue = "PartySegue"
case petDetailSegue = "PetDetailSegue"
case settingsSegue = "SettingsSegue"
Expand Down
2 changes: 2 additions & 0 deletions HabitRPG/Generated/Strings.swift
Original file line number Diff line number Diff line change
Expand Up @@ -544,6 +544,8 @@ public enum L10n {
public static var invitedFriendDescription: String { return L10n.tr("Mainstrings", "invitedFriendDescription") }
/// Invited a Friend
public static var invitedFriendTitle: String { return L10n.tr("Mainstrings", "invitedFriendTitle") }
/// Closed
public static var isClosed: String { return L10n.tr("Mainstrings", "is_closed") }
/// Open
public static var isOpen: String { return L10n.tr("Mainstrings", "is_open") }
/// Join
Expand Down
2 changes: 1 addition & 1 deletion HabitRPG/Habitica-Info.plist
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@
</dict>
</array>
<key>CFBundleVersion</key>
<string>983</string>
<string>985</string>
<key>CustomDomain</key>
<string>${CUSTOM_DOMAIN}</string>
<key>DisableSSL</key>
Expand Down
163 changes: 162 additions & 1 deletion HabitRPG/Storyboards/Base.lproj/Main.storyboard

Large diffs are not rendered by default.

1 change: 1 addition & 0 deletions HabitRPG/Strings/Base.lproj/Mainstrings.strings
Original file line number Diff line number Diff line change
Expand Up @@ -656,6 +656,7 @@
"copied_x_to_clipboard" = "Copied %@ to Clipboard";
"open" = "Open";
"is_open" = "Open";
"is_closed" = "Closed";
"open_mystery_item" = "You open the Mystery Box and find...";
"monday" = "Monday";
"tuesday" = "Tuesday";
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import Foundation
import Habitica_Models
import SwiftUIX

private class BlankGear: GearProtocol {
class BlankGear: GearProtocol {
var key: String?
var text: String?
var notes: String?
Expand Down Expand Up @@ -89,7 +89,7 @@ class AvatarGearDetailViewDataSource: BaseReactiveCollectionViewDataSource<GearP

if let gear = item(at: indexPath), let customizationCell = cell as? CustomizationDetailCell {
customizationCell.isCustomizationSelected = gear.key == equippedKey
customizationCell.currencyView.isHidden = owns(gear: gear)
customizationCell.currencyView.isHidden = owns(gear: gear) || gear is BlankGear
customizationCell.configure(gear: gear)
}

Expand All @@ -99,7 +99,7 @@ class AvatarGearDetailViewDataSource: BaseReactiveCollectionViewDataSource<GearP
override func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {

if let gear = item(at: indexPath) {
if !owns(gear: gear) && !newCustomizationLayout {
if !owns(gear: gear) && !newCustomizationLayout && !(gear is BlankGear) {
return CGSize(width: 80, height: 108)
} else {
return CGSize(width: 80, height: 80)
Expand Down
211 changes: 211 additions & 0 deletions HabitRPG/TableViewDataSources/OldAvatarDetailViewDataSource.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,211 @@
//
// AvatarDetailViewDataSource.swift
// Habitica
//
// Created by Phillip Thelen on 20.04.18.
// Copyright © 2018 HabitRPG Inc. All rights reserved.
//

import Foundation
import Habitica_Models

class OldAvatarDetailViewDataSource: BaseReactiveCollectionViewDataSource<CustomizationProtocol> {

private let customizationRepository = CustomizationRepository()
private let userRepository = UserRepository()

var customizationGroup: String?
var customizationType: String

var purchaseSet: ((CustomizationSetProtocol) -> Void)?

private var ownedCustomizations: [OwnedCustomizationProtocol] = []
private var customizationSets: [String: CustomizationSetProtocol] = [:]

private var equippedKey: String?

private var preferences: PreferencesProtocol?

private var gemCount = 0

init(type: String, group: String?) {
self.customizationType = type
self.customizationGroup = group
super.init()

disposable.add(customizationRepository.getCustomizations(type: customizationType, group: customizationGroup)
.combineLatest(with: customizationRepository.getOwnedCustomizations(type: customizationType, group: customizationGroup))
.on(value: {[weak self](customizations, ownedCustomizations) in
self?.ownedCustomizations = ownedCustomizations.value
self?.configureSections(customizations.value)
}).start())
disposable.add(userRepository.getUser().on(value: {[weak self]user in
self?.preferences = user.preferences
self?.gemCount = user.gemCount

self?.updateEquippedKey(user: user)
self?.collectionView?.reloadData()
}).start())
}

func canAfford(price: Float) -> Bool {
return Float(gemCount) >= price
}

func updateEquippedKey(user: UserProtocol) {
switch customizationType {
case "shirt":
equippedKey = user.preferences?.shirt
case "skin":
equippedKey = user.preferences?.skin
case "chair":
equippedKey = user.preferences?.chair
case "background":
equippedKey = user.preferences?.background
case "hair":
switch customizationGroup {
case "bangs":
equippedKey = String(user.preferences?.hair?.bangs ?? 0)
case "base":
equippedKey = String(user.preferences?.hair?.base ?? 0)
case "mustache":
equippedKey = String(user.preferences?.hair?.mustache ?? 0)
case "beard":
equippedKey = String(user.preferences?.hair?.beard ?? 0)
case "color":
equippedKey = String(user.preferences?.hair?.color ?? "")
case "flower":
equippedKey = String(user.preferences?.hair?.flower ?? 0)
default:
return
}
default:
return
}
}

func owns(customization: CustomizationProtocol) -> Bool {
return ownedCustomizations.contains(where: { (ownedCustomization) -> Bool in
return ownedCustomization.key == customization.key
})
}

private func configureSections(_ customizations: [CustomizationProtocol]) {
customizationSets.removeAll()
sections.removeAll()
sections.append(ItemSection<CustomizationProtocol>())
for customization in customizations {
if (customization.price > 0 && !customization.isPurchasable)
|| customization.key?.lowercased().contains("birthday_bash") == true {
if !owns(customization: customization) {
continue
}
}
if let set = customization.set {
if let index = sections.firstIndex(where: { (section) -> Bool in
return section.key == set.key
}) {
sections[index].items.append(customization)
} else {
customizationSets[set.key ?? ""] = set
sections.append(ItemSection<CustomizationProtocol>(key: set.key, title: set.text))
sections.last?.items.append(customization)
}
} else {
sections[0].items.append(customization)
}
}

if customizationType == "background" {
sections = sections.filter({ section -> Bool in
return section.items.isEmpty == false
}).sorted { (firstSection, secondSection) -> Bool in
if firstSection.key?.contains("incentive") == true || firstSection.key?.contains("timeTravel") == true || firstSection.key?.contains("event") == true {
return true
} else if secondSection.key?.contains("incentive") == true || secondSection.key?.contains("timeTravel") == true || secondSection.key?.contains("event") == true {
return false
}

if let firstKey = firstSection.key?.replacingOccurrences(of: "backgrounds", with: ""), let secondKey = secondSection.key?.replacingOccurrences(of: "backgrounds", with: "") {
let firstIndex = firstKey.index(firstKey.startIndex, offsetBy: 2)
let firstMonth = Int(firstKey[..<firstIndex]) ?? 0
let firstYear = Int(firstKey[firstIndex...]) ?? 0

let secondIndex = secondKey.index(secondKey.startIndex, offsetBy: 2)
let secondMonth = Int(secondKey[..<secondIndex]) ?? 0
let secondYear = Int(secondKey[secondIndex...]) ?? 0

if firstYear == secondYear {
return firstMonth >= secondMonth
} else {
return firstYear >= secondYear
}
}
return firstSection.key ?? "" < secondSection.key ?? ""
}
}
self.collectionView?.reloadData()
}

override func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "Cell", for: indexPath)

if let customization = item(at: indexPath), let customizationCell = cell as? CustomizationDetailCell {
customizationCell.isCustomizationSelected = customization.key == equippedKey
customizationCell.currencyView.isHidden = customization.isPurchasable == false || owns(customization: customization)
customizationCell.configure(customization: customization, preferences: preferences)
if customization.set?.key?.contains("incentive") == true {
customizationCell.imageView.alpha = owns(customization: customization) ? 1.0 : 0.3
} else {
customizationCell.imageView.alpha = 1.0
}
}

return cell
}

override func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {

if let customization = item(at: indexPath) {
if customization.isPurchasable == true && !owns(customization: customization) {
return CGSize(width: 80, height: 108)
} else {
return CGSize(width: 80, height: 80)
}
}
return CGSize.zero
}

override func collectionView(_ collectionView: UICollectionView, viewForSupplementaryElementOfKind kind: String, at indexPath: IndexPath) -> UICollectionReusableView {
let view = super.collectionView(collectionView, viewForSupplementaryElementOfKind: kind, at: indexPath)
let section = sections[indexPath.section]

if let footerView = view as? CustomizationFooterView {
if let set = customizationSets[section.key ?? ""] {
footerView.configure(customizationSet: set)
let individualPrice = set.setItems?.filter { (customization) -> Bool in
return !self.owns(customization: customization)
}.map { $0.price }.reduce(0, +) ?? 0
if individualPrice >= set.setPrice && set.setPrice != 0 && set.key?.contains("timeTravel") != true && set.key?.contains("incentive") != true {
footerView.purchaseButton.isHidden = false
} else {
footerView.purchaseButton.isHidden = true
}

footerView.purchaseButtonTapped = {
if let action = self.purchaseSet {
action(set)
}
}
} else {
footerView.purchaseButton.isHidden = true
}
} else if let headerView = view as? CustomizationHeaderView {
if let set = customizationSets[section.key ?? ""] {
headerView.configure(customizationSet: set, isBackground: customizationType == "background")
}
}

return view
}
}
8 changes: 6 additions & 2 deletions HabitRPG/UI/General/MainMenuViewController.swift
Original file line number Diff line number Diff line change
Expand Up @@ -389,7 +389,7 @@ class MainMenuViewController: BaseTableViewController {
})
}

if configRepository.bool(variable: .enableCustomizationShop) || configRepository.testingLevel.isDeveloper {
if configRepository.bool(variable: .enableCustomizationShop) {
menuItem(withKey: .customizationShop).isHidden = false
tableView.reloadData()
}
Expand Down Expand Up @@ -434,7 +434,11 @@ class MainMenuViewController: BaseTableViewController {
case "fall":
seasonText = L10n.fall
default:
seasonText = L10n.isOpen
if configRepository.bool(variable: .enableCustomizationShop) {
seasonText = L10n.isOpen
} else {
seasonText = L10n.isClosed
}
}
menuItem(withKey: .seasonalShop).pillText = seasonText
tableView.reloadData()
Expand Down
13 changes: 11 additions & 2 deletions HabitRPG/UI/Inventory/AvatarOverviewViewController.swift
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,10 @@ import Habitica_Models
import ReactiveSwift

class AvatarOverviewViewController: BaseUIViewController, UIScrollViewDelegate {
private let disposable = ScopedDisposable(CompositeDisposable())

private let userRepository = UserRepository()
private let disposable = ScopedDisposable(CompositeDisposable())
private let configRepository = ConfigRepository.shared

private var selectedType: String?
private var selectedGroup: String?
Expand Down Expand Up @@ -229,14 +230,22 @@ class AvatarOverviewViewController: BaseUIViewController, UIScrollViewDelegate {
private func openDetailView(type: String, group: String? = nil) {
selectedType = type
selectedGroup = group
perform(segue: StoryboardSegue.Main.detailSegue)
if configRepository.bool(variable: .enableCustomizationShop) {
perform(segue: StoryboardSegue.Main.detailSegue)
} else {
perform(segue: StoryboardSegue.Main.oldDetailSegue)
}
}

override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if segue.identifier == StoryboardSegue.Main.detailSegue.rawValue {
let destination = segue.destination as? AvatarDetailViewController
destination?.customizationType = selectedType
destination?.customizationGroup = selectedGroup
} else if segue.identifier == StoryboardSegue.Main.oldDetailSegue.rawValue {
let destination = segue.destination as? OldAvatarDetailViewController
destination?.customizationType = selectedType
destination?.customizationGroup = selectedGroup
}
}
}
Loading

0 comments on commit 962dc34

Please sign in to comment.