Search in sources :

Example 1 with QuizSubmissionResponse

use of com.instructure.canvasapi2.models.QuizSubmissionResponse in project instructure-android by instructure.

the class QuizSubmissionQuestionListRecyclerAdapter method bindTheHolder.

public void bindTheHolder(final QuizSubmissionQuestion baseItem, RecyclerView.ViewHolder holder, int position) {
    int courseColor = ColorKeeper.getOrGenerateColor(canvasContext);
    if (position == super.getItemCount()) {
        // submit button
        SubmitButtonBinder.bind((SubmitButtonViewHolder) holder, getContext(), canvasContext, QuizSubmissionQuestionListRecyclerAdapter.this, new QuizSubmit() {

            @Override
            public void submitQuiz() {
                QuizManager.postQuizSubmit(canvasContext, quizSubmission, true, new StatusCallback<QuizSubmissionResponse>() {

                    @Override
                    public void onResponse(@NonNull Response<QuizSubmissionResponse> response, @NonNull LinkHeaders linkHeaders, @NonNull ApiType type) {
                        if (type == ApiType.CACHE)
                            return;
                        // Submitted!
                        Toast.makeText(getContext(), R.string.quizSubmittedSuccessfully, Toast.LENGTH_SHORT).show();
                        // Go back to the startQuizFragment
                        ((Activity) getContext()).onBackPressed();
                        Fragment fragment = ((NavigationActivity) getContext()).getTopFragment();
                        if (fragment instanceof QuizStartFragment) {
                            ((QuizStartFragment) fragment).updateQuizInfo();
                        }
                    }

                    @Override
                    public void onFail(@Nullable Call<QuizSubmissionResponse> call, @NonNull Throwable error, @Nullable Response response) {
                        Toast.makeText(getContext(), R.string.quizSubmittedFailure, Toast.LENGTH_SHORT).show();
                    }
                });
            }
        });
        return;
    }
    switch(baseItem.getQuestionType()) {
        case ESSAY:
        case SHORT_ANSWER:
            addEssayQuestion(baseItem, (QuizEssayViewHolder) holder, position, courseColor);
            break;
        case MUTIPLE_CHOICE:
        case TRUE_FALSE:
            addMultipleChoiceQuestion(baseItem, (QuizMultiChoiceViewHolder) holder, position, courseColor);
            break;
        case TEXT_ONLY:
            QuizTextOnlyBinder.bind((QuizTextOnlyViewHolder) holder, baseItem);
            break;
        case MULTIPLE_ANSWERS:
            addMultipleAnswerQuestion((QuizMultiChoiceViewHolder) holder, position, courseColor);
            break;
        case MATCHING:
            addMatchingQuestion(baseItem, (QuizMatchingViewHolder) holder, position, courseColor);
            break;
        case FILE_UPLOAD:
            addFileUploadQuestion(baseItem, (QuizFileUploadViewHolder) holder, position, courseColor);
            break;
        case NUMERICAL:
            addNumericalQuestion(baseItem, (QuizNumericalViewHolder) holder, position, courseColor);
            break;
        case MULTIPLE_DROPDOWNS:
            addMultipleDropdown(baseItem, (QuizMultipleDropdownViewHolder) holder, position, courseColor);
            break;
    }
}
Also used : Call(retrofit2.Call) LinkHeaders(com.instructure.canvasapi2.utils.LinkHeaders) FragmentActivity(android.support.v4.app.FragmentActivity) NavigationActivity(com.instructure.candroid.activity.NavigationActivity) Activity(android.app.Activity) StatusCallback(com.instructure.canvasapi2.StatusCallback) Fragment(android.support.v4.app.Fragment) InternalWebviewFragment(com.instructure.candroid.fragment.InternalWebviewFragment) QuizStartFragment(com.instructure.candroid.fragment.QuizStartFragment) QuizStartFragment(com.instructure.candroid.fragment.QuizStartFragment) QuizSubmissionResponse(com.instructure.canvasapi2.models.QuizSubmissionResponse) Response(retrofit2.Response) QuizSubmissionQuestionResponse(com.instructure.canvasapi2.models.QuizSubmissionQuestionResponse) QuizSubmit(com.instructure.candroid.interfaces.QuizSubmit) NonNull(android.support.annotation.NonNull) ApiType(com.instructure.canvasapi2.utils.ApiType) NavigationActivity(com.instructure.candroid.activity.NavigationActivity) Nullable(android.support.annotation.Nullable)

