Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Replace old placeholders & empty states #256

Merged
merged 31 commits into from
Apr 4, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
31 commits
Select commit Hold shift + click to select a range
32b4803
New placeholder view
kvld Mar 16, 2018
04c6315
Add UITableView subclass with placeholders support
kvld Mar 16, 2018
d57473c
Add more placeholders
kvld Mar 16, 2018
4ebbacd
Add L10n
kvld Mar 16, 2018
a77c251
Some fixes
kvld Mar 16, 2018
f83f587
Vector assets in PDF
kvld Mar 16, 2018
6d10f8a
Use updated empty state in notifications
kvld Mar 16, 2018
2e840fa
Use updated empty state in downloads
kvld Mar 16, 2018
388b3d0
Hide image container when image is nil
kvld Mar 16, 2018
3790a0d
Add hideable button
kvld Mar 18, 2018
c6c0626
Add loading state to StepikTableView
kvld Mar 20, 2018
29cf5fc
Add StepikViewController & anonymous state for certificates
kvld Mar 20, 2018
9190c74
Remove old placeholders & empty states: certificates
kvld Mar 22, 2018
de70a6c
Merge branch 'dev' into feature/remove-dzn
kvld Mar 22, 2018
aa7b054
Add retry action for certificates placeholder
kvld Mar 22, 2018
2f45b81
Remove old placeholders & empty states: discussions
kvld Mar 22, 2018
8bcb4e3
Remove old placeholders & empty states: profile
kvld Mar 22, 2018
b407068
Remove old placeholders & empty states: sections
kvld Mar 22, 2018
6185385
Remove old placeholders & empty states: units
kvld Mar 22, 2018
c1d7e3f
Remove DZNEmptyDataSet from dependencies
kvld Mar 22, 2018
63154f8
Remove old placeholders & empty states: quiz
kvld Mar 22, 2018
923d6ee
Subclass -> protocol
kvld Mar 22, 2018
534ef89
Remove old placeholders & empty states: notifications
kvld Mar 22, 2018
368e9c0
Rename file & remove unused code
kvld Mar 22, 2018
ff15a40
Remove old placeholders & empty states: card steps
kvld Mar 23, 2018
aa0044c
Remove old placeholders & empty states: course select (adaptive)
kvld Mar 23, 2018
eb2f9ca
Remove PlaceholderView
kvld Mar 23, 2018
fd13c9e
Fix placeholder visibility
kvld Apr 3, 2018
5560167
Fix placeholder updates
kvld Apr 3, 2018
aacc4c8
Merge branch 'dev' into feature/remove-dzn
kvld Apr 3, 2018
c8150a0
Remove internal modificator
kvld Apr 3, 2018
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 0 additions & 1 deletion Podfile
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,6 @@ def all_pods
pod 'SVProgressHUD'
pod 'FLKAutoLayout', '1.0.1'
pod 'TSMessages', :git => 'https://github.com/KrauseFx/TSMessages.git'
pod 'DZNEmptyDataSet'
pod 'YandexMobileMetrica/Dynamic'

pod 'FirebaseCore'
Expand Down
182 changes: 38 additions & 144 deletions Stepic.xcodeproj/project.pbxproj

Large diffs are not rendered by default.

