Add activity indicator, "error", "no results" and retry to gif picker.

// FREEBIE
pull/1/head
Matthew Chen 8 years ago
parent 6fb9af6363
commit 334396dac6

@ -15,6 +15,18 @@ class GifPickerViewController: OWSViewController, UISearchBarDelegate, UICollect
// MARK: Properties
enum ViewMode {
case idle, searching, results, noResults, error
}
private var viewMode = ViewMode.idle {
didSet {
Logger.info("\(TAG) viewMode: \(viewMode)")
updateContents()
}
}
public weak var delegate: GifPickerViewControllerDelegate?
var thread: TSThread?
@ -23,6 +35,9 @@ class GifPickerViewController: OWSViewController, UISearchBarDelegate, UICollect
let searchBar: UISearchBar
let layout: GifPickerLayout
let collectionView: UICollectionView
var noResultsView: UILabel?
var searchErrorView: UILabel?
var activityIndicator: UIActivityIndicatorView?
var imageInfos = [GiphyImageInfo]()
@ -159,12 +174,91 @@ class GifPickerViewController: OWSViewController, UISearchBarDelegate, UICollect
logoImageView.autoPinHeightToSuperview(withMargin:3)
logoImageView.autoHCenterInSuperview()
let noResultsView = createErrorLabel(text:NSLocalizedString("GIF_VIEW_SEARCH_NO_RESULTS",
comment:"Indicates that the user's search had no results."))
self.noResultsView = noResultsView
self.view.addSubview(noResultsView)
noResultsView.autoPinWidthToSuperview(withMargin:20)
noResultsView.autoVCenterInSuperview()
let searchErrorView = createErrorLabel(text:NSLocalizedString("GIF_VIEW_SEARCH_ERROR",
comment:"Indicates that an error occured while searching."))
self.searchErrorView = searchErrorView
self.view.addSubview(searchErrorView)
searchErrorView.autoPinWidthToSuperview(withMargin:20)
searchErrorView.autoVCenterInSuperview()
searchErrorView.isUserInteractionEnabled = true
searchErrorView.addGestureRecognizer(UITapGestureRecognizer(target:self, action:#selector(retryTapped)))
let activityIndicator = UIActivityIndicatorView(activityIndicatorStyle:.gray)
self.activityIndicator = activityIndicator
self.view.addSubview(activityIndicator)
activityIndicator.autoCenterInSuperview()
self.updateContents()
}
private func createErrorLabel(text: String) -> UILabel {
let label = UILabel()
label.text = text
label.textColor = UIColor.black
label.font = UIFont.ows_mediumFont(withSize:20)
label.textAlignment = .center
label.numberOfLines = 0
label.lineBreakMode = .byWordWrapping
return label
}
private func updateContents() {
self.collectionView.collectionViewLayout.invalidateLayout()
self.collectionView.reloadData()
guard let noResultsView = self.noResultsView else {
owsFail("Missing noResultsView")
return
}
guard let searchErrorView = self.searchErrorView else {
owsFail("Missing searchErrorView")
return
}
guard let activityIndicator = self.activityIndicator else {
owsFail("Missing activityIndicator")
return
}
switch viewMode {
case .idle:
self.collectionView.isHidden = true
noResultsView.isHidden = true
searchErrorView.isHidden = true
activityIndicator.isHidden = true
activityIndicator.stopAnimating()
case .searching:
self.collectionView.isHidden = true
noResultsView.isHidden = true
searchErrorView.isHidden = true
activityIndicator.isHidden = false
activityIndicator.startAnimating()
case .results:
self.collectionView.isHidden = false
noResultsView.isHidden = true
searchErrorView.isHidden = true
activityIndicator.isHidden = true
activityIndicator.stopAnimating()
self.collectionView.collectionViewLayout.invalidateLayout()
self.collectionView.reloadData()
case .noResults:
self.collectionView.isHidden = true
noResultsView.isHidden = false
searchErrorView.isHidden = true
activityIndicator.isHidden = true
activityIndicator.stopAnimating()
case .error:
self.collectionView.isHidden = true
noResultsView.isHidden = true
searchErrorView.isHidden = false
activityIndicator.isHidden = true
activityIndicator.stopAnimating()
}
}
// MARK: - UICollectionViewDataSource
@ -250,6 +344,10 @@ class GifPickerViewController: OWSViewController, UISearchBarDelegate, UICollect
}
public func searchBarSearchButtonClicked(_ searchBar: UISearchBar) {
tryToSearch()
}
public func tryToSearch() {
guard let text = searchBar.text else {
OWSAlerts.showAlert(withTitle: NSLocalizedString("ALERT_ERROR_TITLE",
comment: ""),
@ -263,19 +361,24 @@ class GifPickerViewController: OWSViewController, UISearchBarDelegate, UICollect
private func search(query: String) {
self.searchBar.resignFirstResponder()
imageInfos = []
updateContents()
viewMode = .searching
self.collectionView.contentOffset = CGPoint.zero
GiphyAPI.sharedInstance.search(query: query, success: { [weak self] imageInfos in
guard let strongSelf = self else { return }
Logger.info("\(strongSelf.TAG) search complete")
strongSelf.imageInfos = imageInfos
strongSelf.updateContents()
if imageInfos.count > 0 {
strongSelf.viewMode = .results
} else {
strongSelf.viewMode = .noResults
}
},
failure: { [weak self] _ in
guard let strongSelf = self else { return }
Logger.info("\(strongSelf.TAG) search failed.")
// TODO: Present this error to the user.
strongSelf.viewMode = .error
})
}
@ -284,4 +387,16 @@ class GifPickerViewController: OWSViewController, UISearchBarDelegate, UICollect
func imageInfosForLayout() -> [GiphyImageInfo] {
return imageInfos
}
// MARK: - Event Handlers
func retryTapped(sender: UIGestureRecognizer) {
guard sender.state == .recognized else {
return
}
guard viewMode == .error else {
return
}
tryToSearch()
}
}

@ -610,6 +610,12 @@
/* Title for the 'gif picker' dialog. */
"GIF_PICKER_VIEW_TITLE" = "GIF Search";
/* Indicates that an error occured while searching. */
"GIF_VIEW_SEARCH_ERROR" = "Error. Tap to Retry.";
/* Indicates that the user's search had no results. */
"GIF_VIEW_SEARCH_NO_RESULTS" = "No Results.";
/* Placeholder text for the search field in gif view */
"GIF_VIEW_SEARCH_PLACEHOLDER_TEXT" = "Enter your search";

Loading…
Cancel
Save