Example 2 with QuizSubmissionResponse

use of com.instructure.canvasapi2.models.QuizSubmissionResponse in project instructure-android by instructure.

the class QuizQuestionsFragment method setupCallbacks.

private void setupCallbacks() {
    quizFileUploadListener = new QuizFileUploadListener() {

        @Override
        public void onFileUploadClicked(long quizQuestionId, int position) {
            Bundle bundle = UploadFilesDialog.createQuizFileBundle(quizQuestionId, course.getId(), quiz.getId(), position);
            UploadFilesDialog.show(getFragmentManager(), bundle, new Function1<Integer, Unit>() {

                @Override
                public Unit invoke(Integer integer) {
                    return null;
                }
            });
        }
    };
    quizSubmissionQuestionResponseCanvasCallback = new StatusCallback<QuizSubmissionQuestionResponse>() {

        @Override
        public void onResponse(@NonNull Response<QuizSubmissionQuestionResponse> response, @NonNull LinkHeaders linkHeaders, @NonNull ApiType type) {
            if (type == ApiType.CACHE)
                return;
            List<QuizSubmissionQuestion> questions = response.body().getQuizSubmissionQuestions();
            // sort the questions based on position that is part of the model object
            if (questions != null) {
                Collections.sort(questions, new Comparator<QuizSubmissionQuestion>() {

                    @Override
                    public int compare(QuizSubmissionQuestion lh, QuizSubmissionQuestion rh) {
                        if (lh != null && rh != null) {
                            if (lh.getPosition() < rh.getPosition()) {
                                return -1;
                            } else if (lh.getPosition() > rh.getPosition()) {
                                return 1;
                            }
                        }
                        return 0;
                    }
                });
            }
            if (quizQuestionAdapter == null) {
                quizQuestionAdapter = new QuizSubmissionQuestionListRecyclerAdapter(getActivity(), questions, course, shouldLetAnswer, quizSubmission, quizFileUploadListener);
            } else {
                quizQuestionAdapter.addAll(questions);
            }
            // cache the views after we view them
            recyclerView.setItemViewCacheSize(response.body().getQuizSubmissionQuestions().size());
            recyclerView.setAdapter(quizQuestionAdapter);
            if (linkHeaders.nextUrl != null) {
                QuizManager.getNextPageSubmissionQuestions(linkHeaders.nextUrl, false, quizSubmissionQuestionResponseCanvasCallback);
            }
        }
    };
    submitQuizCallback = new StatusCallback<QuizSubmissionResponse>() {

        @Override
        public void onResponse(@NonNull Response<QuizSubmissionResponse> response, @NonNull LinkHeaders linkHeaders, @NonNull ApiType type) {
            if (type == ApiType.CACHE)
                return;
            switch(auto_submit_reason) {
                case TIMED_QUIZ:
                    showToast(R.string.submitReasonTimedQuiz);
                    break;
                case DUE_DATE:
                    showToast(R.string.quizSubmittedSuccessfully);
                    break;
                case LOCK_DATE:
                    showToast(R.string.submitReasonLockAt);
                    break;
                default:
                    showToast(R.string.quizSubmittedSuccessfully);
            }
            if (chronometer != null) {
                chronometer.stop();
            }
            if (countDownTimer != null) {
                countDownTimer.cancel();
            }
            getActivity().onBackPressed();
        }
    };
    quizSubmissionTimeCanvasCallback = new StatusCallback<QuizSubmissionTime>() {

        @Override
        public void onResponse(@NonNull Response<QuizSubmissionTime> response, @NonNull LinkHeaders linkHeaders, @NonNull ApiType type) {
            if (type == ApiType.CACHE)
                return;
            mQuizSubmissionTime = response.body();
            if (shouldLetAnswer && isAdded()) {
                if (quiz.getTimeLimit() == 0 && quiz.getDueAt() == null && quiz.getLockAt() == null) {
                    normalTimer();
                } else if (quiz.getTimeLimit() > 0) {
                    timeLimitCountDown(mQuizSubmissionTime.getTimeLeft());
                } else if (quiz.getDueAt() != null && (quiz.getLockAt() == null || quiz.getDueAt().before(quiz.getLockAt()))) {
                    // if we have a due date, we want to give them an option to submit it when it gets to that point, but only if the due date is before the lock date
                    auto_submit_reason = AUTO_SUBMIT_REASON.DUE_DATE;
                    countDownForSubmit(mQuizSubmissionTime.getTimeLeft() * MILLISECOND);
                } else if (quiz.getLockAt() != null) {
                    auto_submit_reason = AUTO_SUBMIT_REASON.LOCK_DATE;
                    countDownForSubmit(mQuizSubmissionTime.getTimeLeft() * MILLISECOND);
                }
            } else {
                int minutes = (int) Math.ceil((double) (quizSubmission.getTimeSpent()) / 60);
                chronometer.setVisibility(View.GONE);
                timer.setText(String.format(Locale.getDefault(), getString(R.string.timeSpentFormat), minutes));
            }
        }
    };
}
Also used : QuizSubmissionTime(com.instructure.canvasapi2.models.QuizSubmissionTime) LinkHeaders(com.instructure.canvasapi2.utils.LinkHeaders) Bundle(android.os.Bundle) QuizFileUploadListener(com.instructure.candroid.interfaces.QuizFileUploadListener) Function1(kotlin.jvm.functions.Function1) Comparator(java.util.Comparator) QuizSubmissionQuestion(com.instructure.canvasapi2.models.QuizSubmissionQuestion) ApiType(com.instructure.canvasapi2.utils.ApiType) QuizSubmissionQuestionResponse(com.instructure.canvasapi2.models.QuizSubmissionQuestionResponse) List(java.util.List) ArrayList(java.util.ArrayList) QuizSubmissionQuestionListRecyclerAdapter(com.instructure.candroid.adapter.QuizSubmissionQuestionListRecyclerAdapter) QuizSubmissionResponse(com.instructure.canvasapi2.models.QuizSubmissionResponse)