6 changes: 3 additions & 3 deletions Stepic/Base.lproj/Main.storyboard
Original file line number Diff line number Diff line change
Expand Up @@ -254,7 +254,7 @@
<rect key="frame" x="0.0" y="0.0" width="375" height="603"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<subviews>
<tableView clipsSubviews="YES" contentMode="scaleToFill" alwaysBounceVertical="YES" dataMode="prototypes" style="plain" separatorStyle="default" rowHeight="44" sectionHeaderHeight="28" sectionFooterHeight="28" translatesAutoresizingMaskIntoConstraints="NO" id="L6O-ow-pfW">
<tableView clipsSubviews="YES" contentMode="scaleToFill" alwaysBounceVertical="YES" dataMode="prototypes" style="plain" separatorStyle="default" rowHeight="44" sectionHeaderHeight="28" sectionFooterHeight="28" translatesAutoresizingMaskIntoConstraints="NO" id="L6O-ow-pfW" customClass="StepikTableView" customModule="Adaptive_1838" customModuleProvider="target">
<rect key="frame" x="0.0" y="0.0" width="375" height="603"/>
<color key="backgroundColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<viewLayoutGuide key="safeArea" id="GLF-og-ZMI"/>
Expand Down Expand Up @@ -297,7 +297,7 @@
<rect key="frame" x="0.0" y="0.0" width="375" height="667"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<subviews>
<tableView clipsSubviews="YES" contentMode="scaleToFill" alwaysBounceVertical="YES" dataMode="prototypes" style="plain" separatorStyle="default" rowHeight="44" sectionHeaderHeight="28" sectionFooterHeight="28" translatesAutoresizingMaskIntoConstraints="NO" id="Q7F-3H-ipp">
<tableView clipsSubviews="YES" contentMode="scaleToFill" alwaysBounceVertical="YES" dataMode="prototypes" style="plain" separatorStyle="default" rowHeight="44" sectionHeaderHeight="28" sectionFooterHeight="28" translatesAutoresizingMaskIntoConstraints="NO" id="Q7F-3H-ipp" customClass="StepikTableView" customModule="Adaptive_1838" customModuleProvider="target">
<rect key="frame" x="0.0" y="20" width="375" height="647"/>
<color key="backgroundColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<connections>
Expand Down Expand Up @@ -690,6 +690,6 @@
</resources>
<inferredMetricsTieBreakers>
<segue reference="Ymm-um-wgY"/>
<segue reference="gVj-jL-WXR"/>
<segue reference="oyz-px-1HN"/>
</inferredMetricsTieBreakers>
</document>
91 changes: 17 additions & 74 deletions Stepic/CardsStepsViewController.swift
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,9 @@ import Foundation
import PromiseKit
import Koloda

