@@ -19,13 +19,22 @@ package com.instructure.student.adapter
1919
2020import android.content.Context
2121import android.view.View
22+ import android.widget.Toast
2223import androidx.recyclerview.widget.RecyclerView
2324import com.instructure.canvasapi2.StatusCallback
2425import com.instructure.canvasapi2.managers.AssignmentManager
2526import com.instructure.canvasapi2.managers.CourseManager
2627import com.instructure.canvasapi2.managers.EnrollmentManager
2728import com.instructure.canvasapi2.managers.SubmissionManager
28- import com.instructure.canvasapi2.models.*
29+ import com.instructure.canvasapi2.models.Assignment
30+ import com.instructure.canvasapi2.models.AssignmentGroup
31+ import com.instructure.canvasapi2.models.CanvasContext
32+ import com.instructure.canvasapi2.models.Course
33+ import com.instructure.canvasapi2.models.CourseGrade
34+ import com.instructure.canvasapi2.models.Enrollment
35+ import com.instructure.canvasapi2.models.GradingPeriod
36+ import com.instructure.canvasapi2.models.GradingPeriodResponse
37+ import com.instructure.canvasapi2.models.Submission
2938import com.instructure.canvasapi2.utils.ApiPrefs
3039import com.instructure.canvasapi2.utils.isNullOrEmpty
3140import com.instructure.canvasapi2.utils.weave.awaitApi
@@ -45,7 +54,8 @@ import kotlinx.coroutines.Dispatchers
4554import kotlinx.coroutines.GlobalScope
4655import kotlinx.coroutines.Job
4756import kotlinx.coroutines.launch
48- import java.util.*
57+ import java.util.ArrayList
58+ import java.util.HashMap
4959
5060open class GradesListRecyclerAdapter (
5161 context : Context ,
@@ -110,46 +120,50 @@ open class GradesListRecyclerAdapter(
110120
111121 final override fun loadData () {
112122 loadDataJob = GlobalScope .launch(Dispatchers .Main ) {
113- // Logic regarding MGP is similar here as it is in both assignment recycler adapters,
114- // if changes are made here, check if they are needed in the other recycler adapters
115- val course = awaitApi<Course >{CourseManager .getCourseWithGrade(canvasContext!! .id, it, true )}
116- val enrollments = (canvasContext as Course ).enrollments
117- canvasContext = course
118-
119- // Use the enrollments that were passed in with the course if one returned has none
120- // Should only be concluded courses that this applies
121- (canvasContext as Course ).apply {
122- if (this .enrollments.isNullOrEmpty()) {
123- this .enrollments = enrollments
124- }
125- }
126-
127- // We want to disable what if grading if MGP weights are enabled
128- if (course.isWeightedGradingPeriods) {
129- adapterToGradesCallback?.setIsWhatIfGrading(false )
130- } else {
131- adapterToGradesCallback?.setIsWhatIfGrading(true )
132- }
133-
134- if (isAllGradingPeriodsSelected) {
135- isRefresh = true
136- updateCourseGrade()
137- updateWithAllAssignments()
138- return @launch
139- }
140-
141- course.enrollments!! .firstOrNull {
142- it.isStudent && it.multipleGradingPeriodsEnabled
143- }?.let { enrollment ->
144- setupStudentGrades(enrollment, course)
145- } ? : course.enrollments!! .firstOrNull { it.isObserver }?.let { enrollment ->
146- setupObserverGrades(enrollment, course)
147- }
148-
149- // If we've made it this far, MGP is not enabled, so we do the standard behavior
150- isRefresh = true
151- updateCourseGrade()
152- updateWithAllAssignments()
123+ try {
124+ // Logic regarding MGP is similar here as it is in both assignment recycler adapters,
125+ // if changes are made here, check if they are needed in the other recycler adapters
126+ val course = awaitApi<Course >{CourseManager .getCourseWithGrade(canvasContext!! .id, it, true )}
127+ val enrollments = (canvasContext as Course ).enrollments
128+ canvasContext = course
129+
130+ // Use the enrollments that were passed in with the course if one returned has none
131+ // Should only be concluded courses that this applies
132+ (canvasContext as Course ).apply {
133+ if (this .enrollments.isNullOrEmpty()) {
134+ this .enrollments = enrollments
135+ }
136+ }
137+
138+ // We want to disable what if grading if MGP weights are enabled
139+ if (course.isWeightedGradingPeriods) {
140+ adapterToGradesCallback?.setIsWhatIfGrading(false )
141+ } else {
142+ adapterToGradesCallback?.setIsWhatIfGrading(true )
143+ }
144+
145+ if (isAllGradingPeriodsSelected) {
146+ isRefresh = true
147+ updateCourseGrade()
148+ updateWithAllAssignments()
149+ return @launch
150+ }
151+
152+ course.enrollments!! .firstOrNull {
153+ it.isStudent && it.multipleGradingPeriodsEnabled
154+ }?.let { enrollment ->
155+ setupStudentGrades(enrollment, course)
156+ } ? : course.enrollments!! .firstOrNull { it.isObserver }?.let { enrollment ->
157+ setupObserverGrades(enrollment, course)
158+ }
159+
160+ // If we've made it this far, MGP is not enabled, so we do the standard behavior
161+ isRefresh = true
162+ updateCourseGrade()
163+ updateWithAllAssignments()
164+ } catch (e: Throwable ) {
165+ Toast .makeText(context, R .string.errorOccurred, Toast .LENGTH_SHORT ).show()
166+ }
153167 }
154168 }
155169
@@ -162,38 +176,42 @@ open class GradesListRecyclerAdapter(
162176
163177 // Get the first student that this user is observing
164178 observerCourseGradeJob = GlobalScope .launch(Dispatchers .Main ) {
165- // We need to use an ID from an observee, not the user (who is currently logged in as an observer) when retrieving the enrollments
166-
167- // Get the first student this user is observing, if none show empty assignments
168- val student = awaitApi<List <Enrollment >> { EnrollmentManager .getObserveeEnrollments(true , it) }
169- .firstOrNull { it.courseId == course.id && it.observedUser != null }?.observedUser
170- ? : return @launch updateAssignmentGroups(emptyList())
171-
172- // Get Assignment Groups
173- val assignmentGroups = awaitApi<List <AssignmentGroup >> { AssignmentManager .getAssignmentGroupsWithAssignmentsForGradingPeriod(canvasContext!! .id, currentGradingPeriod!! .id,
174- scopeToStudent = false ,
175- forceNetwork = true ,
176- callback = it
177- ) }
178- // The assignments in the assignment groups do not come with their submissions (with the associated grades), so we get them all here
179- val assignmentIds = assignmentGroups.map { it.assignments }.flatten().map { it.id }
180- val submissions = awaitApi<List <Submission >>{ SubmissionManager .getSubmissionsForMultipleAssignments(student.id, course.id, assignmentIds, it, true ) }
181- assignmentGroups.forEach { group ->
182- group.assignments.forEach { assignment ->
183- assignment.submission = submissions.firstOrNull { it.assignmentId == assignment.id }
179+ try {
180+ // We need to use an ID from an observee, not the user (who is currently logged in as an observer) when retrieving the enrollments
181+
182+ // Get the first student this user is observing, if none show empty assignments
183+ val student = awaitApi<List <Enrollment >> { EnrollmentManager .getObserveeEnrollments(true , it) }
184+ .firstOrNull { it.courseId == course.id && it.observedUser != null }?.observedUser
185+ ? : return @launch updateAssignmentGroups(emptyList())
186+
187+ // Get Assignment Groups
188+ val assignmentGroups = awaitApi<List <AssignmentGroup >> { AssignmentManager .getAssignmentGroupsWithAssignmentsForGradingPeriod(canvasContext!! .id, currentGradingPeriod!! .id,
189+ scopeToStudent = false ,
190+ forceNetwork = true ,
191+ callback = it
192+ ) }
193+ // The assignments in the assignment groups do not come with their submissions (with the associated grades), so we get them all here
194+ val assignmentIds = assignmentGroups.map { it.assignments }.flatten().map { it.id }
195+ val submissions = awaitApi<List <Submission >>{ SubmissionManager .getSubmissionsForMultipleAssignments(student.id, course.id, assignmentIds, it, true ) }
196+ assignmentGroups.forEach { group ->
197+ group.assignments.forEach { assignment ->
198+ assignment.submission = submissions.firstOrNull { it.assignmentId == assignment.id }
199+ }
184200 }
185- }
186201
187- updateAssignmentGroups(assignmentGroups)
202+ updateAssignmentGroups(assignmentGroups)
188203
189- awaitApi<List <Course >> { CourseManager .getCoursesWithSyllabus(true , it) }
190- .onEach { course ->
191- course.enrollments?.find { it.userId == student.id }?.let {
192- course.enrollments = mutableListOf (it)
193- courseGrade = course.getCourseGradeFromEnrollment(it, false )
194- adapterToGradesCallback?.notifyGradeChanged(courseGrade)
204+ awaitApi<List <Course >> { CourseManager .getCoursesWithSyllabus(true , it) }
205+ .onEach { course ->
206+ course.enrollments?.find { it.userId == student.id }?.let {
207+ course.enrollments = mutableListOf (it)
208+ courseGrade = course.getCourseGradeFromEnrollment(it, false )
209+ adapterToGradesCallback?.notifyGradeChanged(courseGrade)
210+ }
195211 }
196- }
212+ } catch (e: Throwable ) {
213+ Toast .makeText(context, R .string.errorOccurred, Toast .LENGTH_SHORT ).show()
214+ }
197215 }
198216 return
199217 }
@@ -228,16 +246,20 @@ open class GradesListRecyclerAdapter(
228246 val scopeToStudent = (canvasContext as Course ).isStudent
229247 if (scopeToStudent) {
230248 assignmentsForGradingPeriodJob = GlobalScope .launch(Dispatchers .Main ) {
231- val assignmentGroups = awaitApi<List <AssignmentGroup >>{AssignmentManager .getAssignmentGroupsWithAssignmentsForGradingPeriod(canvasContext!! .id, gradingPeriodID, scopeToStudent, true , it)}
232- updateAssignmentGroups(assignmentGroups)
233-
234- // Fetch the enrollments associated with the selected gradingPeriodID, these will contain the
235- // correct grade for the period
236- val enrollments = awaitApi<List <Enrollment >>{CourseManager .getUserEnrollmentsForGradingPeriod(canvasContext!! .id, ApiPrefs .user!! .id, gradingPeriodID, it, true )}
237- updateCourseGradeFromEnrollments(enrollments)
238-
239- // Inform the spinner things are done
240- adapterToGradesCallback?.setTermSpinnerState(true )
249+ try {
250+ val assignmentGroups = awaitApi<List <AssignmentGroup >>{AssignmentManager .getAssignmentGroupsWithAssignmentsForGradingPeriod(canvasContext!! .id, gradingPeriodID, scopeToStudent, true , it)}
251+ updateAssignmentGroups(assignmentGroups)
252+
253+ // Fetch the enrollments associated with the selected gradingPeriodID, these will contain the
254+ // correct grade for the period
255+ val enrollments = awaitApi<List <Enrollment >>{CourseManager .getUserEnrollmentsForGradingPeriod(canvasContext!! .id, ApiPrefs .user!! .id, gradingPeriodID, it, true )}
256+ updateCourseGradeFromEnrollments(enrollments)
257+
258+ // Inform the spinner things are done
259+ adapterToGradesCallback?.setTermSpinnerState(true )
260+ } catch (e: Throwable ) {
261+ Toast .makeText(context, R .string.errorOccurred, Toast .LENGTH_SHORT ).show()
262+ }
241263 }
242264 }
243265 }
@@ -262,9 +284,13 @@ open class GradesListRecyclerAdapter(
262284
263285 private fun updateWithAllAssignments () {
264286 allAssignmentsAndGroupsJob = GlobalScope .launch(Dispatchers .Main ) {
265- // Standard load assignments, unfiltered
266- val aGroups = awaitApi<List <AssignmentGroup >>{AssignmentManager .getAssignmentGroupsWithAssignments(canvasContext!! .id, true , it)}
267- updateAssignmentGroups(aGroups)
287+ try {
288+ // Standard load assignments, unfiltered
289+ val aGroups = awaitApi<List <AssignmentGroup >>{AssignmentManager .getAssignmentGroupsWithAssignments(canvasContext!! .id, true , it)}
290+ updateAssignmentGroups(aGroups)
291+ } catch (e: Throwable ) {
292+ Toast .makeText(context, R .string.errorOccurred, Toast .LENGTH_SHORT ).show()
293+ }
268294 }
269295 }
270296
0 commit comments