Example 3 with QuizSubmissionResponse

use of com.instructure.canvasapi2.models.QuizSubmissionResponse in project instructure-android by instructure.

the class QuizStartFragment method setupCallbacks.

private void setupCallbacks() {
    webViewClientCallback = new CanvasWebView.CanvasWebViewClientCallback() {

        @Override
        public void openMediaFromWebView(String mime, String url, String filename) {
            openMedia(mime, url, filename);
        }

        @Override
        public void onPageFinishedCallback(WebView webView, String url) {
        }

        @Override
        public void onPageStartedCallback(WebView webView, String url) {
        }

        @Override
        public boolean canRouteInternallyDelegate(String url) {
            return RouterUtils.canRouteInternally(null, url, ApiPrefs.getDomain(), false);
        }

        @Override
        public void routeInternallyCallback(String url) {
            RouterUtils.canRouteInternally(getActivity(), url, ApiPrefs.getDomain(), true);
        }
    };
    embeddedWebViewCallback = new CanvasWebView.CanvasEmbeddedWebViewCallback() {

        @Override
        public void launchInternalWebViewFragment(String url) {
            InternalWebviewFragment.Companion.loadInternalWebView(getActivity(), getNavigation(), InternalWebviewFragment.Companion.createBundle(course, url, false));
        }

        @Override
        public boolean shouldLaunchInternalWebViewFragment(String url) {
            return true;
        }
    };
    quizSubmissionTimeCanvasCallback = new StatusCallback<QuizSubmissionTime>() {

        @Override
        public void onResponse(@NonNull Response<QuizSubmissionTime> response, @NonNull LinkHeaders linkHeaders, @NonNull ApiType type) {
            if (type == ApiType.CACHE)
                return;
            QuizStartFragment.this.quizSubmissionTime = quizSubmissionTime;
            QuizManager.getQuizSubmissions(course, quiz.getId(), true, quizSubmissionResponseCanvasCallback);
        }
    };
    quizSubmissionResponseCanvasCallback = new StatusCallback<QuizSubmissionResponse>() {

        @Override
        public void onResponse(@NonNull Response<QuizSubmissionResponse> response, @NonNull LinkHeaders linkHeaders, @NonNull ApiType type) {
            if (type == ApiType.CACHE)
                return;
            final QuizSubmissionResponse quizSubmissionResponse = response.body();
            // since this is a student app, make sure they only have their own submissions (if they're siteadmin it'll be different)
            final ArrayList<QuizSubmission> submissions = new ArrayList<>();
            final User user = ApiPrefs.getUser();
            if (user != null) {
                for (QuizSubmission submission : quizSubmissionResponse.getQuizSubmissions()) {
                    if (submission.getUserId() == user.getId()) {
                        submissions.add(submission);
                    }
                }
            }
            quizSubmissionResponse.setQuizSubmissions(submissions);
            if (quizSubmissionResponse.getQuizSubmissions() == null || quizSubmissionResponse.getQuizSubmissions().size() == 0) {
                // No quiz submissions, let the user start the quiz.
                // They haven't turned it in yet, so don't show the turned-in view
                quizTurnedInContainer.setVisibility(View.GONE);
                shouldStartQuiz = true;
                next.setVisibility(View.VISIBLE);
                next.setEnabled(true);
            } else {
                // We should have at least 1 submission
                quizSubmission = quizSubmissionResponse.getQuizSubmissions().get(quizSubmissionResponse.getQuizSubmissions().size() - 1);
                next.setEnabled(true);
                final boolean hasUnlimitedAttempts = quiz.getAllowedAttempts() == -1;
                // Teacher can manually unlock a quiz for an individual student
                final boolean teacherUnlockedQuizAttempts = quizSubmission.isManuallyUnlocked();
                final boolean hasMoreAttemptsLeft = quizSubmission.getAttemptsLeft() > 0;
                final boolean canTakeQuizAgain = hasUnlimitedAttempts | teacherUnlockedQuizAttempts | hasMoreAttemptsLeft;
                if (quiz.getHideResults() == Quiz.HIDE_RESULTS_TYPE.ALWAYS && !canTakeQuizAgain) {
                    // Don't let the user see the questions if they've exceeded their attempts
                    next.setVisibility(View.GONE);
                } else if (quiz.getHideResults() == Quiz.HIDE_RESULTS_TYPE.AFTER_LAST_ATTEMPT && !canTakeQuizAgain) {
                    // They can only see the results after their last attempt, and that hasn't happened yet
                    next.setVisibility(View.GONE);
                }
                // -1 allowed attempts == unlimited
                if (quizSubmission.getFinishedAt() != null && !canTakeQuizAgain) {
                    // They've finished the quiz and they can't take it anymore; let them see results
                    next.setVisibility(View.VISIBLE);
                    next.setText(getString(R.string.viewQuestions));
                    shouldLetAnswer = false;
                } else {
                    // They are allowed to take the quiz...
                    next.setVisibility(View.VISIBLE);
                    if (quizSubmission.getFinishedAt() != null) {
                        shouldStartQuiz = true;
                        next.setText(getString(R.string.takeQuizAgain));
                    } else {
                        // Let the user resume their quiz
                        next.setText(getString(R.string.resumeQuiz));
                    }
                }
                if (quizSubmission.getFinishedAt() != null) {
                    quizTurnedIn.setText(getString(R.string.turnedIn));
                    quizTurnedInDetails.setText(DateHelper.getDateTimeString(getActivity(), quizSubmission.getFinishedAt()));
                    // The user has turned in the quiz, let them see the results
                    viewResults.setVisibility(View.VISIBLE);
                } else {
                    quizTurnedInContainer.setVisibility(View.GONE);
                }
                // Weird hack where if the time expires and the user hasn't submitted it doesn't let you start the quiz
                if (quizSubmission.getWorkflowState() == QuizSubmission.WORKFLOW_STATE.UNTAKEN && (quizSubmission.getEndAt() != null && (quizSubmissionTime != null && quizSubmissionTime.getTimeLeft() > 0))) {
                    next.setEnabled(false);
                    // submit the quiz for them
                    QuizManager.submitQuiz(course, quizSubmission, true, new StatusCallback<QuizSubmissionResponse>() {

                        @Override
                        public void onResponse(@NonNull Response<QuizSubmissionResponse> response, @NonNull LinkHeaders linkHeaders, @NonNull ApiType type) {
                            if (type == ApiType.CACHE)
                                return;
                            // the user has turned in the quiz, let them see the results
                            viewResults.setVisibility(View.VISIBLE);
                            next.setEnabled(true);
                            shouldStartQuiz = true;
                            next.setText(getString(R.string.takeQuizAgain));
                            QuizSubmissionResponse quizResponse = response.body();
                            // Since this is a student app, make sure they only have their own submissions (if they're siteadmin it'll be different)
                            final ArrayList<QuizSubmission> submissions = new ArrayList<>();
                            final User user = ApiPrefs.getUser();
                            if (user != null) {
                                for (QuizSubmission submission : quizResponse.getQuizSubmissions()) {
                                    if (submission.getUserId() == user.getId()) {
                                        submissions.add(submission);
                                    }
                                }
                            }
                            quizResponse.setQuizSubmissions(submissions);
                            if (quizResponse.getQuizSubmissions() != null && quizResponse.getQuizSubmissions().size() > 0) {
                                quizSubmission = quizResponse.getQuizSubmissions().get(quizResponse.getQuizSubmissions().size() - 1);
                            }
                        }
                    });
                }
                // If the user can only see results once and they have seen it, don't let them view the questions
                if (quiz.isOneTimeResults() && quizSubmission.hasSeenResults()) {
                    next.setVisibility(View.GONE);
                }
                if (quiz.isLockedForUser()) {
                    shouldStartQuiz = false;
                    next.setText(getString(R.string.assignmentLocked));
                }
            }
            populateQuizInfo();
            canvasLoading.setVisibility(View.GONE);
        }

        @Override
        public void onFail(@Nullable Call<QuizSubmissionResponse> call, @NonNull Throwable error, @Nullable Response response) {
            canvasLoading.setVisibility(View.GONE);
            // on quizzes.
            if (response != null && response.code() == 401) {
                populateQuizInfo();
                // there is a not authorized error, so don't let them start the quiz
                next.setVisibility(View.GONE);
            }
        }
    };
    quizStartResponseCallback = new StatusCallback<QuizSubmissionResponse>() {

        @Override
        public void onResponse(@NonNull Response<QuizSubmissionResponse> response, @NonNull LinkHeaders linkHeaders, @NonNull ApiType type) {
            if (response.code() == 200 && type == ApiType.API) {
                // We want to show the quiz here, but we need to get the quizSubmissionId first so our
                // api call for the QuizQuestionsFragment knows which questions to get
                StatusCallback<QuizSubmissionResponse> quizSubmissionResponseCallback = new StatusCallback<QuizSubmissionResponse>() {

                    @Override
                    public void onResponse(@NonNull Response<QuizSubmissionResponse> response, @NonNull LinkHeaders linkHeaders, @NonNull ApiType type) {
                        QuizSubmissionResponse quizSubmissionResponse = response.body();
                        if (quizSubmissionResponse != null && quizSubmissionResponse.getQuizSubmissions() != null && quizSubmissionResponse.getQuizSubmissions().size() > 0) {
                            quizSubmission = quizSubmissionResponse.getQuizSubmissions().get(quizSubmissionResponse.getQuizSubmissions().size() - 1);
                            if (quizSubmission != null) {
                                showQuiz();
                            } else {
                                getLockedMessage();
                            }
                        }
                    }
                };
                QuizManager.getFirstPageQuizSubmissions(course, quiz.getId(), false, quizSubmissionResponseCallback);
            }
        }

        @Override
        public void onFail(@Nullable Call<QuizSubmissionResponse> call, @NonNull Throwable error, @Nullable Response response) {
            if (response != null && response.code() == 403) {
                // Forbidden
                // Check to see if it's because of IP restriction or bad access code or either
                getLockedMessage();
            }
        }
    };
    quizStartSessionCallback = new StatusCallback<ResponseBody>() {
    };
}
Also used : User(com.instructure.canvasapi2.models.User) ArrayList(java.util.ArrayList) QuizSubmission(com.instructure.canvasapi2.models.QuizSubmission) ApiType(com.instructure.canvasapi2.utils.ApiType) NonNull(android.support.annotation.NonNull) CanvasWebView(com.instructure.pandautils.views.CanvasWebView) WebView(android.webkit.WebView) QuizSubmissionTime(com.instructure.canvasapi2.models.QuizSubmissionTime) LinkHeaders(com.instructure.canvasapi2.utils.LinkHeaders) StatusCallback(com.instructure.canvasapi2.StatusCallback) ResponseBody(okhttp3.ResponseBody) Response(retrofit2.Response) QuizSubmissionResponse(com.instructure.canvasapi2.models.QuizSubmissionResponse) CanvasWebView(com.instructure.pandautils.views.CanvasWebView) QuizSubmissionResponse(com.instructure.canvasapi2.models.QuizSubmissionResponse)

