-
Notifications
You must be signed in to change notification settings - Fork 111
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
[Horizon] Feature/clx 165 notebook list #2995
base: feature/horizon
Are you sure you want to change the base?
Conversation
reabbotted
commented
Dec 2, 2024
- Showing and filtering a list of courses that have notes by text search
- Showing and filtering a list of notes for an individual course
|
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Congrats on your first Horizon PR!
Functionality wise, it works well! I had a some remark about our coding conventions, combine usage.
Some general observations:
- In Horizon (as opposed to Canvas) let's follow the
View
,Domain
,Data
folder structure for features. - When declaring properties, we usually keep them "close" without new lines. We do separate dependencies, private properties and such by marking them with a comment but each section of properties are listed without new lines.
- Not set in stone but if a function signature is getting long (e.g 3 ore more parameters) we divide it by new lines.
- When adding view modifiers, reactive operators we add them on new lines.
- I added a few comments about new lines, but not everywhere.
Core/Core/Assets.xcassets/InstIcons/book.imageset/Contents.json
Outdated
Show resolved
Hide resolved
Horizon/Horizon/Sources/Features/Dashboard/View/DashboardViewModel.swift
Outdated
Show resolved
Hide resolved
Horizon/Horizon/Sources/Features/Notebook/Common/Model/CourseNotesRepository.swift
Outdated
Show resolved
Hide resolved
Horizon/Horizon/Sources/Features/Notebook/Common/View/NoteCard.swift
Outdated
Show resolved
Hide resolved
Horizon/Horizon/Sources/Features/Notebook/Course/View/NotebookCourseView.swift
Outdated
Show resolved
Hide resolved
Horizon/Horizon/Sources/Features/Notebook/Course/ViewModel/NotebookCourseViewModel.swift
Outdated
Show resolved
Hide resolved
Horizon/Horizon/Sources/Features/Notebook/CourseList/Model/GetCoursesInteractor.swift
Outdated
Show resolved
Hide resolved
Horizon/Horizon/Sources/Features/Notebook/CourseList/ViewModel/NotebookViewModel.swift
Outdated
Show resolved
Hide resolved
Horizon/Horizon/Sources/Features/Notebook/CourseList/ViewModel/NotebookViewModel.swift
Outdated
Show resolved
Hide resolved
Horizon/Horizon/Sources/Features/Notebook/Common/Data/CourseNotesRepository.swift
Show resolved
Hide resolved
Horizon/Horizon/Sources/Features/Notebook/Common/View/NoteCard.swift
Outdated
Show resolved
Hide resolved
Horizon/Horizon/Sources/Features/Notebook/Common/View/NoteCard.swift
Outdated
Show resolved
Hide resolved
Horizon/Horizon/Sources/Features/Notebook/Common/View/NoteCard.swift
Outdated
Show resolved
Hide resolved
Horizon/Horizon/Sources/Features/Notebook/Common/View/NoteCard.swift
Outdated
Show resolved
Hide resolved
Horizon/Horizon/Sources/Features/Notebook/Common/View/View.swift
Outdated
Show resolved
Hide resolved
Horizon/Horizon/Sources/Features/Notebook/Common/View/View.swift
Outdated
Show resolved
Hide resolved
Horizon/Horizon/Sources/Features/Notebook/Course/Domain/GetCourseNotesInteractor.swift
Show resolved
Hide resolved
Horizon/Horizon/Sources/Features/Notebook/Course/Domain/GetCourseNotesInteractor.swift
Show resolved
Hide resolved
Horizon/Horizon/Sources/Features/Notebook/Course/NotebookCourseAssembly.swift
Show resolved
Hide resolved
Horizon/Horizon/Sources/Features/Notebook/Course/View/NotebookCourseView.swift
Show resolved
Hide resolved
Horizon/Horizon/Sources/Features/Notebook/Course/View/NotebookCourseView.swift
Show resolved
Hide resolved
Horizon/Horizon/Sources/Features/Notebook/Course/View/NotebookCourseView.swift
Outdated
Show resolved
Hide resolved
Horizon/Horizon/Sources/Features/Notebook/Course/View/NotebookCourseView.swift
Outdated
Show resolved
Hide resolved
Horizon/Horizon/Sources/Features/Notebook/Course/View/NotebookCourseViewModel.swift
Show resolved
Hide resolved
Horizon/Horizon/Sources/Features/Notebook/CourseList/Data/NotebookCourse.swift
Show resolved
Hide resolved
Horizon/Horizon/Sources/Features/Notebook/CourseList/Domain/GetCoursesInteractor.swift
Show resolved
Hide resolved
Horizon/Horizon/Sources/Features/Notebook/CourseList/View/NotebookView.swift
Show resolved
Hide resolved
Horizon/Horizon/Sources/Features/Notebook/CourseList/View/NotebookView.swift
Show resolved
Hide resolved
Horizon/Horizon/Sources/Features/Notebook/CourseList/View/NotebookView.swift
Outdated
Show resolved
Hide resolved
Horizon/Horizon/Sources/Features/Notebook/CourseList/View/NotebookView.swift
Outdated
Show resolved
Hide resolved
Horizon/Horizon/Sources/Features/Notebook/CourseList/View/NotebookViewModel.swift
Show resolved
Hide resolved
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
congratulation for your first PR,
I set some comments
I'm sorry approved by mistake |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for the changes!
Last round of suggestions below.
Horizon/Horizon/Sources/Features/Notebook/Common/Data/CourseNotesRepository.swift
Show resolved
Hide resolved
.frame(maxWidth: .infinity, alignment: .leading) | ||
.padding(24) | ||
.background(Color.white) | ||
.cornerRadius(16) | ||
.shadow(color: Color.black.opacity(0.2), radius: 8, x: 1, y: 2) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Missing indentation.
.padding(.horizontal, 24) | ||
.padding(.bottom, 24) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Missing indentation.
|
||
init( | ||
title: String, | ||
router: Router, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Instead of passing the whole router we could reduce the coupling by passing a closure e.g onBackButtonTap
or didTap and then NotebookCourseViewModel
and NotebookViewModel
could handle the back logic.
let notebookNoteLabel = courseNote.labels.map({ label in | ||
NotebookNoteLabel.allCases.first { $0.rawValue.lowercased() == label.lowercased() } | ||
}).filter({$0 != nil}).map({$0!}).first |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
let notebookNoteLabel = courseNote.labels.map({ label in | |
NotebookNoteLabel.allCases.first { $0.rawValue.lowercased() == label.lowercased() } | |
}).filter({$0 != nil}).map({$0!}).first | |
let notebookNoteLabel = courseNote.labels | |
.map { label in | |
NotebookNoteLabel.allCases.first { | |
$0.rawValue.lowercased() == label.lowercased() | |
} | |
} | |
.filter {$0 != nil} | |
.map {$0!} | |
.first |
private let courseId: String | ||
private let formatter = DateFormatter() | ||
private let getCourseNotesInteractor: GetCourseNotesInteractor | ||
private var cancellables: Set<AnyCancellable> = [] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please use the name subscriptions
as that's the project wide standard for storing AnyCancellables.
func get() -> AnyPublisher<[NotebookCourse], Error> { | ||
courseNotesRepository | ||
.get() | ||
.map({ notes in notes.map({ NotebookCourse(from: $0) }) }) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
.map({ notes in notes.map({ NotebookCourse(from: $0) }) }) | |
.map { notes in notes.map({ NotebookCourse(from: $0) }) } |
return courses.filter({ course in | ||
term.isEmpty || | ||
course.course.lowercased().contains(term.lowercased()) || | ||
course.institution.lowercased().contains(term.lowercased()) | ||
}) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
return courses.filter({ course in | |
term.isEmpty || | |
course.course.lowercased().contains(term.lowercased()) || | |
course.institution.lowercased().contains(term.lowercased()) | |
}) | |
return courses.filter { course in | |
term.isEmpty || | |
course.course.lowercased().contains(term.lowercased()) || | |
course.institution.lowercased().contains(term.lowercased()) | |
} |
private let getCoursesInteractor: GetCoursesInteractor | ||
private var cancellables: Set<AnyCancellable> = [] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please group the router and the interactor together as they are outside dependencies and use subscriptions
instead of cancellables
.
getCoursesInteractor.get().sink { _ in } receiveValue: { [weak self] courses in | ||
self?.listItems = courses.map { | ||
NotebookListItem(id: $0.id, course: $0.course, institution: $0.institution) | ||
} | ||
}.store(in: &cancellables) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
getCoursesInteractor.get().sink { _ in } receiveValue: { [weak self] courses in | |
self?.listItems = courses.map { | |
NotebookListItem(id: $0.id, course: $0.course, institution: $0.institution) | |
} | |
}.store(in: &cancellables) | |
getCoursesInteractor.get() | |
.flatMap { | |
$0.publisher | |
.map { course in | |
NotebookListItem( | |
id: course.id, | |
course: course.course, | |
institution: course.institution | |
) | |
} | |
.collect() | |
} | |
.replaceError(with: []) | |
.sink { [weak self] in | |
self?.listItems = $0 | |
} | |
.store(in: &cancellables) |