Skip to content

Commit

Permalink
Merge pull request #491 from willowtreeapps/feature/253/categories-sa…
Browse files Browse the repository at this point in the history
…yings-empty-state

#253 | Enable and update Empty State views for Sayings & Categories
  • Loading branch information
moyerr authored Mar 24, 2022
2 parents 7c4317b + 749fa52 commit 64cd705
Show file tree
Hide file tree
Showing 9 changed files with 88 additions and 48 deletions.
8 changes: 8 additions & 0 deletions Vocable.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@
2745402E2460DD760056EF98 /* presets.json in Resources */ = {isa = PBXBuildFile; fileRef = 2745402D2460DD760056EF98 /* presets.json */; };
30B979A524254CBC00309D7C /* WarningView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 30B979A424254CBC00309D7C /* WarningView.swift */; };
30B979B82425583E00309D7C /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = 30B979BA2425583E00309D7C /* InfoPlist.strings */; };
4E014DAA27EA53BC00561FC8 /* NSRange+.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4E014DA927EA53BC00561FC8 /* NSRange+.swift */; };
4E8A303C27EBB95C000177B1 /* BidirectionalCollection+.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4E8A303B27EBB95C000177B1 /* BidirectionalCollection+.swift */; };
54D3C41723E37CD40061EF47 /* VocableTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 54D3C41623E37CD40061EF47 /* VocableTests.swift */; };
620DD31927DA90F1003B01A0 /* CustomCategoriesBaseTest.swift in Sources */ = {isa = PBXBuildFile; fileRef = 620DD31827DA90F1003B01A0 /* CustomCategoriesBaseTest.swift */; };
628B35C227DF9C6B00299312 /* BaseScreen.swift in Sources */ = {isa = PBXBuildFile; fileRef = 628B35C127DF9C6B00299312 /* BaseScreen.swift */; };
Expand Down Expand Up @@ -216,6 +218,8 @@
30B979A424254CBC00309D7C /* WarningView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WarningView.swift; sourceTree = "<group>"; };
30B979B92425583E00309D7C /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/InfoPlist.strings; sourceTree = "<group>"; };
30B979BB2425584300309D7C /* de */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = de; path = de.lproj/InfoPlist.strings; sourceTree = "<group>"; };
4E014DA927EA53BC00561FC8 /* NSRange+.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "NSRange+.swift"; sourceTree = "<group>"; };
4E8A303B27EBB95C000177B1 /* BidirectionalCollection+.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "BidirectionalCollection+.swift"; sourceTree = "<group>"; };
54D3C41423E37CD40061EF47 /* VocableTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = VocableTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
54D3C41623E37CD40061EF47 /* VocableTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = VocableTests.swift; sourceTree = "<group>"; };
54D3C41823E37CD40061EF47 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
Expand Down Expand Up @@ -835,6 +839,8 @@
6B724AA225E9774E0033891F /* UIEdgeInsets+Operators.swift */,
6B5C73A627DFE61600004713 /* PredicateBuilders.swift */,
6B5C73A827DFE63600004713 /* NSPredicate+Operators.swift */,
4E014DA927EA53BC00561FC8 /* NSRange+.swift */,
4E8A303B27EBB95C000177B1 /* BidirectionalCollection+.swift */,
);
path = Extensions;
sourceTree = "<group>";
Expand Down Expand Up @@ -1165,13 +1171,15 @@
A9CF2AEF242D44EE005633A7 /* TimingSensitivityViewController.swift in Sources */,
64B32593254B562B00023566 /* EditCategoryDetailTitleCollectionViewCell.swift in Sources */,
6459943E25895D9C0010EEFF /* SpeechRecognitionController.swift in Sources */,
4E014DAA27EA53BC00561FC8 /* NSRange+.swift in Sources */,
B8DA9DF423F30BD200FEBE19 /* VectorUtils.swift in Sources */,
B879831523E0DA8300DC1A81 /* PresetItemCollectionViewCell.swift in Sources */,
6B724AA325E9774F0033891F /* UIEdgeInsets+Operators.swift in Sources */,
6B823BCC23F4ADE30099F65E /* TunningView.swift in Sources */,
6B005AE5245B06F3004919F4 /* VocableViewController.swift in Sources */,
6BDE5D3D25C1DF1600F47066 /* TranscriptionOutputTextView.swift in Sources */,
6B9DFA5F23E889DB0037673E /* UIHeadGazeEvent.swift in Sources */,
4E8A303C27EBB95C000177B1 /* BidirectionalCollection+.swift in Sources */,
6B5C73B327E3ADCF00004713 /* AppResetController.swift in Sources */,
6BE2628B25BB376700281BB5 /* AudioPermissionPromptController.swift in Sources */,
6B4F3C6325A5137F008A3CB2 /* SoundEffect.swift in Sources */,
Expand Down
7 changes: 0 additions & 7 deletions Vocable.xcodeproj/xcshareddata/xcschemes/Development.xcscheme
Original file line number Diff line number Diff line change
Expand Up @@ -108,13 +108,6 @@
isEnabled = "NO">
</CommandLineArgument>
</CommandLineArguments>
<EnvironmentVariables>
<EnvironmentVariable
key = "EmptyStatesEnabled"
value = ""
isEnabled = "YES">
</EnvironmentVariable>
</EnvironmentVariables>
</LaunchAction>
<ProfileAction
buildConfiguration = "Debug"
Expand Down
4 changes: 0 additions & 4 deletions Vocable/AppConfig.swift
Original file line number Diff line number Diff line change
Expand Up @@ -57,10 +57,6 @@ struct AppConfig {
return Locale.preferredLanguages.first ?? defaultLanguageCode
}