Example 4 with QuizSubmissionResponse

use of com.instructure.canvasapi2.models.QuizSubmissionResponse in project instructure-android by instructure.

the class QuizManager_Test method getQuizSubmissions.

public static void getQuizSubmissions(StatusCallback<QuizSubmissionResponse> callback) {
    Response response = new Response.Builder().code(200).message("todo").protocol(Protocol.HTTP_1_0).body(ResponseBody.create(MediaType.parse("application/json"), "todo".getBytes())).addHeader("content-type", "application/json").build();
    List<QuizSubmission> quizSubmissions = new ArrayList<>();
    QuizSubmission quizSubmission = new QuizSubmission();
    quizSubmission.setQuizId(456321L);
    quizSubmissions.add(quizSubmission);
    QuizSubmissionResponse quizSubmissionResponse = new QuizSubmissionResponse();
    quizSubmissionResponse.setQuizSubmissions(quizSubmissions);
    retrofit2.Response<QuizSubmissionResponse> response1 = retrofit2.Response.success(quizSubmissionResponse, response);
    callback.onResponse(response1, new LinkHeaders(), ApiType.CACHE);
}
Also used : QuizSubmissionResponse(com.instructure.canvasapi2.models.QuizSubmissionResponse) Response(okhttp3.Response) QuizSubmissionQuestionResponse(com.instructure.canvasapi2.models.QuizSubmissionQuestionResponse) QuizSubmission(com.instructure.canvasapi2.models.QuizSubmission) LinkHeaders(com.instructure.canvasapi2.utils.LinkHeaders) ArrayList(java.util.ArrayList) QuizSubmissionResponse(com.instructure.canvasapi2.models.QuizSubmissionResponse)

