From b25ae75841f2985ac15bb759affde8039b57715f Mon Sep 17 00:00:00 2001 From: Cameron Moreau Date: Wed, 3 Oct 2018 18:25:52 -0700 Subject: [PATCH] Add "Try Again" button for EmptyView (#2214) --- Classes/Issues/IssuesViewController.swift | 9 ++++++++ ...lRequestReviewCommentsViewController.swift | 9 ++++++++ .../RepositoryCodeBlobViewController.swift | 10 ++++++++- .../RepositoryWebViewController.swift | 12 ++++++++++ Classes/Search/SearchViewController.swift | 22 ++++++++++++++----- .../BaseListViewController.swift | 9 ++++++++ Classes/Views/Constants.swift | 1 + Classes/Views/EmptyView.swift | 22 +++++++++++++++++++ 8 files changed, 88 insertions(+), 6 deletions(-) diff --git a/Classes/Issues/IssuesViewController.swift b/Classes/Issues/IssuesViewController.swift index 9ebae0347..7210f3b2c 100644 --- a/Classes/Issues/IssuesViewController.swift +++ b/Classes/Issues/IssuesViewController.swift @@ -34,6 +34,7 @@ final class IssuesViewController: FlatCacheListener, IssueCommentSectionControllerDelegate, IssueTextActionsViewSendDelegate, + EmptyViewDelegate, MessageTextViewListener { private let client: GithubClient @@ -501,6 +502,8 @@ final class IssuesViewController: case .idle: let emptyView = EmptyView() emptyView.label.text = NSLocalizedString("Issue cannot be found", comment: "") + emptyView.delegate = self + emptyView.button.isHidden = false return emptyView case .loading, .loadingNext: return nil @@ -615,6 +618,12 @@ final class IssuesViewController: } } + // MARK: EmptyViewDelegate + + func didTapRetry() { + self.feed.refreshHead() + } + // MARK: MessageTextViewListener func didChange(textView: MessageTextView) { diff --git a/Classes/PullRequestReviews/PullRequestReviewCommentsViewController.swift b/Classes/PullRequestReviews/PullRequestReviewCommentsViewController.swift index 4956c6209..07d0e1d9c 100644 --- a/Classes/PullRequestReviews/PullRequestReviewCommentsViewController.swift +++ b/Classes/PullRequestReviews/PullRequestReviewCommentsViewController.swift @@ -16,6 +16,7 @@ final class PullRequestReviewCommentsViewController: MessageViewController, ListAdapterDataSource, FeedDelegate, PullRequestReviewReplySectionControllerDelegate, + EmptyViewDelegate, IssueTextActionsViewSendDelegate { private let model: IssueDetailsModel @@ -169,6 +170,8 @@ final class PullRequestReviewCommentsViewController: MessageViewController, case .idle: let emptyView = EmptyView() emptyView.label.text = NSLocalizedString("Error loading review comments.", comment: "") + emptyView.delegate = self + emptyView.button.isHidden = false return emptyView case .loadingNext: return nil @@ -187,6 +190,12 @@ final class PullRequestReviewCommentsViewController: MessageViewController, focusedReplyModel = reply } + // MARK: EmptyViewDelegate + + func didTapRetry() { + self.feed.refreshHead() + } + // MARK: IssueTextActionsViewSendDelegate func didSend(for actionsView: IssueTextActionsView) { diff --git a/Classes/Repository/RepositoryCodeBlobViewController.swift b/Classes/Repository/RepositoryCodeBlobViewController.swift index c9027f804..63bd7d10b 100644 --- a/Classes/Repository/RepositoryCodeBlobViewController.swift +++ b/Classes/Repository/RepositoryCodeBlobViewController.swift @@ -9,7 +9,7 @@ import UIKit import Squawk -final class RepositoryCodeBlobViewController: UIViewController { +final class RepositoryCodeBlobViewController: UIViewController, EmptyViewDelegate { private let client: GithubClient private let branch: String @@ -55,6 +55,8 @@ final class RepositoryCodeBlobViewController: UIViewController { view.backgroundColor = .white emptyView.isHidden = true + emptyView.delegate = self + emptyView.button.isHidden = false view.addSubview(emptyView) view.addSubview(codeView) @@ -136,4 +138,10 @@ final class RepositoryCodeBlobViewController: UIViewController { codeView.set(code: text) } + // MARK: EmptyViewDelegate + + func didTapRetry() { + self.onRefresh() + } + } diff --git a/Classes/Repository/RepositoryWebViewController.swift b/Classes/Repository/RepositoryWebViewController.swift index 524d22223..3ec576d02 100644 --- a/Classes/Repository/RepositoryWebViewController.swift +++ b/Classes/Repository/RepositoryWebViewController.swift @@ -129,6 +129,16 @@ extension RepositoryWebViewController: WKNavigationDelegate { } +// MARK: - RepositoryWebViewController (EmptyViewDelegate) - + +extension RepositoryWebViewController: EmptyViewDelegate { + + func didTapRetry() { + self.fetch() + } + +} + // MARK: - RepositoryWebViewController (Fetch Data) - extension RepositoryWebViewController { @@ -179,6 +189,8 @@ extension RepositoryWebViewController { state = .idle emptyView.isHidden = true + emptyView.delegate = self + emptyView.button.isHidden = false view.backgroundColor = .white view.addSubview(emptyView) diff --git a/Classes/Search/SearchViewController.swift b/Classes/Search/SearchViewController.swift index d0d0f8315..1ead7b6c6 100644 --- a/Classes/Search/SearchViewController.swift +++ b/Classes/Search/SearchViewController.swift @@ -14,11 +14,12 @@ class SearchViewController: UIViewController, ListAdapterDataSource, PrimaryViewController, UISearchBarDelegate, -InitialEmptyViewDelegate, -SearchRecentSectionControllerDelegate, -SearchRecentHeaderSectionControllerDelegate, -TabNavRootViewControllerType, -SearchResultSectionControllerDelegate { + EmptyViewDelegate, + InitialEmptyViewDelegate, + SearchRecentSectionControllerDelegate, + SearchRecentHeaderSectionControllerDelegate, + TabNavRootViewControllerType, + SearchResultSectionControllerDelegate { private let client: GithubClient private let noResultsKey = "com.freetime.SearchViewController.no-results-key" as ListDiffable @@ -188,6 +189,8 @@ SearchResultSectionControllerDelegate { case .error: let view = EmptyView() view.label.text = NSLocalizedString("Error finding results", comment: "") + view.delegate = self + view.button.isHidden = false return view case .results: return nil @@ -226,6 +229,15 @@ SearchResultSectionControllerDelegate { update(animated: false) } + // MARK: EmptyViewDelegate + + func didTapRetry() { + searchBar.resignFirstResponder() + + guard let term = searchTerm(for: searchBar.text) else { return } + search(term: term) + } + // MARK: InitialEmptyViewDelegate func didTap(emptyView: InitialEmptyView) { diff --git a/Classes/View Controllers/BaseListViewController.swift b/Classes/View Controllers/BaseListViewController.swift index bbbcc964e..36b7a9cc2 100644 --- a/Classes/View Controllers/BaseListViewController.swift +++ b/Classes/View Controllers/BaseListViewController.swift @@ -31,6 +31,7 @@ protocol BaseListViewControllerDataSource: class { class BaseListViewController: UIViewController, ListAdapterDataSource, FeedDelegate, +EmptyViewDelegate, LoadMoreSectionControllerDelegate { // required on init @@ -160,6 +161,8 @@ LoadMoreSectionControllerDelegate { guard hasError else { return nil } let empty = EmptyView() empty.label.text = emptyErrorMessage + empty.delegate = self + empty.button.isHidden = false return empty } @@ -174,6 +177,12 @@ LoadMoreSectionControllerDelegate { return false } + // MARK: EmptyViewDelegate + + func didTapRetry() { + self.feed.refreshHead() + } + // MARK: LoadMoreSectionControllerDelegate final func didSelect(sectionController: LoadMoreSectionController) { diff --git a/Classes/Views/Constants.swift b/Classes/Views/Constants.swift index 22baac0a6..a2039fbb8 100644 --- a/Classes/Views/Constants.swift +++ b/Classes/Views/Constants.swift @@ -56,5 +56,6 @@ enum Constants { static let assignees = NSLocalizedString("Assignees", comment: "") static let reviewers = NSLocalizedString("Reviewers", comment: "") static let reviewGitHubAccess = NSLocalizedString("Review GitHub Access", comment: "") + static let tryAgain = NSLocalizedString("Try Again", comment: "") } } diff --git a/Classes/Views/EmptyView.swift b/Classes/Views/EmptyView.swift index 8886f5c49..975938ac7 100644 --- a/Classes/Views/EmptyView.swift +++ b/Classes/Views/EmptyView.swift @@ -9,9 +9,15 @@ import UIKit import SnapKit +protocol EmptyViewDelegate: class { + func didTapRetry() +} + final class EmptyView: UIView { let label = UILabel() + let button = UIButton(type: .system) + var delegate: EmptyViewDelegate? override init(frame: CGRect) { super.init(frame: frame) @@ -22,14 +28,30 @@ final class EmptyView: UIView { label.textColor = Styles.Colors.Gray.medium.color label.numberOfLines = 0 addSubview(label) + + button.isHidden = true + button.titleLabel?.font = Styles.Text.button.preferredFont + button.setTitle(Constants.Strings.tryAgain, for: .normal) + button.setTitleColor(Styles.Colors.Blue.medium.color, for: .normal) + button.addTarget(self, action: #selector(tapRetry), for: .touchUpInside) + addSubview(button) + label.snp.makeConstraints { make in make.center.equalTo(self) make.width.lessThanOrEqualToSuperview().offset(-Styles.Sizes.gutter) } + + button.snp.makeConstraints { make in + make.centerX.equalTo(self) + make.top.equalTo(label).offset(Styles.Sizes.gutter) + } } required init?(coder aDecoder: NSCoder) { fatalError("init(coder:) has not been implemented") } + @objc private func tapRetry(sender: UIButton) { + delegate?.didTapRetry() + } }