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

Fix syllabus always displays units placeholders on continue learning #885

Merged
merged 2 commits into from
Feb 1, 2021
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
18 changes: 7 additions & 11 deletions Stepic/Legacy/TransitionRouters/LastStepRouter.swift
Original file line number Diff line number Diff line change
Expand Up @@ -46,13 +46,13 @@ final class LastStepRouter {

ApiDataDownloader.lastSteps.getObjectsByIds(
ids: [lastStepID],
updating: course.lastStep != nil ? [course.lastStep!] : []
).done { newLastSteps in
guard let newLastStep = newLastSteps.first else {
updating: [course.lastStep].flatMap { $0 }
).done { lastSteps in
guard let lastStep = lastSteps.first else {
throw LastStepError.multipleLastSteps
}

course.lastStep = newLastStep
course.lastStep = lastStep
CoreDataHelper.shared.save()
}.ensure {
self.navigate(
Expand Down Expand Up @@ -137,16 +137,12 @@ final class LastStepRouter {
}

func checkSectionAndNavigate(in unit: Unit) {
var sectionForUpdate: Section?
if let retrievedSections = try? Section.getSections(unit.sectionId),
let section = retrievedSections.first {
sectionForUpdate = section
}
let cachedSection = try? Section.getSections(unit.sectionId).first

// Always refresh section to prevent obsolete `isReachable` state
ApiDataDownloader.sections.retrieve(
ids: [unit.sectionId],
existing: sectionForUpdate == nil ? [] : [sectionForUpdate!],
existing: [cachedSection].flatMap { $0 },
refreshMode: .update,
success: { sections in
if let section = sections.first {
Expand All @@ -170,7 +166,7 @@ final class LastStepRouter {
print("last step router: error while loading section, error = \(error)")

// Fallback: use cached section
guard let section = sectionForUpdate else {
guard let section = cachedSection else {
return openSyllabus()
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ final class CourseInfoTabSyllabusInteractor: CourseInfoTabSyllabusInteractorProt
}
}
}
private var didLoadFromCache = false
private var connectionType: NetworkReachabilityConnectionType { self.networkReachabilityService.connectionType }
private var shouldCheckUseOfCellularDataForDownloads = true

Expand Down Expand Up @@ -109,34 +110,38 @@ final class CourseInfoTabSyllabusInteractor: CourseInfoTabSyllabusInteractorProt

strongSelf.fetchSemaphore.wait()

let isOnline = strongSelf.isOnline
print("course info tab syllabus interactor: start fetching syllabus, isOnline = \(isOnline)")
let shouldUseNetwork = strongSelf.isOnline && strongSelf.didLoadFromCache
print("CourseInfoTabSyllabusInteractor :: start fetching syllabus, isOnline = \(shouldUseNetwork)")

strongSelf.fetchSyllabusInAppropriateMode(course: course, isOnline: isOnline).done { response in
strongSelf.fetchSyllabusInAppropriateMode(course: course, isOnline: shouldUseNetwork).done { response in
DispatchQueue.main.async {
print("course info tab syllabus interactor: finish fetching syllabus, isOnline = \(isOnline)")
print("CourseInfoTabSyllabusInteractor :: finish fetching syllabus, isOnline = \(shouldUseNetwork)")
strongSelf.presenter.presentCourseSyllabus(response: response)

if isOnline && !strongSelf.didLoadFromNetwork {
if !strongSelf.didLoadFromCache {
strongSelf.didLoadFromCache = true
}

if shouldUseNetwork && !strongSelf.didLoadFromNetwork {
strongSelf.didLoadFromNetwork = true
strongSelf.updateSyllabusHeader()
strongSelf.sectionFetchSemaphore.signal()
}
}
}.catch { error in
// TODO: handle error
print("course info tab syllabus interactor: error while fetching syllabus, isOnline = \(isOnline), error = \(error)")
print("CourseInfoTabSyllabusInteractor :: error while fetching syllabus, isOnline = \(shouldUseNetwork), error = \(error)")
}.finally {
strongSelf.fetchSemaphore.signal()
}
}
}

func doSectionFetch(request: CourseInfoTabSyllabus.SyllabusSectionLoad.Request) {
// Skip request if already fetched earlier
if self.remoteFetchedSectionsUniqueIdentifiers.contains(request.uniqueIdentifier) {
return
}

self.remoteFetchedSectionsUniqueIdentifiers.insert(request.uniqueIdentifier)

self.unitsFetchBackgroundQueue.async { [weak self] in
Expand All @@ -152,17 +157,17 @@ final class CourseInfoTabSyllabusInteractor: CourseInfoTabSyllabusInteractorProt
return
}

print("course info tab syllabus interactor: start fetching section from network, id = \(section.id)")
print("CourseInfoTabSyllabusInteractor :: start fetching section from network, id = \(section.id)")

strongSelf.fetchSyllabusSection(section: section).done { response in
DispatchQueue.main.async {
print("course info tab syllabus interactor: finish fetching section from network, id = \(section.id)")
print("CourseInfoTabSyllabusInteractor :: finish fetching section from network, id = \(section.id)")

strongSelf.presenter.presentCourseSyllabus(response: response)
strongSelf.updateSyllabusHeader()
}
}.catch { error in
print("course info tab syllabus interactor: error while fetching section from network, error = \(error)")
print("CourseInfoTabSyllabusInteractor :: error while fetching section from network, error = \(error)")
strongSelf.remoteFetchedSectionsUniqueIdentifiers.remove(request.uniqueIdentifier)
}
}
Expand All @@ -175,7 +180,7 @@ final class CourseInfoTabSyllabusInteractor: CourseInfoTabSyllabusInteractorProt

func handleUnit(id: UniqueIdentifierType) {
guard let unit = self.currentUnits[id] as? Unit else {
return print("course info tab syllabus interactor: unit doesn't exists in current units, id = \(id)")
return print("CourseInfoTabSyllabusInteractor :: unit doesn't exists in current units, id = \(id)")
}

let currentState = self.getDownloadingStateForUnit(unit)
Expand Down Expand Up @@ -231,7 +236,7 @@ final class CourseInfoTabSyllabusInteractor: CourseInfoTabSyllabusInteractorProt

func handleSection(id: UniqueIdentifierType) {
guard let section = self.currentSections[id] else {
return print("course info tab syllabus interactor: section doesn't exists in current sections, id = \(id)")
return print("CourseInfoTabSyllabusInteractor :: section doesn't exists in current sections, id = \(id)")
}

let currentState = self.getDownloadingStateForSection(section)
Expand Down Expand Up @@ -331,7 +336,7 @@ final class CourseInfoTabSyllabusInteractor: CourseInfoTabSyllabusInteractorProt
self.startDownloadingCourse()
}
default:
return print("course info tab syllabus interactor: did receive invalid state when handle download all")
return print("CourseInfoTabSyllabusInteractor :: did receive invalid state when handle download all")
}
}

Expand Down Expand Up @@ -440,7 +445,7 @@ final class CourseInfoTabSyllabusInteractor: CourseInfoTabSyllabusInteractorProt
let data = self.makeSyllabusDataFromCurrentData()
seal.fulfill(.init(result: .success(data)))
}.catch { error in
print("course info tab syllabus interactor: unable to fetch section, error = \(error)")
print("CourseInfoTabSyllabusInteractor :: unable to fetch section, error = \(error)")
seal.reject(Error.fetchFailed)
}
}
Expand Down Expand Up @@ -475,7 +480,7 @@ final class CourseInfoTabSyllabusInteractor: CourseInfoTabSyllabusInteractorProt
let data = self.makeSyllabusDataFromCurrentData()
seal.fulfill(.init(result: .success(data)))
}.catch { error in
print("course info tab syllabus interactor: unable to fetch syllabus, error = \(error)")
print("CourseInfoTabSyllabusInteractor :: unable to fetch syllabus, error = \(error)")
seal.reject(Error.fetchFailed)
}
}
Expand Down Expand Up @@ -569,7 +574,7 @@ extension CourseInfoTabSyllabusInteractor: CourseInfoTabSyllabusInputProtocol {
}

func update(with course: Course, viewSource: AnalyticsEvent.CourseViewSource, isOnline: Bool) {
print("course info tab syllabus interactor: updated from parent module, isOnline = \(isOnline)")
print("CourseInfoTabSyllabusInteractor :: updated from parent module, isOnline = \(isOnline)")

self.currentCourse = course
self.isOnline = isOnline
Expand Down Expand Up @@ -755,7 +760,7 @@ extension CourseInfoTabSyllabusInteractor {
self.analytics.send(.downloadStarted(content: .lesson))

let unitID = unit.id
print("course info tab syllabus interactor: start downloading unit = \(unitID)")
print("CourseInfoTabSyllabusInteractor :: start downloading unit = \(unitID)")

self.presenter.presentDownloadButtonUpdate(
response: .init(
Expand All @@ -765,9 +770,9 @@ extension CourseInfoTabSyllabusInteractor {
)

self.syllabusDownloadsService.download(unit: unit).done {
print("course info tab syllabus interactor: started downloading unit = \(unitID)")
print("CourseInfoTabSyllabusInteractor :: started downloading unit = \(unitID)")
}.catch { error in
print("course info tab syllabus interactor: error while starting download unit = \(unitID), error = \(error)")
print("CourseInfoTabSyllabusInteractor :: error while starting download unit = \(unitID), error = \(error)")

self.updateUnitDownloadState(unit, forceSectionUpdate: true)
self.updateSyllabusHeader()
Expand All @@ -780,7 +785,7 @@ extension CourseInfoTabSyllabusInteractor {
self.analytics.send(.downloadStarted(content: .section))

let sectionID = section.id
print("course info tab syllabus interactor: start downloading section = \(sectionID)")
print("CourseInfoTabSyllabusInteractor :: start downloading section = \(sectionID)")

self.presenter.presentDownloadButtonUpdate(
response: .init(
Expand All @@ -802,9 +807,9 @@ extension CourseInfoTabSyllabusInteractor {
}

self.syllabusDownloadsService.download(section: section).done {
print("course info tab syllabus interactor: started downloading section = \(sectionID)")
print("CourseInfoTabSyllabusInteractor :: started downloading section = \(sectionID)")
}.catch { error in
print("course info tab syllabus interactor: error while starting download section = \(sectionID), error = \(error)")
print("CourseInfoTabSyllabusInteractor :: error while starting download section = \(sectionID), error = \(error)")

self.updateSectionDownloadState(section)
self.updateSyllabusHeader()
Expand Down Expand Up @@ -839,66 +844,66 @@ extension CourseInfoTabSyllabusInteractor {
self.analytics.send(.downloadCancelled(content: .lesson))

let unitID = unit.id
print("course info tab syllabus interactor: start cancelling unit = \(unitID)")
print("CourseInfoTabSyllabusInteractor :: start cancelling unit = \(unitID)")

self.syllabusDownloadsService.cancel(unit: unit).done {
print("course info tab syllabus interactor: finish cancelling unit = \(unitID)")
print("CourseInfoTabSyllabusInteractor :: finish cancelling unit = \(unitID)")
}.ensure {
self.updateUnitDownloadState(unit, forceSectionUpdate: true)
self.updateSyllabusHeader()
}.catch { error in
print("course info tab syllabus interactor: error while cancelling unit = \(unitID), error = \(error)")
print("CourseInfoTabSyllabusInteractor :: error while cancelling unit = \(unitID), error = \(error)")
}
}

private func cancelDownloading(section: Section) {
self.analytics.send(.downloadCancelled(content: .section))

let sectionID = section.id
print("course info tab syllabus interactor: start cancelling section = \(sectionID)")
print("CourseInfoTabSyllabusInteractor :: start cancelling section = \(sectionID)")

self.syllabusDownloadsService.cancel(section: section).done {
print("course info tab syllabus interactor: finish cancelling section = \(sectionID)")
print("CourseInfoTabSyllabusInteractor :: finish cancelling section = \(sectionID)")
}.ensure {
// FIXME: Better handle this case, w/o delay section downloading tasks may not be cancelled
DispatchQueue.main.asyncAfter(deadline: .now() + .seconds(1)) {
self.updateSectionDownloadState(section)
self.updateSyllabusHeader()
}
}.catch { error in
print("course info tab syllabus interactor: error while cancelling section = \(sectionID), error = \(error)")
print("CourseInfoTabSyllabusInteractor :: error while cancelling section = \(sectionID), error = \(error)")
}
}

private func removeCached(unit: Unit) {
self.analytics.send(.downloadDeleted(content: .lesson, source: .syllabus))

let unitID = unit.id
print("course info tab syllabus interactor: start removing cached unit = \(unitID)")
print("CourseInfoTabSyllabusInteractor :: start removing cached unit = \(unitID)")

self.syllabusDownloadsService.remove(unit: unit).done {
print("course info tab syllabus interactor: finish removing cached unit = \(unitID)")
print("CourseInfoTabSyllabusInteractor :: finish removing cached unit = \(unitID)")
}.ensure {
self.updateUnitDownloadState(unit, forceSectionUpdate: true)
self.updateSyllabusHeader()
}.catch { error in
print("course info tab syllabus interactor: error while removing cached unit = \(unitID), error = \(error)")
print("CourseInfoTabSyllabusInteractor :: error while removing cached unit = \(unitID), error = \(error)")
}
}

private func removeCached(section: Section) {
self.analytics.send(.downloadDeleted(content: .section, source: .syllabus))

let sectionID = section.id
print("course info tab syllabus interactor: start removing cached section = \(sectionID)")
print("CourseInfoTabSyllabusInteractor :: start removing cached section = \(sectionID)")

self.syllabusDownloadsService.remove(section: section).done {
print("course info tab syllabus interactor: finish removing cached section = \(sectionID)")
print("CourseInfoTabSyllabusInteractor :: finish removing cached section = \(sectionID)")
}.ensure {
self.updateSectionDownloadState(section)
self.updateSyllabusHeader()
}.catch { error in
print("course info tab syllabus interactor: error while removing cached section = \(sectionID), error = \(error)")
print("CourseInfoTabSyllabusInteractor :: error while removing cached section = \(sectionID), error = \(error)")
}
}

Expand All @@ -910,15 +915,15 @@ extension CourseInfoTabSyllabusInteractor {
self.analytics.send(.downloadDeleted(content: .course, source: .syllabus))

let courseID = course.id
print("course info tab syllabus interactor: start removing cached course = \(courseID)")
print("CourseInfoTabSyllabusInteractor :: start removing cached course = \(courseID)")

self.syllabusDownloadsService.remove(course: course).done {
print("course info tab syllabus interactor: finish removing cached course = \(courseID)")
print("CourseInfoTabSyllabusInteractor :: finish removing cached course = \(courseID)")
}.ensure {
self.updateSyllabusHeader()
course.sections.forEach { self.updateSectionDownloadState($0) }
}.catch { error in
print("course info tab syllabus interactor: error while removing cached course = \(courseID), error = \(error)")
print("CourseInfoTabSyllabusInteractor :: error while removing cached course = \(courseID), error = \(error)")
}
}

Expand Down