Example 5 with QuizSubmissionResponse

use of com.instructure.canvasapi2.models.QuizSubmissionResponse in project instructure-android by instructure.

the class QuizManager method getFirstPageQuizSubmissions.

public static void getFirstPageQuizSubmissions(CanvasContext canvasContext, long quizId, final boolean forceNetwork, final StatusCallback<QuizSubmissionResponse> callback) {
    final RestBuilder adapter = new RestBuilder(callback);
    final RestParams params = new RestParams.Builder().withPerPageQueryParam(true).withShouldIgnoreToken(false).withForceReadFromNetwork(forceNetwork).build();
    QuizAPI.getFirstPageQuizSubmissions(canvasContext, quizId, adapter, params, callback);
}
Also used : RestParams(com.instructure.canvasapi2.builders.RestParams) RestBuilder(com.instructure.canvasapi2.builders.RestBuilder) RestBuilder(com.instructure.canvasapi2.builders.RestBuilder)

Aggregations

RestBuilder (com.instructure.canvasapi2.builders.RestBuilder)7 RestParams (com.instructure.canvasapi2.builders.RestParams)7 QuizSubmissionResponse (com.instructure.canvasapi2.models.QuizSubmissionResponse)6 LinkHeaders (com.instructure.canvasapi2.utils.LinkHeaders)5 QuizSubmission (com.instructure.canvasapi2.models.QuizSubmission)4 QuizSubmissionQuestionResponse (com.instructure.canvasapi2.models.QuizSubmissionQuestionResponse)4 ArrayList (java.util.ArrayList)4 StatusCallback (com.instructure.canvasapi2.StatusCallback)3 ApiType (com.instructure.canvasapi2.utils.ApiType)3 NonNull (android.support.annotation.NonNull)2 QuizSubmissionTime (com.instructure.canvasapi2.models.QuizSubmissionTime)2 Response (okhttp3.Response)2 Response (retrofit2.Response)2 Activity (android.app.Activity)1 Bundle (android.os.Bundle)1 Nullable (android.support.annotation.Nullable)1 Fragment (android.support.v4.app.Fragment)1 FragmentActivity (android.support.v4.app.FragmentActivity)1 WebView (android.webkit.WebView)1 NavigationActivity (com.instructure.candroid.activity.NavigationActivity)1