Skip to content

Commit

Permalink
Merge pull request #1109 from StepicOrg/release/1.208
Browse files Browse the repository at this point in the history
Release 1.208
  • Loading branch information
ivan-magda authored Feb 3, 2022
2 parents 7eedb86 + 139c461 commit 2f201df
Show file tree
Hide file tree
Showing 34 changed files with 850 additions and 109 deletions.
2 changes: 1 addition & 1 deletion Gemfile
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
source "https://rubygems.org"
ruby "2.6.5"

gem "fastlane", "2.201.2"
gem "fastlane", "2.203.0"
gem "cocoapods", "1.11.2"
gem "generamba", "1.5.0"

Expand Down
12 changes: 6 additions & 6 deletions Gemfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ GEM
artifactory (3.0.15)
atomos (0.1.3)
aws-eventstream (1.2.0)
aws-partitions (1.549.0)
aws-partitions (1.551.0)
aws-sdk-core (3.125.5)
aws-eventstream (~> 1, >= 1.0.2)
aws-partitions (~> 1, >= 1.525.0)
Expand Down Expand Up @@ -116,7 +116,7 @@ GEM
faraday_middleware (1.2.0)
faraday (~> 1.0)
fastimage (2.2.6)
fastlane (2.201.2)
fastlane (2.203.0)
CFPropertyList (>= 2.3, < 4.0.0)
addressable (>= 2.8, < 3.0.0)
artifactory (~> 3.0)
Expand Down Expand Up @@ -168,7 +168,7 @@ GEM
xcodeproj (>= 1.5.0, < 2.0.0)
gh_inspector (1.1.3)
git (1.2.9.1)
google-apis-androidpublisher_v3 (0.15.0)
google-apis-androidpublisher_v3 (0.16.0)
google-apis-core (>= 0.4, < 2.a)
google-apis-core (0.4.2)
addressable (~> 2.5, >= 2.5.1)
Expand Down Expand Up @@ -210,7 +210,7 @@ GEM
http-cookie (1.0.4)
domain_name (~> 0.5)
httpclient (2.8.3)
i18n (1.8.11)
i18n (1.9.1)
concurrent-ruby (~> 1.0)
jmespath (1.5.0)
json (2.6.1)
Expand Down Expand Up @@ -280,14 +280,14 @@ GEM
rouge (~> 2.0.7)
xcpretty-travis-formatter (1.0.1)
xcpretty (~> 0.2, >= 0.0.7)
zeitwerk (2.5.3)
zeitwerk (2.5.4)

PLATFORMS
ruby

DEPENDENCIES
cocoapods (= 1.11.2)
fastlane (= 2.201.2)
fastlane (= 2.203.0)
fastlane-plugin-firebase_app_distribution
generamba (= 1.5.0)

Expand Down
60 changes: 46 additions & 14 deletions Stepic.xcodeproj/project.pbxproj

Large diffs are not rendered by default.

