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
Original file line number Diff line number Diff line change
Expand Up @@ -255,14 +255,16 @@ final class NewLessonViewController: TabmanViewController, ControllerWithStepikP
// Can navigate to previous unit from current step
let canNavigateToPreviousUnit = index == 0 && hasNavigationToPreviousUnit
let canNavigateToNextUnit = (index == self.stepModulesInputs.count - 1) && hasNavigationToNextUnit
let canNavigateToNextStep = index != self.stepModulesInputs.count - 1

guard let input = self.stepModulesInputs[safe: index].flatMap({ $0 }) else {
return
}

input.updateStepNavigation(
canNavigateToPreviousUnit: canNavigateToPreviousUnit,
canNavigateNextUnit: canNavigateToNextUnit
canNavigateToNextUnit: canNavigateToNextUnit,
canNavigateToNextStep: canNavigateToNextStep
)
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import Foundation

protocol NewStepInputProtocol: class {
func updateStepNavigation(canNavigateToPreviousUnit: Bool, canNavigateNextUnit: Bool)
func updateStepNavigation(canNavigateToPreviousUnit: Bool, canNavigateToNextUnit: Bool, canNavigateToNextStep: Bool)
}
9 changes: 8 additions & 1 deletion Stepic/Sources/Modules/NewStep/NewStepDataFlow.swift
Original file line number Diff line number Diff line change
Expand Up @@ -19,11 +19,13 @@ enum NewStep {
struct Response {
let canNavigateToPreviousUnit: Bool
let canNavigateToNextUnit: Bool
let canNavigateToNextStep: Bool
}

struct ViewModel {
let canNavigateToPreviousUnit: Bool
let canNavigateToNextUnit: Bool
let canNavigateToNextStep: Bool
}
}

