Skip to content

Commit

Permalink
Merge Release/student/6.6.1 into master (#305)
Browse files Browse the repository at this point in the history
* Version bump

* [Student] Fix bottom bar divider still being shown (#261)

* [Student][R-6.6.1] Load submission files on background thread (#260)

* [Student][R-6.6.1] Fix duplicate file error in submission (#262)

Instead of naming files something unique and altering the users filename, only delete files if no other file for a submission depends on it. This will also include newly created submissions that haven't been put into the database yet.

* [Student][R-6.6.1] Fix success/error from file uploads on assignment deets (#264)

The submission wasn't getting deleted/errored correctly for file uploads.

* [Student][RC6.6.1] Color change into rc (#265)

* [Student][NewRelic][MBL-13108]: USE_REMOTE_CONFIG -> USE_NEW_RELIC (#267)

* [RC6.6.1] Change cancel text to red (#263)

* [Teacher][MBL-13105] Post Policy skeleton (#257)

Added the feature flag, necessary strings, and the view pager layout for the base screen. Now just the two individual screens need their loops/views done.

* MBL-13108: USE_REMOTE_CONFIG -> USE_NEW_RELIC

* [Student][R-6.6.1][MBL-13100] Quick bandaid for network-related crashes in grades list (#268)

* removed files added back by merge

* fixed errors from merge conflict resolution
  • Loading branch information
TrevorNeedham authored Sep 12, 2019
1 parent 2274ab9 commit 1a9c9fd
Show file tree
Hide file tree
Showing 12 changed files with 149 additions and 110 deletions.
4 changes: 2 additions & 2 deletions apps/student/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -57,8 +57,8 @@ android {
applicationId "com.instructure.candroid"
minSdkVersion Versions.MIN_SDK
targetSdkVersion Versions.TARGET_SDK
versionCode = 199
versionName = '6.6.0'
versionCode = 200
versionName = '6.6.1'

vectorDrawables.useSupportLibrary = true
multiDexEnabled = true
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,11 @@ SELECT *
FROM fileSubmission
WHERE dbSubmissionId = ?;

getFilesForPath:
SELECT *
FROM fileSubmission
WHERE id != ? AND fullPath = ?;

getFilesWithoutAttachmentsForSubmissionId:
SELECT *
FROM fileSubmission
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ class LoginActivity : BaseLoginInitActivity() {

override fun onCreate(savedInstanceState: Bundle?) {
val startNewRelic =
RemoteConfigUtils.getString(RemoteConfigParam.USE_REMOTE_CONFIG)?.equals("true",ignoreCase = true) ?: false
RemoteConfigUtils.getString(RemoteConfigParam.USE_NEW_RELIC)?.equals("true",ignoreCase = true) ?: false

Log.v("LoginActivity","startNewRelic=$startNewRelic")

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -163,7 +163,9 @@ class NavigationActivity : BaseRouterActivity(), Navigation, MasqueradingDialog.
/* Update nav bar visibility to show for specific 'root' fragments. Also show the nav bar when there is
only one fragment on the backstack, which commonly occurs with non-root fragments when routing
from external sources. */
bottomBar.setVisible(it::class.java in bottomNavBarFragments || supportFragmentManager.backStackEntryCount <= 1)
val visible = it::class.java in bottomNavBarFragments || supportFragmentManager.backStackEntryCount <= 1
bottomBar.setVisible(visible)
bottomBarDivider.setVisible(visible)
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,13 +19,22 @@ package com.instructure.student.adapter

import android.content.Context
import android.view.View
import android.widget.Toast
import androidx.recyclerview.widget.RecyclerView
import com.instructure.canvasapi2.StatusCallback
import com.instructure.canvasapi2.managers.AssignmentManager
import com.instructure.canvasapi2.managers.CourseManager
import com.instructure.canvasapi2.managers.EnrollmentManager
import com.instructure.canvasapi2.managers.SubmissionManager
import com.instructure.canvasapi2.models.*
import com.instructure.canvasapi2.models.Assignment
import com.instructure.canvasapi2.models.AssignmentGroup
import com.instructure.canvasapi2.models.CanvasContext
import com.instructure.canvasapi2.models.Course
import com.instructure.canvasapi2.models.CourseGrade
import com.instructure.canvasapi2.models.Enrollment
import com.instructure.canvasapi2.models.GradingPeriod
import com.instructure.canvasapi2.models.GradingPeriodResponse
import com.instructure.canvasapi2.models.Submission
import com.instructure.canvasapi2.utils.ApiPrefs
import com.instructure.canvasapi2.utils.isNullOrEmpty
import com.instructure.canvasapi2.utils.weave.awaitApi
Expand All @@ -45,7 +54,8 @@ import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.GlobalScope
import kotlinx.coroutines.Job
import kotlinx.coroutines.launch
import java.util.*
import java.util.ArrayList
import java.util.HashMap

open class GradesListRecyclerAdapter(
context: Context,
Expand Down Expand Up @@ -110,46 +120,50 @@ open class GradesListRecyclerAdapter(

final override fun loadData() {
loadDataJob = GlobalScope.launch(Dispatchers.Main) {
// Logic regarding MGP is similar here as it is in both assignment recycler adapters,
// if changes are made here, check if they are needed in the other recycler adapters
val course = awaitApi<Course>{CourseManager.getCourseWithGrade(canvasContext!!.id, it, true)}
val enrollments = (canvasContext as Course).enrollments
canvasContext = course

// Use the enrollments that were passed in with the course if one returned has none
// Should only be concluded courses that this applies
(canvasContext as Course).apply {
if (this.enrollments.isNullOrEmpty()) {
this.enrollments = enrollments
}
}

// We want to disable what if grading if MGP weights are enabled
if (course.isWeightedGradingPeriods) {
adapterToGradesCallback?.setIsWhatIfGrading(false)
} else {
adapterToGradesCallback?.setIsWhatIfGrading(true)
}

if (isAllGradingPeriodsSelected) {
isRefresh = true
updateCourseGrade()
updateWithAllAssignments()
return@launch
}

course.enrollments!!.firstOrNull {
it.isStudent && it.multipleGradingPeriodsEnabled
}?.let { enrollment ->
setupStudentGrades(enrollment, course)
} ?: course.enrollments!!.firstOrNull { it.isObserver }?.let { enrollment ->
setupObserverGrades(enrollment, course)
}

// If we've made it this far, MGP is not enabled, so we do the standard behavior
isRefresh = true
updateCourseGrade()
updateWithAllAssignments()
try {
// Logic regarding MGP is similar here as it is in both assignment recycler adapters,
// if changes are made here, check if they are needed in the other recycler adapters
val course = awaitApi<Course>{CourseManager.getCourseWithGrade(canvasContext!!.id, it, true)}
val enrollments = (canvasContext as Course).enrollments
canvasContext = course

// Use the enrollments that were passed in with the course if one returned has none
// Should only be concluded courses that this applies
(canvasContext as Course).apply {
if (this.enrollments.isNullOrEmpty()) {
this.enrollments = enrollments
}
}

// We want to disable what if grading if MGP weights are enabled
if (course.isWeightedGradingPeriods) {
adapterToGradesCallback?.setIsWhatIfGrading(false)
} else {
adapterToGradesCallback?.setIsWhatIfGrading(true)
}

if (isAllGradingPeriodsSelected) {
isRefresh = true
updateCourseGrade()
updateWithAllAssignments()
return@launch
}

course.enrollments!!.firstOrNull {
it.isStudent && it.multipleGradingPeriodsEnabled
}?.let { enrollment ->
setupStudentGrades(enrollment, course)
} ?: course.enrollments!!.firstOrNull { it.isObserver }?.let { enrollment ->
setupObserverGrades(enrollment, course)
}

// If we've made it this far, MGP is not enabled, so we do the standard behavior
isRefresh = true
updateCourseGrade()
updateWithAllAssignments()
} catch (e: Throwable) {
Toast.makeText(context, R.string.errorOccurred, Toast.LENGTH_SHORT).show()
}
}
}

Expand All @@ -162,38 +176,42 @@ open class GradesListRecyclerAdapter(

// Get the first student that this user is observing
observerCourseGradeJob = GlobalScope.launch(Dispatchers.Main) {
// We need to use an ID from an observee, not the user (who is currently logged in as an observer) when retrieving the enrollments

// Get the first student this user is observing, if none show empty assignments
val student = awaitApi<List<Enrollment>> { EnrollmentManager.getObserveeEnrollments(true, it) }
.firstOrNull { it.courseId == course.id && it.observedUser != null }?.observedUser
?: return@launch updateAssignmentGroups(emptyList())

// Get Assignment Groups
val assignmentGroups = awaitApi<List<AssignmentGroup>> { AssignmentManager.getAssignmentGroupsWithAssignmentsForGradingPeriod(canvasContext!!.id, currentGradingPeriod!!.id,
scopeToStudent = false,
forceNetwork = true,
callback = it
) }
// The assignments in the assignment groups do not come with their submissions (with the associated grades), so we get them all here
val assignmentIds = assignmentGroups.map { it.assignments }.flatten().map { it.id }
val submissions = awaitApi<List<Submission>>{ SubmissionManager.getSubmissionsForMultipleAssignments(student.id, course.id, assignmentIds, it, true) }
assignmentGroups.forEach { group ->
group.assignments.forEach { assignment ->
assignment.submission = submissions.firstOrNull { it.assignmentId == assignment.id }
try {
// We need to use an ID from an observee, not the user (who is currently logged in as an observer) when retrieving the enrollments

// Get the first student this user is observing, if none show empty assignments
val student = awaitApi<List<Enrollment>> { EnrollmentManager.getObserveeEnrollments(true, it) }
.firstOrNull { it.courseId == course.id && it.observedUser != null }?.observedUser
?: return@launch updateAssignmentGroups(emptyList())

// Get Assignment Groups
val assignmentGroups = awaitApi<List<AssignmentGroup>> { AssignmentManager.getAssignmentGroupsWithAssignmentsForGradingPeriod(canvasContext!!.id, currentGradingPeriod!!.id,
scopeToStudent = false,
forceNetwork = true,
callback = it
) }
// The assignments in the assignment groups do not come with their submissions (with the associated grades), so we get them all here
val assignmentIds = assignmentGroups.map { it.assignments }.flatten().map { it.id }
val submissions = awaitApi<List<Submission>>{ SubmissionManager.getSubmissionsForMultipleAssignments(student.id, course.id, assignmentIds, it, true) }
assignmentGroups.forEach { group ->
group.assignments.forEach { assignment ->
assignment.submission = submissions.firstOrNull { it.assignmentId == assignment.id }
}
}
}

updateAssignmentGroups(assignmentGroups)
updateAssignmentGroups(assignmentGroups)

awaitApi<List<Course>> { CourseManager.getCoursesWithSyllabus(true, it) }
.onEach { course ->
course.enrollments?.find { it.userId == student.id }?.let {
course.enrollments = mutableListOf(it)
courseGrade = course.getCourseGradeFromEnrollment(it, false)
adapterToGradesCallback?.notifyGradeChanged(courseGrade)
awaitApi<List<Course>> { CourseManager.getCoursesWithSyllabus(true, it) }
.onEach { course ->
course.enrollments?.find { it.userId == student.id }?.let {
course.enrollments = mutableListOf(it)
courseGrade = course.getCourseGradeFromEnrollment(it, false)
adapterToGradesCallback?.notifyGradeChanged(courseGrade)
}
}
}
} catch (e: Throwable) {
Toast.makeText(context, R.string.errorOccurred, Toast.LENGTH_SHORT).show()
}
}
return
}
Expand Down Expand Up @@ -228,16 +246,20 @@ open class GradesListRecyclerAdapter(
val scopeToStudent = (canvasContext as Course).isStudent
if (scopeToStudent) {
assignmentsForGradingPeriodJob = GlobalScope.launch(Dispatchers.Main) {
val assignmentGroups = awaitApi<List<AssignmentGroup>>{AssignmentManager.getAssignmentGroupsWithAssignmentsForGradingPeriod(canvasContext!!.id, gradingPeriodID, scopeToStudent, true, it)}
updateAssignmentGroups(assignmentGroups)

// Fetch the enrollments associated with the selected gradingPeriodID, these will contain the
// correct grade for the period
val enrollments = awaitApi<List<Enrollment>>{CourseManager.getUserEnrollmentsForGradingPeriod(canvasContext!!.id, ApiPrefs.user!!.id, gradingPeriodID, it, true)}
updateCourseGradeFromEnrollments(enrollments)

// Inform the spinner things are done
adapterToGradesCallback?.setTermSpinnerState(true)
try {
val assignmentGroups = awaitApi<List<AssignmentGroup>>{AssignmentManager.getAssignmentGroupsWithAssignmentsForGradingPeriod(canvasContext!!.id, gradingPeriodID, scopeToStudent, true, it)}
updateAssignmentGroups(assignmentGroups)

// Fetch the enrollments associated with the selected gradingPeriodID, these will contain the
// correct grade for the period
val enrollments = awaitApi<List<Enrollment>>{CourseManager.getUserEnrollmentsForGradingPeriod(canvasContext!!.id, ApiPrefs.user!!.id, gradingPeriodID, it, true)}
updateCourseGradeFromEnrollments(enrollments)

// Inform the spinner things are done
adapterToGradesCallback?.setTermSpinnerState(true)
} catch (e: Throwable) {
Toast.makeText(context, R.string.errorOccurred, Toast.LENGTH_SHORT).show()
}
}
}
}
Expand All @@ -262,9 +284,13 @@ open class GradesListRecyclerAdapter(

private fun updateWithAllAssignments() {
allAssignmentsAndGroupsJob = GlobalScope.launch(Dispatchers.Main) {
// Standard load assignments, unfiltered
val aGroups = awaitApi<List<AssignmentGroup>>{AssignmentManager.getAssignmentGroupsWithAssignments(canvasContext!!.id, true, it)}
updateAssignmentGroups(aGroups)
try {
// Standard load assignments, unfiltered
val aGroups = awaitApi<List<AssignmentGroup>>{AssignmentManager.getAssignmentGroupsWithAssignments(canvasContext!!.id, true, it)}
updateAssignmentGroups(aGroups)
} catch (e: Throwable) {
Toast.makeText(context, R.string.errorOccurred, Toast.LENGTH_SHORT).show()
}
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,16 +24,25 @@ import android.net.Uri
import androidx.core.content.FileProvider
import com.instructure.canvasapi2.models.postmodels.FileSubmitObject
import com.instructure.canvasapi2.utils.exhaustive
import com.instructure.pandautils.utils.*
import com.instructure.pandautils.utils.Const
import com.instructure.pandautils.utils.FilePrefs
import com.instructure.pandautils.utils.FileUploadUtils
import com.instructure.pandautils.utils.OnActivityResults
import com.instructure.pandautils.utils.PermissionUtils
import com.instructure.pandautils.utils.remove
import com.instructure.pandautils.utils.requestPermissions
import com.instructure.student.R
import com.instructure.student.mobius.assignmentDetails.submission.picker.PickerSubmissionMode.*
import com.instructure.student.mobius.assignmentDetails.submission.picker.PickerSubmissionMode.CommentAttachment
import com.instructure.student.mobius.assignmentDetails.submission.picker.PickerSubmissionMode.FileSubmission
import com.instructure.student.mobius.assignmentDetails.submission.picker.PickerSubmissionMode.MediaSubmission
import com.instructure.student.mobius.assignmentDetails.submission.picker.ui.PickerSubmissionUploadView
import com.instructure.student.mobius.common.ui.EffectHandler
import com.instructure.student.mobius.common.ui.SubmissionService
import com.spotify.mobius.Connection
import com.spotify.mobius.functions.Consumer
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
import org.greenrobot.eventbus.EventBus
import org.greenrobot.eventbus.Subscribe
import java.io.File
Expand Down Expand Up @@ -147,7 +156,9 @@ class PickerSubmissionUploadEffectHandler constructor(

private fun loadFile(allowedExtensions: List<String>, uri: Uri, context: Context) {
launch(Dispatchers.Main) {
val submitObject = FileUploadUtils.getFile(context, uri)
val submitObject = withContext(Dispatchers.IO) {
FileUploadUtils.getFile(context, uri)
}

submitObject?.let {
var fileToSubmit: FileSubmitObject? = null
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ object PickerSubmissionUploadPresenter : Presenter<PickerSubmissionUploadModel,
model: PickerSubmissionUploadModel,
context: Context
): PickerSubmissionUploadViewState {
return if (model.files.isEmpty()) {
return if (model.files.isEmpty() && !model.isLoadingFile) {
presentEmptyState(model)
} else {
presentListState(model, context)
Expand Down
Loading

0 comments on commit 1a9c9fd

Please sign in to comment.