class CardsStepsViewController: UIViewController, CardsStepsView {
class CardsStepsViewController: UIViewController, CardsStepsView, ControllerWithStepikPlaceholder {

var placeholderContainer: StepikPlaceholderControllerContainer = StepikPlaceholderControllerContainer()
var presenter: CardsStepsPresenter?

@IBOutlet weak var kolodaView: KolodaView!
Expand All @@ -25,34 +26,32 @@ class CardsStepsViewController: UIViewController, CardsStepsView {
didSet {
switch state {
case .normal:
self.placeholderView.isHidden = true
self.kolodaView.isHidden = false
case .connectionError, .coursePassed:
self.placeholderView.isHidden = false
self.kolodaView.isHidden = true

self.placeholderView.datasource = self
isPlaceholderShown = false
case .connectionError:
showPlaceholder(for: .connectionError)
case .coursePassed:
showPlaceholder(for: .adaptiveCoursePassed)
default:
break
}
}
}

lazy var placeholderView: PlaceholderView = {
let v = PlaceholderView()
self.view.insertSubview(v, aboveSubview: self.view)
v.align(toView: self.kolodaView)
v.delegate = self
v.datasource = self
v.backgroundColor = self.view.backgroundColor
return v
}()

// Can be overriden in the children classes (for adaptive app)
var cardView: StepCardView {
return StepCardView()
}

override func viewDidLoad() {
super.viewDidLoad()

registerPlaceholder(placeholder: StepikPlaceholder(.noConnection, action: { [weak self] in
self?.presenter?.tryAgain()
}), for: .connectionError)

registerPlaceholder(placeholder: StepikPlaceholder(.adaptiveCoursePassed), for: .adaptiveCoursePassed)
}

func refreshCards() {
if kolodaView.delegate == nil {
kolodaView.dataSource = self
Expand Down Expand Up @@ -199,62 +198,6 @@ extension CardsStepsViewController: KolodaViewDataSource {
}
}

extension CardsStepsViewController: PlaceholderViewDataSource {
func placeholderImage() -> UIImage? {
switch state {
case .connectionError:
return Images.placeholders.connectionError
case .coursePassed:
return Images.placeholders.coursePassed
default:
return nil
}
}

func placeholderButtonTitle() -> String? {
switch state {
case .connectionError:
return NSLocalizedString("TryAgain", comment: "")
default:
return nil
}
}

func placeholderDescription() -> String? {
switch state {
case .connectionError:
return nil
case .coursePassed:
return NSLocalizedString("NoRecommendations", comment: "")
default:
return nil
}
}

func placeholderStyle() -> PlaceholderStyle {
var style = PlaceholderStyle()
style.button.textColor = UIColor.mainDark
return style
}

func placeholderTitle() -> String? {
switch state {
case .connectionError:
return NSLocalizedString("ConnectionErrorText", comment: "")
case .coursePassed:
return NSLocalizedString("CoursePassed", comment: "")
default:
return nil
}
}
}

extension CardsStepsViewController: PlaceholderViewDelegate {
func placeholderButtonDidPress() {
presenter?.tryAgain()
}
}

extension CardsStepsViewController: CardStepDelegate {
func stepSubmissionDidCorrect() {
AnalyticsReporter.reportEvent(AnalyticsEvents.Adaptive.Step.correctAnswer)
Expand Down
2 changes: 1 addition & 1 deletion Stepic/CertificatesStoryboard.storyboard
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@
<rect key="frame" x="0.0" y="0.0" width="375" height="667"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<subviews>
<tableView clipsSubviews="YES" contentMode="scaleToFill" alwaysBounceVertical="YES" dataMode="prototypes" style="grouped" separatorStyle="default" rowHeight="44" sectionHeaderHeight="18" sectionFooterHeight="18" translatesAutoresizingMaskIntoConstraints="NO" id="xIF-ha-DwF">
<tableView clipsSubviews="YES" contentMode="scaleToFill" alwaysBounceVertical="YES" dataMode="prototypes" style="grouped" separatorStyle="default" rowHeight="44" sectionHeaderHeight="18" sectionFooterHeight="18" translatesAutoresizingMaskIntoConstraints="NO" id="xIF-ha-DwF" customClass="StepikTableView" customModule="Stepic">
<rect key="frame" x="0.0" y="0.0" width="375" height="667"/>
<color key="backgroundColor" cocoaTouchSystemColor="groupTableViewBackgroundColor"/>
<viewLayoutGuide key="safeArea" id="pdh-3F-YzY"/>
Expand Down
160 changes: 25 additions & 135 deletions Stepic/CertificatesViewController.swift
Original file line number Diff line number Diff line change
Expand Up @@ -7,24 +7,17 @@
//

import Foundation
import DZNEmptyDataSet

enum CertificatesEmptyDatasetState {
case anonymous, error, empty, refreshing
}
class CertificatesViewController: UIViewController, CertificatesView, ControllerWithStepikPlaceholder {

var placeholderContainer: StepikPlaceholderControllerContainer = StepikPlaceholderControllerContainer()

class CertificatesViewController: UIViewController, CertificatesView {
@IBOutlet weak var tableView: UITableView!
@IBOutlet weak var tableView: StepikTableView!

var presenter: CertificatesPresenter?

var certificates: [CertificateViewData] = []
var showNextPageFooter: Bool = false
var emptyState: CertificatesEmptyDatasetState = .empty {
didSet {
tableView.reloadEmptyDataSet()
}
}

let refreshControl = UIRefreshControl()

Expand All @@ -33,14 +26,26 @@ class CertificatesViewController: UIViewController, CertificatesView {
tableView.delegate = self
tableView.dataSource = self

tableView.emptySetPlaceholder = StepikPlaceholder(.emptyCertificates) { [weak self] in
self?.tabBarController?.selectedIndex = 1
}
tableView.loadingPlaceholder = StepikPlaceholder(.emptyCertificatesLoading)

registerPlaceholder(placeholder: StepikPlaceholder(.login, action: { [weak self] in
guard let strongSelf = self else {
return
}
RoutingManager.auth.routeFrom(controller: strongSelf, success: nil, cancel: nil)
}), for: .anonymous)
registerPlaceholder(placeholder: StepikPlaceholder(.noConnection, action: { [weak self] in
self?.presenter?.checkStatus()
}), for: .connectionError)

title = NSLocalizedString("Certificates", comment: "")

presenter = CertificatesPresenter(certificatesAPI: ApiDataDownloader.certificates, coursesAPI: ApiDataDownloader.courses, presentationContainer: PresentationContainer.certificates, view: self)
presenter?.view = self

tableView.emptyDataSetSource = self
tableView.emptyDataSetDelegate = self

tableView.register(UINib(nibName: "CertificateTableViewCell", bundle: nil), forCellReuseIdentifier: "CertificateTableViewCell")

self.tableView.estimatedRowHeight = 161
Expand Down Expand Up @@ -125,21 +130,23 @@ class CertificatesViewController: UIViewController, CertificatesView {

func displayAnonymous() {
refreshControl.endRefreshing()
emptyState = .anonymous
showPlaceholder(for: .anonymous)
}

func displayError() {
refreshControl.endRefreshing()
emptyState = .error
showPlaceholder(for: .connectionError)
}

func displayEmpty() {
refreshControl.endRefreshing()
emptyState = .empty
tableView.reloadData()
self.isPlaceholderShown = false
}

func displayRefreshing() {
emptyState = .refreshing
tableView.showLoadingPlaceholder()
self.isPlaceholderShown = false
}

func displayLoadNextPageError() {
Expand Down Expand Up @@ -172,30 +179,6 @@ class CertificatesViewController: UIViewController, CertificatesView {
}
}

extension CertificatesViewController : DZNEmptyDataSetDelegate {
func emptyDataSetShouldAllowScroll(_ scrollView: UIScrollView!) -> Bool {
return true
}

func emptyDataSetDidTapButton(_ scrollView: UIScrollView!) {
switch emptyState {
case .anonymous:
RoutingManager.auth.routeFrom(controller: self, success: nil, cancel: nil)
break

case .empty:
self.tabBarController?.selectedIndex = 1
break

case .error:
break

case .refreshing:
break
}
}
}

extension CertificatesViewController : UITableViewDelegate {

func tableView(_ tableView: UITableView, viewForFooterInSection section: Int) -> UIView? {
Expand Down Expand Up @@ -272,96 +255,3 @@ extension CertificatesViewController : UITableViewDataSource {
return cell
}
}

extension CertificatesViewController : DZNEmptyDataSetSource {
func image(forEmptyDataSet scrollView: UIScrollView!) -> UIImage! {
//Add correct placeholders here
switch emptyState {
case .anonymous:
return Images.placeholders.anonymous
case .empty:
return Images.placeholders.certificates
case .error:
return Images.placeholders.connectionError
case .refreshing:
return Images.placeholders.certificates
}
}

func title(forEmptyDataSet scrollView: UIScrollView!) -> NSAttributedString! {
var text: String = ""

switch emptyState {
case .anonymous:
text = NSLocalizedString("AnonymousCertificatesTitle", comment: "")
case .empty:
text = NSLocalizedString("EmptyCertificatesTitle", comment: "")
break
case .error:
text = NSLocalizedString("ConnectionErrorTitle", comment: "")
break
case .refreshing:
text = NSLocalizedString("Refreshing", comment: "")
break
}

let attributes = [NSAttributedStringKey.font: UIFont.boldSystemFont(ofSize: 18.0),
NSAttributedStringKey.foregroundColor: UIColor.darkGray]

return NSAttributedString(string: text, attributes: attributes)
}

func description(forEmptyDataSet scrollView: UIScrollView!) -> NSAttributedString! {
var text: String = ""

switch emptyState {
case .anonymous:
text = NSLocalizedString("SignInToHaveCertificates", comment: "")
break
case .empty:
text = NSLocalizedString("EmptyCertificatesDescription", comment: "")
break
case .error:
text = NSLocalizedString("ConnectionErrorPullToRefresh", comment: "")
break
case .refreshing:
text = NSLocalizedString("RefreshingDescription", comment: "")
break
}

let paragraph = NSMutableParagraphStyle()
paragraph.lineBreakMode = .byWordWrapping
paragraph.alignment = .center

let attributes = [NSAttributedStringKey.font: UIFont.systemFont(ofSize: 14.0),
NSAttributedStringKey.foregroundColor: UIColor.lightGray,
NSAttributedStringKey.paragraphStyle: paragraph]

return NSAttributedString(string: text, attributes: attributes)
}

func buttonTitle(forEmptyDataSet scrollView: UIScrollView!, for state: UIControlState) -> NSAttributedString! {
var text: String = ""
switch emptyState {
case .anonymous:
text = NSLocalizedString("SignIn", comment: "")
case .empty:
text = NSLocalizedString("ChooseCourse", comment: "")
case .error:
text = ""
break
case .refreshing:
text = ""
break
}

let attributes = [NSAttributedStringKey.font: UIFont.systemFont(ofSize: 16.0),
NSAttributedStringKey.foregroundColor: UIColor.mainDark]

return NSAttributedString(string: text, attributes: attributes)
}

func backgroundColor(forEmptyDataSet scrollView: UIScrollView!) -> UIColor! {
return UIColor.groupTableViewBackground
}
}
Loading