Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
21 changes: 19 additions & 2 deletions Stepic/Sources/Helpers/FormatterHelper.swift
Original file line number Diff line number Diff line change
Expand Up @@ -37,9 +37,9 @@ enum FormatterHelper {
}

/// Format hours count with localized and pluralized suffix; 1 -> "1 hour", 5 -> "5 hours"
static func hoursInSeconds(_ seconds: TimeInterval) -> String {
static func hoursInSeconds(_ seconds: TimeInterval, roundingRule: FloatingPointRoundingRule = .up) -> String {
let hour = 3600.0
let hours = Int(ceil(seconds / hour))
let hours = Int((seconds / hour).rounded(roundingRule))

let pluralizedHoursString = StringHelper.pluralize(
number: hours,
Expand All @@ -53,6 +53,23 @@ enum FormatterHelper {
return "\(hours) \(pluralizedHoursString)"
}

/// Format minutes count with localized and pluralized suffix; 1 -> "1 minute", 5 -> "5 minutes"
static func minutesInSeconds(_ seconds: TimeInterval, roundingRule: FloatingPointRoundingRule = .up) -> String {
let minute = 60.0
let minutes = Int((seconds / minute).rounded(roundingRule))

let pluralizedMinutesString = StringHelper.pluralize(
number: minutes,
forms: [
NSLocalizedString("minutes1", comment: ""),
NSLocalizedString("minutes234", comment: ""),
NSLocalizedString("minutes567890", comment: "")
]
)

return "\(minutes) \(pluralizedMinutesString)"
}

/// Format date with full month and year; "18 October 2018 00:00"
static func dateStringWithFullMonthAndYear(_ date: Date) -> String {
let dateFormatter = DateFormatter()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -189,6 +189,20 @@ final class CourseInfoTabSyllabusPresenter: CourseInfoTabSyllabusPresenterProtoc
return "\(progress.numberOfStepsPassed)/\(progress.numberOfSteps)"
}()

let timeToCompleteLabelText: String? = {
guard let timeToComplete = unit.lesson?.timeToComplete else {
return nil
}

if timeToComplete < 60 {
return nil
} else if case 60..<3600 = timeToComplete {
return FormatterHelper.minutesInSeconds(timeToComplete, roundingRule: .down)
} else {
return FormatterHelper.hoursInSeconds(timeToComplete, roundingRule: .down)
}
}()

let viewModel = CourseInfoTabSyllabusUnitViewModel(
uniqueIdentifier: uid,
title: "\(sectionIndex + 1).\(unitIndex + 1) \(lesson.title)",
Expand All @@ -197,6 +211,7 @@ final class CourseInfoTabSyllabusPresenter: CourseInfoTabSyllabusPresenterProtoc
likesCount: likesCount == 0 ? nil : likesCount,
learnersLabelText: FormatterHelper.longNumber(lesson.passedBy),
progressLabelText: progressLabelText,
timeToCompleteLabelText: timeToCompleteLabelText,
downloadState: isAvailable ? downloadState : .notAvailable,
isSelectable: isAvailable
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ struct CourseInfoTabSyllabusUnitViewModel: UniqueIdentifiable {
let likesCount: Int?
let learnersLabelText: String
let progressLabelText: String?
let timeToCompleteLabelText: String?

var downloadState: CourseInfoTabSyllabus.DownloadState
let isSelectable: Bool
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,17 @@ final class CourseInfoTabSyllabusCellStatsView: UIView {
return view
}()

private lazy var timeToCompleteView: CourseWidgetStatsItemView = {
var appearance = CourseWidgetStatsItemView.Appearance()
// There is no icon in this view now
appearance.iconSpacing = 0
appearance.imageViewSize = .zero
appearance.textColor = self.appearance.itemTextColor
appearance.font = self.appearance.itemTextFont
let view = CourseWidgetStatsItemView(appearance: appearance)
return view
}()

var learnersLabelText: String? {
didSet {
self.learnersView.isHidden = self.learnersLabelText?.isEmpty ?? true
Expand Down Expand Up @@ -91,6 +102,13 @@ final class CourseInfoTabSyllabusCellStatsView: UIView {
}
}

var timeToCompleteLabelText: String? {
didSet {
self.timeToCompleteView.isHidden = self.timeToCompleteLabelText?.isEmpty ?? true
self.timeToCompleteView.text = self.timeToCompleteLabelText
}
}

init(frame: CGRect = .zero, appearance: Appearance = Appearance()) {
self.appearance = appearance
super.init(frame: frame)
Expand All @@ -117,6 +135,7 @@ extension CourseInfoTabSyllabusCellStatsView: ProgrammaticallyInitializableViewP
self.itemsStackView.addArrangedSubview(self.learnersView)
self.itemsStackView.addArrangedSubview(self.likesView)
self.itemsStackView.addArrangedSubview(self.progressView)
self.itemsStackView.addArrangedSubview(self.timeToCompleteView)
}

func makeConstraints() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,7 @@ final class CourseInfoTabSyllabusCellView: UIView {

self.statsView.progressLabelText = viewModel.progressLabelText
self.statsView.learnersLabelText = viewModel.learnersLabelText
self.statsView.timeToCompleteLabelText = viewModel.timeToCompleteLabelText
self.statsView.likesCount = viewModel.likesCount

self.updateDownloadState(newState: viewModel.downloadState)
Expand Down
3 changes: 3 additions & 0 deletions Stepic/en.lproj/Localizable.strings
Original file line number Diff line number Diff line change
Expand Up @@ -156,6 +156,9 @@ days567890 = "days";
hours1 = "hour";
hours234 = "hours";
hours567890 = "hours";
minutes1 = "minute";
minutes234 = "minutes";
minutes567890 = "minutes";
points1 = "point";
points234 = "points";
points567890 = "points";
Expand Down
3 changes: 3 additions & 0 deletions Stepic/ru.lproj/Localizable.strings
Original file line number Diff line number Diff line change
Expand Up @@ -156,6 +156,9 @@ days567890 = "дней";
hours1 = "час";
hours234 = "часа";
hours567890 = "часов";
minutes1 = "минута";
minutes234 = "минуты";
minutes567890 = "минут";
points1 = "балл";
points234 = "балла";
points567890 = "баллов";
Expand Down