4 changes: 2 additions & 2 deletions Stepic/Info-Develop.plist
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
<key>CFBundlePackageType</key>
<string>APPL</string>
<key>CFBundleShortVersionString</key>
<string>1.207-develop</string>
<string>1.208-develop</string>
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleURLTypes</key>
Expand Down Expand Up @@ -62,7 +62,7 @@
</dict>
</array>
<key>CFBundleVersion</key>
<string>406</string>
<string>409</string>
<key>FacebookAppID</key>
<string>171127739724012</string>
<key>FacebookDisplayName</key>
Expand Down
4 changes: 2 additions & 2 deletions Stepic/Info-Production.plist
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
<key>CFBundlePackageType</key>
<string>APPL</string>
<key>CFBundleShortVersionString</key>
<string>1.207</string>
<string>1.208</string>
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleURLTypes</key>
Expand Down Expand Up @@ -62,7 +62,7 @@
</dict>
</array>
<key>CFBundleVersion</key>
<string>406</string>
<string>409</string>
<key>FacebookAppID</key>
<string>171127739724012</string>
<key>FacebookDisplayName</key>
Expand Down
4 changes: 2 additions & 2 deletions Stepic/Info-Release.plist
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
<key>CFBundlePackageType</key>
<string>APPL</string>
<key>CFBundleShortVersionString</key>
<string>1.207-release</string>
<string>1.208-release</string>
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleURLTypes</key>
Expand Down Expand Up @@ -62,7 +62,7 @@
</dict>
</array>
<key>CFBundleVersion</key>
<string>406</string>
<string>409</string>
<key>FacebookAppID</key>
<string>171127739724012</string>
<key>FacebookDisplayName</key>
Expand Down
6 changes: 5 additions & 1 deletion Stepic/Sources/Helpers/FormatterHelper.swift
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,11 @@ enum FormatterHelper {
/// Format Progress's score value with 2 decimal points if has decimals; 0.123456 -> "0.12", 1.0 -> "1"
static func progressScore(_ score: Float) -> String {
let hasDecimals = score.truncatingRemainder(dividingBy: 1) != 0
return hasDecimals ? String(format: "%.2f", score) : "\(Int(score))"
if hasDecimals {
let result = String(format: "%.2f", score)
return result.last == "0" ? String(result.dropLast()) : result
}
return "\(Int(score))"
}

/// Format Submission's score with 2 decimal points if has decimals; 0.75 -> "0.75", 1.0 -> "1"
Expand Down
24 changes: 18 additions & 6 deletions Stepic/Sources/Modules/CourseList/CourseListPresenter.swift
Original file line number Diff line number Diff line change
Expand Up @@ -82,13 +82,25 @@ final class CourseListPresenter: CourseListPresenterProtocol {
return viewModels
}

private func makeProgressViewModel(progress: Progress) -> CourseWidgetProgressViewModel {
var normalizedPercent = progress.percentPassed
normalizedPercent.round(.up)
private func makeProgressViewModel(progress: Progress, course: Course) -> CourseWidgetProgressViewModel {
let progressValue = progress.cost > 0
? progress.score / Float(progress.cost)
: 1
let certificateRegularThreshold = (course.certificateRegularThreshold ?? 0) > 0
? course.certificateRegularThreshold
: nil
let certificateDistinctionThreshold = (course.certificateDistinctionThreshold ?? 0) > 0
? course.certificateDistinctionThreshold
: nil

return CourseWidgetProgressViewModel(
progress: normalizedPercent / 100.0,
progressLabelText: "\(FormatterHelper.progressScore(progress.score))/\(progress.cost)"
score: progress.score,
cost: progress.cost,
progress: progressValue,
progressLabelText: "\(FormatterHelper.progressScore(progress.score))/\(progress.cost)",
isWithCertificate: course.isWithCertificate,
certificateRegularThreshold: certificateRegularThreshold,
certificateDistinctionThreshold: certificateDistinctionThreshold
)
}

Expand All @@ -112,7 +124,7 @@ final class CourseListPresenter: CourseListPresenterProtocol {

var progressViewModel: CourseWidgetProgressViewModel?
if let progress = course.progress {
progressViewModel = self.makeProgressViewModel(progress: progress)
progressViewModel = self.makeProgressViewModel(progress: progress, course: course)
}

var userCourseViewModel: CourseWidgetUserCourseViewModel?
Expand Down
7 changes: 7 additions & 0 deletions Stepic/Sources/Modules/CourseList/CourseWidgetViewModel.swift
Original file line number Diff line number Diff line change
@@ -1,8 +1,15 @@
import UIKit

struct CourseWidgetProgressViewModel {
let score: Float
let cost: Int

let progress: Float
let progressLabelText: String

let isWithCertificate: Bool
let certificateRegularThreshold: Int?
let certificateDistinctionThreshold: Int?
}

struct CourseWidgetUserCourseViewModel {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,11 @@ class CourseListCollectionViewCell: UICollectionViewCell, Reusable {
).cgPath
}

override func prepareForReuse() {
super.prepareForReuse()
self.widgetView.prepareForReuse()
}

func configure(viewModel: CourseWidgetViewModel) {
self.widgetView.configure(viewModel: viewModel)
self.configurationViewModel = viewModel
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import Foundation
import UIKit

enum CourseListColorMode {
case light
Expand Down Expand Up @@ -88,6 +88,35 @@ extension CourseListColorMode {
}
}

var courseWidgetProgressViewAppearance: CourseWidgetProgressView.Appearance {
let progressTextLabelTextColor = UIColor.stepikMaterialSecondaryText
let progressBarTrackTintColor = UIColor.onSurface.withAlphaComponent(0.12)

var appearance = CourseWidgetProgressView.Appearance(
progressTextLabelAppearance: .init(
maxLinesCount: 1,
font: Typography.caption1Font,
textColor: progressTextLabelTextColor
),
progressBarViewAppearance: .init(trackTintColor: progressBarTrackTintColor)
)

switch self {
case .light, .grouped:
return appearance
case .dark:
appearance.progressTextLabelAppearance.textColor = .dynamic(
light: .white.withAlphaComponent(0.6),
dark: progressTextLabelTextColor
)
appearance.progressBarViewAppearance.trackTintColor = .dynamic(
light: .white.withAlphaComponent(0.12),
dark: progressBarTrackTintColor
)
return appearance
}
}

var courseWidgetTitleLabelAppearance: CourseWidgetLabel.Appearance {
var appearance = CourseWidgetLabel.Appearance(
maxLinesCount: 3,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ extension CourseListView {
let horizontalLayoutMinimumItemWidth: CGFloat = 276

let smallVerticalLayoutMinimumItemWidth: CGFloat = 168
let smallHorizontalLayoutMinimumItemWidth: CGFloat = 156
let smallHorizontalLayoutMinimumItemWidth: CGFloat = 154

let lightModeBackgroundColor = UIColor.stepikBackground
let darkModeBackgroundColor = UIColor.dynamic(light: .stepikAccent, dark: .stepikSecondaryBackground)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import SnapKit
import UIKit

protocol CourseWidgetViewProtocol: UIView {
func prepareForReuse()
func configure(viewModel: CourseWidgetViewModel)
}

Expand All @@ -18,6 +19,8 @@ extension CourseWidgetView {
let statsViewHeight: CGFloat = 17
let statsViewInsets = LayoutInsets(top: 8)

let progressViewInsets = LayoutInsets(top: 8, right: 16)

let summaryLabelInsets = LayoutInsets(top: 12, left: 16, bottom: 16, right: 16)
let priceViewInsets = LayoutInsets(top: 12, bottom: 17)

Expand Down Expand Up @@ -48,6 +51,12 @@ final class CourseWidgetView: UIView, CourseWidgetViewProtocol {
appearance: self.colorMode.courseWidgetStatsViewAppearance
)

private lazy var progressView: CourseWidgetProgressView = {
let view = CourseWidgetProgressView(appearance: self.colorMode.courseWidgetProgressViewAppearance)
view.isHidden = true
return view
}()

private lazy var separatorView: UIView = {
let view = UIView()
view.backgroundColor = self.colorMode.courseWidgetBorderColor
Expand Down Expand Up @@ -98,6 +107,30 @@ final class CourseWidgetView: UIView, CourseWidgetViewProtocol {
fatalError("init(coder:) has not been implemented")
}

// MARK: Public API

func prepareForReuse() {
self.titleLabel.text = nil

self.coverView.coverImageURL = nil
self.coverView.shouldShowAdaptiveMark = false

self.summaryLabel.attributedText = nil
self.summaryLabel.isHidden = false

self.separatorView.isHidden = true
self.continueLearningButton.isHidden = true

self.statsView.learnersLabelText = nil
self.statsView.certificatesLabelText = nil
self.statsView.ratingLabelText = nil
self.statsView.isArchived = false

self.updateProgressView(viewModel: nil)
self.updatePriceView(viewModel: nil)
self.updateBadgeImageView(viewModel: nil)
}

func configure(viewModel: CourseWidgetViewModel) {
self.titleLabel.text = viewModel.title
self.coverView.coverImageURL = viewModel.coverImageURL
Expand All @@ -114,14 +147,23 @@ final class CourseWidgetView: UIView, CourseWidgetViewProtocol {

let isArchived = viewModel.userCourse?.isArchived ?? false
self.statsView.isArchived = isArchived
self.statsView.progress = isArchived ? nil : viewModel.progress

self.updateProgressView(viewModel: isArchived ? nil : viewModel.progress)
self.updatePriceView(viewModel: viewModel.price)
self.updateBadgeImageView(viewModel: viewModel)
}

func updateProgress(viewModel: CourseWidgetProgressViewModel) {
self.statsView.progress = viewModel
self.updateProgressView(viewModel: viewModel)
}

// MARK: Private API

private func updateProgressView(viewModel: CourseWidgetProgressViewModel?) {
if let viewModel = viewModel {
self.progressView.configure(viewModel: viewModel)
}
self.progressView.isHidden = viewModel == nil
}

private func updatePriceView(viewModel: CourseWidgetPriceViewModel?) {
Expand All @@ -138,8 +180,12 @@ final class CourseWidgetView: UIView, CourseWidgetViewProtocol {
}
}

private func updateBadgeImageView(viewModel: CourseWidgetViewModel) {
private func updateBadgeImageView(viewModel: CourseWidgetViewModel?) {
let badgeImage: UIImage? = {
guard let viewModel = viewModel else {
return nil
}

if viewModel.isWishlistAvailable {
let imageName = viewModel.isWishlisted ? "wishlist-like-filled" : "wishlist-like"
return UIImage(named: imageName)?.withRenderingMode(.alwaysTemplate)
Expand All @@ -159,8 +205,6 @@ final class CourseWidgetView: UIView, CourseWidgetViewProtocol {
)
}

// MARK: Private API

@objc
private func continueLearningButtonClicked() {
self.onContinueLearningButtonClick?()
Expand All @@ -177,6 +221,7 @@ extension CourseWidgetView: ProgrammaticallyInitializableViewProtocol {
self.addSubview(self.titleLabel)
self.addSubview(self.badgeImageView)
self.addSubview(self.statsView)
self.addSubview(self.progressView)
self.addSubview(self.summaryLabel)
self.addSubview(self.priceView)
self.addSubview(self.continueLearningButton)
Expand Down Expand Up @@ -238,6 +283,21 @@ extension CourseWidgetView: ProgrammaticallyInitializableViewProtocol {
.equalTo(self.appearance.statsViewHeight)
}

self.progressView.translatesAutoresizingMaskIntoConstraints = false
self.progressView.snp.makeConstraints { make in
make.top
.greaterThanOrEqualTo(self.titleLabel.snp.bottom)
.offset(self.appearance.progressViewInsets.top)
.priority(.low)
make.leading
.equalTo(self.titleLabel.snp.leading)
make.bottom
.equalTo(self.coverView.snp.bottom)
make.trailing
.equalToSuperview()
.offset(-self.appearance.progressViewInsets.right)
}

self.summaryLabel.translatesAutoresizingMaskIntoConstraints = false
self.summaryLabel.snp.makeConstraints { make in
make.top
Expand Down
Loading

0 comments on commit 2f201df

Please sign in to comment.