static var emptyStatesEnabled: Bool {
return ProcessInfo.processInfo.environment.keys.contains("EmptyStatesEnabled")
}

static let isVoiceExperimentEnabled = true

}
70 changes: 35 additions & 35 deletions Vocable/Common/Views/EmptyStateView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,21 @@ private class EmptyStateButton: GazeableButton {
}

private func commonInit() {
contentEdgeInsets = .init(top: 16, left: 16, bottom: 16, right: 16)
updateForCurrentTraitCollection()
}

override func traitCollectionDidChange(_ previousTraitCollection: UITraitCollection?) {
super.traitCollectionDidChange(previousTraitCollection)
updateForCurrentTraitCollection()
}

private func updateForCurrentTraitCollection() {
let hasCompactSize = [traitCollection.horizontalSizeClass, traitCollection.verticalSizeClass]
.contains(.compact)

contentEdgeInsets = hasCompactSize ?
.vertical(8) + .horizontal(48) :
.uniform(32)
}
}

Expand Down Expand Up @@ -142,19 +156,16 @@ final class EmptyStateView: UIView {

private func commonInit() {

preservesSuperviewLayoutMargins = true

backgroundColor = .collectionViewBackgroundColor

stackView.spacing = 24
stackView.axis = .vertical
stackView.alignment = .center

if action != nil {
let font = UIFont.boldSystemFont(ofSize: 18)
if let title = button.title(for: .normal) {
let attributed = NSAttributedString(string: title,
attributes: [.font: font, .foregroundColor: UIColor.defaultTextColor])
attributes: [.foregroundColor: UIColor.defaultTextColor])
button.setAttributedTitle(attributed, for: .normal)
}
button.addTarget(self,
Expand All @@ -165,12 +176,12 @@ final class EmptyStateView: UIView {

stackView.translatesAutoresizingMaskIntoConstraints = false
addSubview(stackView)

NSLayoutConstraint.activate([
stackView.leftAnchor.constraint(greaterThanOrEqualTo: layoutMarginsGuide.leftAnchor),
stackView.rightAnchor.constraint(lessThanOrEqualTo: layoutMarginsGuide.rightAnchor),
stackView.centerYAnchor.constraint(equalTo: centerYAnchor),
stackView.centerXAnchor.constraint(equalTo: centerXAnchor),
stackView.widthAnchor.constraint(lessThanOrEqualTo: readableContentGuide.widthAnchor)
stackView.widthAnchor.constraint(lessThanOrEqualTo: readableContentGuide.widthAnchor),
stackView.heightAnchor.constraint(lessThanOrEqualTo: layoutMarginsGuide.heightAnchor)
])

let color = UIColor.defaultTextColor
Expand All @@ -192,40 +203,29 @@ final class EmptyStateView: UIView {
}

private func updateContentForCurrentTraitCollection() {
let hasCompactSize = [traitCollection.horizontalSizeClass, traitCollection.verticalSizeClass]
.contains(.compact)

if [traitCollection.horizontalSizeClass, traitCollection.verticalSizeClass].contains(.compact) {
titleLabel.font = .boldSystemFont(ofSize: 28)
} else {
titleLabel.font = .boldSystemFont(ofSize: 20)
let font: UIFont = hasCompactSize ?
.systemFont(ofSize: 22, weight: .bold) :
.systemFont(ofSize: 28, weight: .bold)

titleLabel.font = font

if let attributedButtonTitle = button.attributedTitle(for: .normal) {
let updatedButtonTitle = NSMutableAttributedString(attributedString: attributedButtonTitle)
updatedButtonTitle.addAttribute(.font, value: font, range: .entireRange(of: updatedButtonTitle.string))
button.setAttributedTitle(updatedButtonTitle, for: .normal)
}

}

@objc private func handleButton(_ sender: GazeableButton) {
if let action = action {
action()
}
action?()
}

private func updateStackView() {
if imageView.image != nil {
stackView.insertArrangedSubview(imageView, at: 0)
} else {
stackView.removeArrangedSubview(imageView)
imageView.removeFromSuperview()
}

if descriptionLabel.text != nil {
stackView.insertSubview(descriptionLabel, belowSubview: titleLabel)
} else {
stackView.removeArrangedSubview(descriptionLabel)
descriptionLabel.removeFromSuperview()
}

if descriptionLabel.attributedText != nil {
stackView.insertSubview(descriptionLabel, belowSubview: titleLabel)
} else {
stackView.removeArrangedSubview(descriptionLabel)
descriptionLabel.removeFromSuperview()
}
imageView.isHidden = imageView.image == nil
descriptionLabel.isHidden = descriptionLabel.text == nil && descriptionLabel.attributedText == nil
}
}
14 changes: 14 additions & 0 deletions Vocable/Extensions/BidirectionalCollection+.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
//
// BidirectionalCollection+.swift
// Vocable
//
// Created by Robert Moyer on 3/23/22.
// Copyright © 2022 WillowTree. All rights reserved.
//

extension BidirectionalCollection {
/// The range spanning all valid indices of the collection
var rangeOfIndices: Range<Index> {
startIndex ..< endIndex
}
}
19 changes: 19 additions & 0 deletions Vocable/Extensions/NSRange+.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
//
// StringProtocol+Range.swift
// Vocable
//
// Created by Robert Moyer on 3/22/22.
// Copyright © 2022 WillowTree. All rights reserved.
//

import Foundation

extension NSRange {
init<S: StringProtocol>(of s: S) {
self.init(s.rangeOfIndices, in: s)
}

static func entireRange<S: StringProtocol>(of s: S) -> NSRange {
NSRange(s.rangeOfIndices, in: s)
}
}
12 changes: 12 additions & 0 deletions Vocable/Extensions/UIEdgeInsets+Operators.swift
Original file line number Diff line number Diff line change
Expand Up @@ -27,4 +27,16 @@ extension UIEdgeInsets {
bottom: lhs.bottom - rhs.bottom,
right: lhs.right - rhs.right)
}

static func uniform(_ inset: CGFloat) -> UIEdgeInsets {
.init(top: inset, left: inset, bottom: inset, right: inset)
}

static func vertical(_ verticalInset: CGFloat) -> UIEdgeInsets {
.init(top: verticalInset, left: 0, bottom: verticalInset, right: 0)
}

static func horizontal(_ horizontalInset: CGFloat) -> UIEdgeInsets {
.init(top: 0, left: horizontalInset, bottom: 0, right: horizontalInset)
}
}
1 change: 0 additions & 1 deletion Vocable/Features/Root/CategoryDetailViewController.swift
Original file line number Diff line number Diff line change
Expand Up @@ -141,7 +141,6 @@ class CategoryDetailViewController: PagingCarouselViewController, NSFetchedResul
}

private func installEmptyStateIfNeeded() {
guard AppConfig.emptyStatesEnabled else { return }
guard collectionView.backgroundView == nil else { return }
paginationView.isHidden = true
if category.identifier == Category.Identifier.recents {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -124,7 +124,6 @@ final class EditPhrasesViewController: PagingCarouselViewController, NSFetchedRe
}

private func installEmptyStateIfNeeded() {
guard AppConfig.emptyStatesEnabled else { return }
guard collectionView.backgroundView == nil else { return }
paginationView.isHidden = true
collectionView.backgroundView = EmptyStateView(type: EmptyStateType.phraseCollection, action: addPhrasePressed)
Expand Down

0 comments on commit 64cd705

Please sign in to comment.