Expand Down Expand Up @@ -51,8 +53,13 @@ enum NewStep {

/// Handle navigation inside lesson
enum StepNavigationRequest {
enum Direction {
case index(Int)
case next
}

struct Request {
let index: Int
let direction: Direction
}
}

Expand Down
25 changes: 22 additions & 3 deletions Stepic/Sources/Modules/NewStep/NewStepInteractor.swift
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,9 @@ final class NewStepInteractor: NewStepInteractorProtocol {
private let stepID: Step.IdType
private var didAnalyticsSend = false

/// Current step index inside lesson.
private var currentStepIndex: Int?

init(
stepID: Step.IdType,
presenter: NewStepPresenterProtocol,
Expand All @@ -35,6 +38,8 @@ final class NewStepInteractor: NewStepInteractorProtocol {
throw Error.fetchFailed
}

self.currentStepIndex = step.position - 1

DispatchQueue.main.async { [weak self] in
self?.presenter.presentStep(response: .init(result: .success(step)))
}
Expand Down Expand Up @@ -79,7 +84,16 @@ final class NewStepInteractor: NewStepInteractorProtocol {
}

func doStepNavigationRequest(request: NewStep.StepNavigationRequest.Request) {
self.moduleOutput?.handleStepNavigation(to: request.index - 1)
switch request.direction {
case .index(let stepIndex):
self.moduleOutput?.handleStepNavigation(to: stepIndex)
case .next:
guard let currentStepIndex = self.currentStepIndex else {
return
}

self.moduleOutput?.handleStepNavigation(to: currentStepIndex + 1)
}
}

func doLessonNavigationRequest(request: NewStep.LessonNavigationRequest.Request) {
Expand All @@ -105,11 +119,16 @@ final class NewStepInteractor: NewStepInteractorProtocol {
}

extension NewStepInteractor: NewStepInputProtocol {
func updateStepNavigation(canNavigateToPreviousUnit: Bool, canNavigateNextUnit: Bool) {
func updateStepNavigation(
canNavigateToPreviousUnit: Bool,
canNavigateToNextUnit: Bool,
canNavigateToNextStep: Bool
) {
self.presenter.presentControlsUpdate(
response: .init(
canNavigateToPreviousUnit: canNavigateToPreviousUnit,
canNavigateToNextUnit: canNavigateNextUnit
canNavigateToNextUnit: canNavigateToNextUnit,
canNavigateToNextStep: canNavigateToNextStep
)
)
}
Expand Down
3 changes: 2 additions & 1 deletion Stepic/Sources/Modules/NewStep/NewStepPresenter.swift
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,8 @@ final class NewStepPresenter: NewStepPresenterProtocol {
func presentControlsUpdate(response: NewStep.ControlsUpdate.Response) {
let viewModel = NewStep.ControlsUpdate.ViewModel(
canNavigateToPreviousUnit: response.canNavigateToPreviousUnit,
canNavigateToNextUnit: response.canNavigateToNextUnit
canNavigateToNextUnit: response.canNavigateToNextUnit,
canNavigateToNextStep: response.canNavigateToNextStep
)

self.viewController?.displayControlsUpdate(viewModel: viewModel)
Expand Down
15 changes: 13 additions & 2 deletions Stepic/Sources/Modules/NewStep/NewStepViewController.swift
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,8 @@ final class NewStepViewController: UIViewController, ControllerWithStepikPlaceho

private var isFirstAppearance = true

private var canNavigateToNextStep = false

init(interactor: NewStepInteractorProtocol) {
self.interactor = interactor
self.state = .loading
Expand Down Expand Up @@ -168,7 +170,11 @@ final class NewStepViewController: UIViewController, ControllerWithStepikPlaceho
let quizController: UIViewController? = {
switch quizType {
case .string, .number, .math, .freeAnswer, .choice, .code, .sorting, .matching:
let assembly = BaseQuizAssembly(step: viewModel.step, output: self)
let assembly = BaseQuizAssembly(
step: viewModel.step,
hasNextStep: self.canNavigateToNextStep,
output: self
)
return assembly.makeModule()
default:
return initQuizController(type: quizType, step: viewModel.step)
Expand Down Expand Up @@ -197,6 +203,7 @@ extension NewStepViewController: NewStepViewControllerProtocol {
hasPreviousButton: viewModel.canNavigateToPreviousUnit,
hasNextButton: viewModel.canNavigateToNextUnit
)
self.canNavigateToNextStep = viewModel.canNavigateToNextStep
}
}

Expand Down Expand Up @@ -251,7 +258,7 @@ extension NewStepViewController: NewStepViewDelegate {
if index + 1 < components.count {
let urlStepIndexString = components[index + 1]
if let urlStepIndex = Int(urlStepIndexString) {
self.interactor.doStepNavigationRequest(request: .init(index: urlStepIndex))
self.interactor.doStepNavigationRequest(request: .init(direction: .index(urlStepIndex - 1)))
return
}
}
Expand Down Expand Up @@ -287,4 +294,8 @@ extension NewStepViewController: BaseQuizOutputProtocol {
func handleCorrectSubmission() {
self.interactor.doStepDoneRequest(request: .init())
}

func handleNextStepNavigation() {
self.interactor.doStepNavigationRequest(request: .init(direction: .next))
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,12 @@ import UIKit
final class BaseQuizAssembly: Assembly {
private weak var moduleOutput: BaseQuizOutputProtocol?
private let step: Step
private let hasNextStep: Bool

init(step: Step, output: BaseQuizOutputProtocol? = nil) {
init(step: Step, hasNextStep: Bool = false, output: BaseQuizOutputProtocol? = nil) {
self.moduleOutput = output
self.step = step
self.hasNextStep = hasNextStep
}

func makeModule() -> UIViewController {
Expand All @@ -18,6 +20,7 @@ final class BaseQuizAssembly: Assembly {
let presenter = BaseQuizPresenter()
let interactor = BaseQuizInteractor(
step: self.step,
hasNextStep: self.hasNextStep,
presenter: presenter,
provider: provider,
notificationSuggestionManager: NotificationSuggestionManager(),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ enum BaseQuiz {
let submission: Submission?
let cachedReply: Reply?
let submissionsCount: Int
let hasNextStep: Bool
}

struct Request {
Expand Down Expand Up @@ -56,6 +57,11 @@ enum BaseQuiz {
}
}

/// Navigate to next step inside lesson
enum NextStepNavigation {
struct Request { }
}

enum ViewControllerState {
case loading
case result(data: BaseQuizViewModel)
Expand Down
11 changes: 10 additions & 1 deletion Stepic/Sources/Modules/Quizzes/BaseQuiz/BaseQuizInteractor.swift
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ protocol BaseQuizInteractorProtocol {
func doSubmissionLoad(request: BaseQuiz.SubmissionLoad.Request)
func doSubmissionSubmit(request: BaseQuiz.SubmissionSubmit.Request)
func doReplyCache(request: BaseQuiz.ReplyCache.Request)
func doNextStepNavigationRequest(request: BaseQuiz.NextStepNavigation.Request)
}

final class BaseQuizInteractor: BaseQuizInteractorProtocol {
Expand All @@ -21,19 +22,22 @@ final class BaseQuizInteractor: BaseQuizInteractorProtocol {
private let rateAppManager: RateAppManager

let step: Step
private let hasNextStep: Bool

private var submissionsCount = 0
private var currentAttempt: Attempt?

init(
step: Step,
hasNextStep: Bool,
presenter: BaseQuizPresenterProtocol,
provider: BaseQuizProviderProtocol,
notificationSuggestionManager: NotificationSuggestionManager,
rateAppManager: RateAppManager,
userService: UserAccountServiceProtocol
) {
self.step = step
self.hasNextStep = hasNextStep
self.presenter = presenter
self.provider = provider
self.userService = userService
Expand Down Expand Up @@ -147,6 +151,10 @@ final class BaseQuizInteractor: BaseQuizInteractorProtocol {
}
}

func doNextStepNavigationRequest(request: BaseQuiz.NextStepNavigation.Request) {
self.moduleOutput?.handleNextStepNavigation()
}

// MARK: - Private API

@discardableResult
Expand Down Expand Up @@ -186,7 +194,8 @@ final class BaseQuizInteractor: BaseQuizInteractorProtocol {
attempt: attempt,
submission: submission,
cachedReply: cachedReply,
submissionsCount: self.submissionsCount
submissionsCount: self.submissionsCount,
hasNextStep: self.hasNextStep
)

self.presenter.presentSubmission(response: .init(result: .success(response)))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,5 @@ import Foundation

protocol BaseQuizOutputProtocol: class {
func handleCorrectSubmission()
func handleNextStepNavigation()
}
12 changes: 9 additions & 3 deletions Stepic/Sources/Modules/Quizzes/BaseQuiz/BaseQuizPresenter.swift
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,8 @@ final class BaseQuizPresenter: BaseQuizPresenterProtocol {
submission: data.submission,
attempt: data.attempt,
cachedReply: data.cachedReply,
submissionsCount: data.submissionsCount
submissionsCount: data.submissionsCount,
hasNextStep: data.hasNextStep
)
self.viewController?.displaySubmission(viewModel: .init(state: .result(data: viewModel)))
}
Expand All @@ -38,7 +39,8 @@ final class BaseQuizPresenter: BaseQuizPresenterProtocol {
submission: Submission?,
attempt: Attempt,
cachedReply: Reply?,
submissionsCount: Int
submissionsCount: Int,
hasNextStep: Bool
) -> BaseQuizViewModel {
let quizStatus: QuizStatus? = {
guard let submission = submission else {
Expand Down Expand Up @@ -90,6 +92,8 @@ final class BaseQuizPresenter: BaseQuizPresenterProtocol {

let isSubmitButtonDisabled = quizStatus == .evaluation || submissionsLeft == 0
let shouldPassPeerReview = quizStatus == .correct && step.hasReview
let canNavigateToNextStep = quizStatus == .correct && hasNextStep
let canRetry = quizStatus == .correct && !(submissionsLeft == 0)

let hintContent: String? = {
if let text = submission?.hint, !text.isEmpty {
Expand Down Expand Up @@ -122,7 +126,9 @@ final class BaseQuizPresenter: BaseQuizPresenterProtocol {
shouldPassPeerReview: shouldPassPeerReview,
stepURL: self.makeURL(for: step),
hintContent: hintContent,
codeDetails: codeDetails
codeDetails: codeDetails,
canNavigateToNextStep: canNavigateToNextStep,
canRetry: canRetry
)
}

Expand Down
Loading