forked from CIT/Vmeda.Online
		
	MOBILE-2334 assign: Fix errors with offline and sync
This commit is contained in:
		
							parent
							
								
									dc74546f3d
								
							
						
					
					
						commit
						ae290c3c05
					
				@ -105,6 +105,9 @@ export class AddonModAssignIndexComponent extends CoreCourseModuleMainActivityCo
 | 
			
		||||
            if (this.assign && data.assignmentId == this.assign.id && data.userId == this.userId) {
 | 
			
		||||
                // Assignment submitted, check completion.
 | 
			
		||||
                this.courseProvider.checkModuleCompletion(this.courseId, this.module.completionstatus);
 | 
			
		||||
 | 
			
		||||
                // Reload data since it can have offline data now.
 | 
			
		||||
                this.showLoadingAndRefresh(true, false);
 | 
			
		||||
            }
 | 
			
		||||
        }, this.siteId);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -200,7 +200,7 @@ export class AddonModAssignSubmissionComponent implements OnInit, OnDestroy {
 | 
			
		||||
     */
 | 
			
		||||
    copyPrevious(): void {
 | 
			
		||||
        if (!this.appProvider.isOnline()) {
 | 
			
		||||
            this.domUtils.showErrorModal('mm.core.networkerrormsg', true);
 | 
			
		||||
            this.domUtils.showErrorModal('core.networkerrormsg', true);
 | 
			
		||||
 | 
			
		||||
            return;
 | 
			
		||||
        }
 | 
			
		||||
@ -229,9 +229,6 @@ export class AddonModAssignSubmissionComponent implements OnInit, OnDestroy {
 | 
			
		||||
                // Now go to edit.
 | 
			
		||||
                this.goToEdit();
 | 
			
		||||
 | 
			
		||||
                // Invalidate and refresh data to update this view.
 | 
			
		||||
                this.invalidateAndRefresh();
 | 
			
		||||
 | 
			
		||||
                if (!this.assign.submissiondrafts) {
 | 
			
		||||
                    // No drafts allowed, so it was submitted. Trigger event.
 | 
			
		||||
                    this.eventsProvider.trigger(AddonModAssignProvider.SUBMITTED_FOR_GRADING_EVENT, {
 | 
			
		||||
@ -239,12 +236,17 @@ export class AddonModAssignSubmissionComponent implements OnInit, OnDestroy {
 | 
			
		||||
                        submissionId: this.userSubmission.id,
 | 
			
		||||
                        userId: this.currentUserId
 | 
			
		||||
                    }, this.siteId);
 | 
			
		||||
                } else {
 | 
			
		||||
                    // Invalidate and refresh data to update this view.
 | 
			
		||||
                    this.invalidateAndRefresh();
 | 
			
		||||
                }
 | 
			
		||||
            }).catch((error) => {
 | 
			
		||||
                this.domUtils.showErrorModalDefault(error, 'core.error', true);
 | 
			
		||||
            }).finally(() => {
 | 
			
		||||
                modal.dismiss();
 | 
			
		||||
            });
 | 
			
		||||
        }).catch(() => {
 | 
			
		||||
            // Cancelled.
 | 
			
		||||
        });
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@ -382,7 +384,7 @@ export class AddonModAssignSubmissionComponent implements OnInit, OnDestroy {
 | 
			
		||||
 | 
			
		||||
            // Check if there's any offline data for this submission.
 | 
			
		||||
            promises.push(this.assignOfflineProvider.getSubmission(assign.id, this.submitId).then((data) => {
 | 
			
		||||
                this.hasOffline = data && data.plugindata && Object.keys(data.plugindata).length > 0;
 | 
			
		||||
                this.hasOffline = data && data.pluginData && Object.keys(data.pluginData).length > 0;
 | 
			
		||||
                this.submittedOffline = data && data.submitted;
 | 
			
		||||
            }).catch(() => {
 | 
			
		||||
                // No offline data found.
 | 
			
		||||
@ -505,6 +507,9 @@ export class AddonModAssignSubmissionComponent implements OnInit, OnDestroy {
 | 
			
		||||
                return;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            // Make sure outcomes is an array.
 | 
			
		||||
            gradeInfo.outcomes = gradeInfo.outcomes || [];
 | 
			
		||||
 | 
			
		||||
            if (!this.isDestroyed) {
 | 
			
		||||
                // Block the assignment.
 | 
			
		||||
                this.syncProvider.blockOperation(AddonModAssignProvider.COMPONENT, this.assign.id);
 | 
			
		||||
@ -556,8 +561,8 @@ export class AddonModAssignSubmissionComponent implements OnInit, OnDestroy {
 | 
			
		||||
                            this.originalGrades.grade = this.grade.grade;
 | 
			
		||||
                        }
 | 
			
		||||
 | 
			
		||||
                        this.grade.applyToAll = data.applytoall;
 | 
			
		||||
                        this.grade.addAttempt = data.addattempt;
 | 
			
		||||
                        this.grade.applyToAll = data.applyToAll;
 | 
			
		||||
                        this.grade.addAttempt = data.addAttempt;
 | 
			
		||||
                        this.originalGrades.applyToAll = this.grade.applyToAll;
 | 
			
		||||
                        this.originalGrades.addAttempt = this.grade.addAttempt;
 | 
			
		||||
 | 
			
		||||
@ -600,7 +605,7 @@ export class AddonModAssignSubmissionComponent implements OnInit, OnDestroy {
 | 
			
		||||
     * @param {any} status Submission status.
 | 
			
		||||
     */
 | 
			
		||||
    protected setStatusNameAndClass(status: any): void {
 | 
			
		||||
        if (this.hasOffline) {
 | 
			
		||||
        if (this.hasOffline || this.submittedOffline) {
 | 
			
		||||
            // Offline data.
 | 
			
		||||
            this.statusTranslated = this.translate.instant('core.notsent');
 | 
			
		||||
            this.statusColor = 'warning';
 | 
			
		||||
@ -669,9 +674,6 @@ export class AddonModAssignSubmissionComponent implements OnInit, OnDestroy {
 | 
			
		||||
            this.assignProvider.submitForGrading(this.assign.id, this.courseId, acceptStatement, this.userSubmission.timemodified,
 | 
			
		||||
                    this.hasOffline).then(() => {
 | 
			
		||||
 | 
			
		||||
                // Invalidate and refresh data.
 | 
			
		||||
                this.invalidateAndRefresh();
 | 
			
		||||
 | 
			
		||||
                // Submitted, trigger event.
 | 
			
		||||
                this.eventsProvider.trigger(AddonModAssignProvider.SUBMITTED_FOR_GRADING_EVENT, {
 | 
			
		||||
                    assignmentId: this.assign.id,
 | 
			
		||||
 | 
			
		||||
@ -128,13 +128,13 @@ export class AddonModAssignFeedbackCommentsComponent extends AddonModAssignFeedb
 | 
			
		||||
                return this.assignOfflineProvider.getSubmissionGrade(this.assign.id, this.userId).catch(() => {
 | 
			
		||||
                    // No offline data found.
 | 
			
		||||
                }).then((offlineData) => {
 | 
			
		||||
                    if (offlineData && offlineData.plugindata && offlineData.plugindata.assignfeedbackcomments_editor) {
 | 
			
		||||
                    if (offlineData && offlineData.pluginData && offlineData.pluginData.assignfeedbackcomments_editor) {
 | 
			
		||||
                        // Save offline as draft.
 | 
			
		||||
                        this.isSent = false;
 | 
			
		||||
                        this.feedbackDelegate.saveFeedbackDraft(this.assign.id, this.userId, this.plugin,
 | 
			
		||||
                                offlineData.plugindata.assignfeedbackcomments_editor);
 | 
			
		||||
                                offlineData.pluginData.assignfeedbackcomments_editor);
 | 
			
		||||
 | 
			
		||||
                        return offlineData.plugindata.assignfeedbackcomments_editor.text;
 | 
			
		||||
                        return offlineData.pluginData.assignfeedbackcomments_editor.text;
 | 
			
		||||
                    }
 | 
			
		||||
 | 
			
		||||
                    // No offline data found, return online text.
 | 
			
		||||
 | 
			
		||||
@ -46,7 +46,6 @@ export class AddonModAssignFeedbackCommentsHandler implements AddonModAssignFeed
 | 
			
		||||
     */
 | 
			
		||||
    discardDraft(assignId: number, userId: number, siteId?: string): void | Promise<any> {
 | 
			
		||||
        const id = this.getDraftId(assignId, userId, siteId);
 | 
			
		||||
 | 
			
		||||
        if (typeof this.drafts[id] != 'undefined') {
 | 
			
		||||
            delete this.drafts[id];
 | 
			
		||||
        }
 | 
			
		||||
@ -129,8 +128,8 @@ export class AddonModAssignFeedbackCommentsHandler implements AddonModAssignFeed
 | 
			
		||||
        return this.assignOfflineProvider.getSubmissionGrade(assign.id, userId).catch(() => {
 | 
			
		||||
            // No offline data found.
 | 
			
		||||
        }).then((data) => {
 | 
			
		||||
            if (data && data.plugindata && data.plugindata.assignfeedbackcomments_editor) {
 | 
			
		||||
                return data.plugindata.assignfeedbackcomments_editor.text;
 | 
			
		||||
            if (data && data.pluginData && data.pluginData.assignfeedbackcomments_editor) {
 | 
			
		||||
                return data.pluginData.assignfeedbackcomments_editor.text;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            // No offline data found, get text from plugin.
 | 
			
		||||
@ -172,15 +171,6 @@ export class AddonModAssignFeedbackCommentsHandler implements AddonModAssignFeed
 | 
			
		||||
        return true;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Whether or not the handler is enabled for edit on a site level.
 | 
			
		||||
     *
 | 
			
		||||
     * @return {boolean|Promise<boolean>} Whether or not the handler is enabled for edit on a site level.
 | 
			
		||||
     */
 | 
			
		||||
    isEnabledForEdit(): boolean | Promise<boolean> {
 | 
			
		||||
        return true;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Prepare and add to pluginData the data to send to the server based on the draft data saved.
 | 
			
		||||
     *
 | 
			
		||||
 | 
			
		||||
@ -17,7 +17,10 @@
 | 
			
		||||
                <!-- Submission statement. -->
 | 
			
		||||
                <ion-item text-wrap *ngIf="submissionStatement">
 | 
			
		||||
                    <ion-label><core-format-text [text]="submissionStatement"></core-format-text></ion-label>
 | 
			
		||||
                    <ion-checkbox item-end name="submissionstatement"></ion-checkbox>
 | 
			
		||||
                    <ion-checkbox item-end name="submissionstatement" [(ngModel)]="submissionStatementAccepted"></ion-checkbox>
 | 
			
		||||
 | 
			
		||||
                    <!-- ion-checkbox doesn't use an input. Create a hidden input to hold the value. -->
 | 
			
		||||
                    <input item-content type="hidden" [ngModel]="submissionStatementAccepted" name="submissionstatement">
 | 
			
		||||
                </ion-item>
 | 
			
		||||
 | 
			
		||||
                <addon-mod-assign-submission-plugin *ngFor="let plugin of userSubmission.plugins" [assign]="assign" [submission]="userSubmission" [plugin]="plugin" [edit]="true" [allowOffline]="allowOffline"></addon-mod-assign-submission-plugin>
 | 
			
		||||
 | 
			
		||||
@ -40,6 +40,7 @@ export class AddonModAssignEditPage implements OnInit, OnDestroy {
 | 
			
		||||
    userSubmission: any; // The user submission.
 | 
			
		||||
    allowOffline: boolean; // Whether offline is allowed.
 | 
			
		||||
    submissionStatement: string; // The submission statement.
 | 
			
		||||
    submissionStatementAccepted: boolean; // Whether submission statement is accepted.
 | 
			
		||||
    loaded: boolean; // Whether data has been loaded.
 | 
			
		||||
 | 
			
		||||
    protected moduleId: number; // Module ID the submission belongs to.
 | 
			
		||||
@ -125,14 +126,17 @@ export class AddonModAssignEditPage implements OnInit, OnDestroy {
 | 
			
		||||
                return this.assignProvider.getSubmissionStatus(this.assign.id, this.userId, this.isBlind).then((response) => {
 | 
			
		||||
                    const userSubmission = this.assignProvider.getSubmissionObjectFromAttempt(this.assign, response.lastattempt);
 | 
			
		||||
 | 
			
		||||
                    if (this.assignHelper.canEditSubmissionOffline(this.assign, userSubmission)) {
 | 
			
		||||
                        return response;
 | 
			
		||||
                    }
 | 
			
		||||
                    // Check if the user can edit it in offline.
 | 
			
		||||
                    return this.assignHelper.canEditSubmissionOffline(this.assign, userSubmission).then((canEditOffline) => {
 | 
			
		||||
                        if (canEditOffline) {
 | 
			
		||||
                            return response;
 | 
			
		||||
                        }
 | 
			
		||||
 | 
			
		||||
                    // Submission cannot be edited in offline, reject.
 | 
			
		||||
                    this.allowOffline = false;
 | 
			
		||||
                        // Submission cannot be edited in offline, reject.
 | 
			
		||||
                        this.allowOffline = false;
 | 
			
		||||
 | 
			
		||||
                    return Promise.reject(err);
 | 
			
		||||
                        return Promise.reject(err);
 | 
			
		||||
                    });
 | 
			
		||||
                });
 | 
			
		||||
            }).then((response) => {
 | 
			
		||||
                if (!response.lastattempt.canedit) {
 | 
			
		||||
@ -152,7 +156,7 @@ export class AddonModAssignEditPage implements OnInit, OnDestroy {
 | 
			
		||||
 | 
			
		||||
                // Check if there's any offline data for this submission.
 | 
			
		||||
                return this.assignOfflineProvider.getSubmission(this.assign.id, this.userId).then((data) => {
 | 
			
		||||
                    this.hasOffline = data && data.plugindata && Object.keys(data.plugindata).length > 0;
 | 
			
		||||
                    this.hasOffline = data && data.pluginData && Object.keys(data.pluginData).length > 0;
 | 
			
		||||
                }).catch(() => {
 | 
			
		||||
                    // No offline data found.
 | 
			
		||||
                    this.hasOffline = false;
 | 
			
		||||
@ -262,7 +266,7 @@ export class AddonModAssignEditPage implements OnInit, OnDestroy {
 | 
			
		||||
    protected saveSubmission(): Promise<any> {
 | 
			
		||||
        const inputData = this.getInputData();
 | 
			
		||||
 | 
			
		||||
        if (this.submissionStatement && !inputData.submissionstatement) {
 | 
			
		||||
        if (this.submissionStatement && (!inputData.submissionstatement || inputData.submissionstatement === 'false')) {
 | 
			
		||||
            return Promise.reject(this.translate.instant('addon.mod_assign.acceptsubmissionstatement'));
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -218,7 +218,7 @@ export class AddonModAssignSubmissionListPage implements OnInit, OnDestroy {
 | 
			
		||||
     * @param {any} submission The submission to load.
 | 
			
		||||
     */
 | 
			
		||||
    loadSubmission(submission: any): void {
 | 
			
		||||
        if (this.selectedSubmissionId === submission.id) {
 | 
			
		||||
        if (this.selectedSubmissionId === submission.id && this.splitviewCtrl.isOn()) {
 | 
			
		||||
            // Already selected.
 | 
			
		||||
            return;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
@ -412,7 +412,6 @@ export class AddonModAssignOfflineProvider {
 | 
			
		||||
                return {
 | 
			
		||||
                    assignId: assignId,
 | 
			
		||||
                    courseId: courseId,
 | 
			
		||||
                    pluginData: '{}',
 | 
			
		||||
                    userId: userId,
 | 
			
		||||
                    onlineTimemodified: timemodified,
 | 
			
		||||
                    timecreated: now,
 | 
			
		||||
@ -420,8 +419,9 @@ export class AddonModAssignOfflineProvider {
 | 
			
		||||
                };
 | 
			
		||||
            }).then((submission) => {
 | 
			
		||||
                // Mark the submission.
 | 
			
		||||
                submission.submitted = !!submitted;
 | 
			
		||||
                submission.submissionstatement = !!acceptStatement;
 | 
			
		||||
                submission.submitted = submitted ? 1 : 0;
 | 
			
		||||
                submission.submissionStatement = acceptStatement ? 1 : 0;
 | 
			
		||||
                submission.pluginData = submission.pluginData ? JSON.stringify(submission.pluginData) : '{}';
 | 
			
		||||
 | 
			
		||||
                return site.getDb().insertRecord(this.SUBMISSIONS_TABLE, submission);
 | 
			
		||||
            });
 | 
			
		||||
@ -452,7 +452,7 @@ export class AddonModAssignOfflineProvider {
 | 
			
		||||
                    courseId: courseId,
 | 
			
		||||
                    pluginData: pluginData ? JSON.stringify(pluginData) : '{}',
 | 
			
		||||
                    userId: userId,
 | 
			
		||||
                    submitted: !!submitted,
 | 
			
		||||
                    submitted: submitted ? 1 : 0,
 | 
			
		||||
                    timecreated: now,
 | 
			
		||||
                    timemodified: now,
 | 
			
		||||
                    onlineTimemodified: timemodified
 | 
			
		||||
@ -489,9 +489,9 @@ export class AddonModAssignOfflineProvider {
 | 
			
		||||
                    courseId: courseId,
 | 
			
		||||
                    grade: grade,
 | 
			
		||||
                    attemptNumber: attemptNumber,
 | 
			
		||||
                    addAttempt: !!addAttempt,
 | 
			
		||||
                    addAttempt: addAttempt ? 1 : 0,
 | 
			
		||||
                    workflowState: workflowState,
 | 
			
		||||
                    applyToAll: !!applyToAll,
 | 
			
		||||
                    applyToAll: applyToAll ? 1 : 0,
 | 
			
		||||
                    outcomes: outcomes ? JSON.stringify(outcomes) : '{}',
 | 
			
		||||
                    pluginData: pluginData ? JSON.stringify(pluginData) : '{}',
 | 
			
		||||
                    timemodified: now
 | 
			
		||||
 | 
			
		||||
@ -213,7 +213,7 @@ export class AddonModAssignSyncProvider extends CoreSyncBaseProvider {
 | 
			
		||||
                return Promise.reject(null);
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            courseId = submissions.length > 0 ? submissions[0].courseid : grades[0].courseid;
 | 
			
		||||
            courseId = submissions.length > 0 ? submissions[0].courseId : grades[0].courseId;
 | 
			
		||||
 | 
			
		||||
            return this.assignProvider.getAssignmentById(courseId, assignId, siteId).then((assignData) => {
 | 
			
		||||
                assign = assignData;
 | 
			
		||||
 | 
			
		||||
@ -200,7 +200,12 @@ export class AddonModAssignProvider {
 | 
			
		||||
 | 
			
		||||
            return site.read('mod_assign_get_user_mappings', params, preSets).then((response) => {
 | 
			
		||||
                // Search the user.
 | 
			
		||||
                if (userId && userId > 0 && response.assignments && response.assignments.length) {
 | 
			
		||||
                if (response.assignments && response.assignments.length) {
 | 
			
		||||
                    if (!userId || userId < 0) {
 | 
			
		||||
                        // User not valid, stop.
 | 
			
		||||
                        return -1;
 | 
			
		||||
                    }
 | 
			
		||||
 | 
			
		||||
                    const assignment = response.assignments[0];
 | 
			
		||||
 | 
			
		||||
                    if (assignment.assignmentid == assignId) {
 | 
			
		||||
@ -212,6 +217,8 @@ export class AddonModAssignProvider {
 | 
			
		||||
                            }
 | 
			
		||||
                        }
 | 
			
		||||
                    }
 | 
			
		||||
                } else if (response.warnings && response.warnings.length) {
 | 
			
		||||
                    return Promise.reject(response.warnings[0]);
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                return Promise.reject(null);
 | 
			
		||||
 | 
			
		||||
@ -95,12 +95,4 @@ export class AddonModAssignDefaultFeedbackHandler implements AddonModAssignFeedb
 | 
			
		||||
    isEnabled(): boolean | Promise<boolean> {
 | 
			
		||||
        return true;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Whether or not the handler is enabled for edit on a site level.
 | 
			
		||||
     * @return {boolean|Promise<boolean>} Whether or not the handler is enabled for edit on a site level.
 | 
			
		||||
     */
 | 
			
		||||
    isEnabledForEdit(): boolean | Promise<boolean> {
 | 
			
		||||
        return false;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -102,13 +102,6 @@ export interface AddonModAssignFeedbackHandler extends CoreDelegateHandler {
 | 
			
		||||
     */
 | 
			
		||||
    hasDraftData?(assignId: number, userId: number, siteId?: string): boolean | Promise<boolean>;
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Whether or not the handler is enabled for edit on a site level.
 | 
			
		||||
     *
 | 
			
		||||
     * @return {boolean|Promise<boolean>} Whether or not the handler is enabled for edit on a site level.
 | 
			
		||||
     */
 | 
			
		||||
    isEnabledForEdit?(): boolean | Promise<boolean>;
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Prefetch any required data for the plugin.
 | 
			
		||||
     * This should NOT prefetch files. Files to be prefetched should be returned by the getPluginFiles function.
 | 
			
		||||
@ -258,16 +251,6 @@ export class AddonModAssignFeedbackDelegate extends CoreDelegate {
 | 
			
		||||
        return this.hasHandler(pluginType, true);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Check if a feedback plugin is supported for edit.
 | 
			
		||||
     *
 | 
			
		||||
     * @param {string} pluginType Type of the plugin.
 | 
			
		||||
     * @return {Promise<boolean>} Whether it's supported for edit.
 | 
			
		||||
     */
 | 
			
		||||
    isPluginSupportedForEdit(pluginType: string): Promise<boolean> {
 | 
			
		||||
        return Promise.resolve(this.executeFunctionOnEnabled(pluginType, 'isEnabledForEdit'));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Prefetch any required data for a feedback plugin.
 | 
			
		||||
     *
 | 
			
		||||
 | 
			
		||||
@ -46,25 +46,32 @@ export class AddonModAssignHelperProvider {
 | 
			
		||||
     * @param {any} submission Submission.
 | 
			
		||||
     * @return {boolean} Whether it can be edited offline.
 | 
			
		||||
     */
 | 
			
		||||
    canEditSubmissionOffline(assign: any, submission: any): boolean {
 | 
			
		||||
    canEditSubmissionOffline(assign: any, submission: any): Promise<boolean> {
 | 
			
		||||
        if (!submission) {
 | 
			
		||||
            return false;
 | 
			
		||||
            return Promise.resolve(false);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (submission.status == AddonModAssignProvider.SUBMISSION_STATUS_NEW ||
 | 
			
		||||
                submission.status == AddonModAssignProvider.SUBMISSION_STATUS_REOPENED) {
 | 
			
		||||
            // It's a new submission, allow creating it in offline.
 | 
			
		||||
            return true;
 | 
			
		||||
            return Promise.resolve(true);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        const promises = [];
 | 
			
		||||
        let canEdit = true;
 | 
			
		||||
 | 
			
		||||
        for (let i = 0; i < submission.plugins.length; i++) {
 | 
			
		||||
            const plugin = submission.plugins[i];
 | 
			
		||||
            if (!this.submissionDelegate.canPluginEditOffline(assign, submission, plugin)) {
 | 
			
		||||
                return false;
 | 
			
		||||
            }
 | 
			
		||||
            promises.push(this.submissionDelegate.canPluginEditOffline(assign, submission, plugin).then((canEditPlugin) => {
 | 
			
		||||
                if (!canEditPlugin) {
 | 
			
		||||
                    canEdit = false;
 | 
			
		||||
                }
 | 
			
		||||
            }));
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        return true;
 | 
			
		||||
        return Promise.all(promises).then(() => {
 | 
			
		||||
            return canEdit;
 | 
			
		||||
        });
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
 | 
			
		||||
@ -153,7 +153,7 @@ export class AddonModAssignPrefetchHandler extends CoreCourseModulePrefetchHandl
 | 
			
		||||
 | 
			
		||||
            if (response.lastattempt) {
 | 
			
		||||
                const userSubmission = this.assignProvider.getSubmissionObjectFromAttempt(assign, response.lastattempt);
 | 
			
		||||
                if (userSubmission) {
 | 
			
		||||
                if (userSubmission && userSubmission.plugins) {
 | 
			
		||||
                    // Add submission plugin files.
 | 
			
		||||
                    userSubmission.plugins.forEach((plugin) => {
 | 
			
		||||
                        promises.push(this.submissionDelegate.getPluginFiles(assign, userSubmission, plugin, siteId));
 | 
			
		||||
@ -161,7 +161,7 @@ export class AddonModAssignPrefetchHandler extends CoreCourseModulePrefetchHandl
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            if (response.feedback) {
 | 
			
		||||
            if (response.feedback && response.feedback.plugins) {
 | 
			
		||||
                // Add feedback plugin files.
 | 
			
		||||
                response.feedback.plugins.forEach((plugin) => {
 | 
			
		||||
                    promises.push(this.feedbackDelegate.getPluginFiles(assign, response, plugin, siteId));
 | 
			
		||||
@ -237,7 +237,9 @@ export class AddonModAssignPrefetchHandler extends CoreCourseModulePrefetchHandl
 | 
			
		||||
                blindMarking = assign.blindmarking && !assign.revealidentities;
 | 
			
		||||
 | 
			
		||||
            if (blindMarking) {
 | 
			
		||||
                subPromises.push(this.assignProvider.getAssignmentUserMappings(assign.id, undefined, siteId));
 | 
			
		||||
                subPromises.push(this.assignProvider.getAssignmentUserMappings(assign.id, undefined, siteId).catch(() => {
 | 
			
		||||
                    // Ignore errors.
 | 
			
		||||
                }));
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            subPromises.push(this.prefetchSubmissions(assign, courseId, module.id, userId, siteId));
 | 
			
		||||
@ -342,9 +344,11 @@ export class AddonModAssignPrefetchHandler extends CoreCourseModulePrefetchHandl
 | 
			
		||||
 | 
			
		||||
            if (userSubmission && userSubmission.id) {
 | 
			
		||||
                // Prefetch submission plugins data.
 | 
			
		||||
                userSubmission.plugins.forEach((plugin) => {
 | 
			
		||||
                    promises.push(this.submissionDelegate.prefetch(assign, userSubmission, plugin, siteId));
 | 
			
		||||
                });
 | 
			
		||||
                if (userSubmission.plugins) {
 | 
			
		||||
                    userSubmission.plugins.forEach((plugin) => {
 | 
			
		||||
                        promises.push(this.submissionDelegate.prefetch(assign, userSubmission, plugin, siteId));
 | 
			
		||||
                    });
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                // Get ID of the user who did the submission.
 | 
			
		||||
                if (userSubmission.userid) {
 | 
			
		||||
@ -365,9 +369,11 @@ export class AddonModAssignPrefetchHandler extends CoreCourseModulePrefetchHandl
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            // Prefetch feedback plugins data.
 | 
			
		||||
            submission.feedback.plugins.forEach((plugin) => {
 | 
			
		||||
                promises.push(this.feedbackDelegate.prefetch(assign, submission, plugin, siteId));
 | 
			
		||||
            });
 | 
			
		||||
            if (submission.feedback.plugins) {
 | 
			
		||||
                submission.feedback.plugins.forEach((plugin) => {
 | 
			
		||||
                    promises.push(this.feedbackDelegate.prefetch(assign, submission, plugin, siteId));
 | 
			
		||||
                });
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // Prefetch user profiles.
 | 
			
		||||
 | 
			
		||||
@ -47,10 +47,10 @@ export class AddonModAssignSubmissionFileComponent extends AddonModAssignSubmiss
 | 
			
		||||
        this.assignOfflineProvider.getSubmission(this.assign.id).catch(() => {
 | 
			
		||||
            // Error getting data, assume there's no offline submission.
 | 
			
		||||
        }).then((offlineData) => {
 | 
			
		||||
            if (offlineData && offlineData.plugindata && offlineData.plugindata.files_filemanager) {
 | 
			
		||||
            if (offlineData && offlineData.pluginData && offlineData.pluginData.files_filemanager) {
 | 
			
		||||
                // It has offline data.
 | 
			
		||||
                let promise;
 | 
			
		||||
                if (offlineData.plugindata.files_filemanager.offline) {
 | 
			
		||||
                if (offlineData.pluginData.files_filemanager.offline) {
 | 
			
		||||
                    promise = this.assignHelper.getStoredSubmissionFiles(this.assign.id,
 | 
			
		||||
                            AddonModAssignSubmissionFileHandler.FOLDER_NAME);
 | 
			
		||||
                } else {
 | 
			
		||||
@ -58,7 +58,7 @@ export class AddonModAssignSubmissionFileComponent extends AddonModAssignSubmiss
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                return promise.then((offlineFiles) => {
 | 
			
		||||
                    const onlineFiles = offlineData.plugindata.files_filemanager.online || [];
 | 
			
		||||
                    const onlineFiles = offlineData.pluginData.files_filemanager.online || [];
 | 
			
		||||
                    offlineFiles = this.fileUploaderProvider.markOfflineFiles(offlineFiles);
 | 
			
		||||
 | 
			
		||||
                    this.files = onlineFiles.concat(offlineFiles);
 | 
			
		||||
 | 
			
		||||
@ -237,9 +237,9 @@ export class AddonModAssignSubmissionFileHandler implements AddonModAssignSubmis
 | 
			
		||||
        return this.assignOfflineProvider.getSubmission(assign.id, submission.userid).catch(() => {
 | 
			
		||||
            // No offline data found.
 | 
			
		||||
        }).then((offlineData) => {
 | 
			
		||||
            if (offlineData && offlineData.plugindata && offlineData.plugindata.files_filemanager) {
 | 
			
		||||
            if (offlineData && offlineData.pluginData && offlineData.pluginData.files_filemanager) {
 | 
			
		||||
                // Has offline data, return the number of files.
 | 
			
		||||
                return offlineData.plugindata.files_filemanager.offline + offlineData.plugindata.files_filemanager.online.length;
 | 
			
		||||
                return offlineData.pluginData.files_filemanager.offline + offlineData.pluginData.files_filemanager.online.length;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            // No offline data, return the number of online files.
 | 
			
		||||
@ -333,7 +333,7 @@ export class AddonModAssignSubmissionFileHandler implements AddonModAssignSubmis
 | 
			
		||||
    prepareSyncData(assign: any, submission: any, plugin: any, offlineData: any, pluginData: any, siteId?: string)
 | 
			
		||||
            : void | Promise<any> {
 | 
			
		||||
 | 
			
		||||
        const filesData = offlineData && offlineData.plugindata && offlineData.plugindata.files_filemanager;
 | 
			
		||||
        const filesData = offlineData && offlineData.pluginData && offlineData.pluginData.files_filemanager;
 | 
			
		||||
        if (filesData) {
 | 
			
		||||
            // Has some data to sync.
 | 
			
		||||
            let files = filesData.online || [],
 | 
			
		||||
 | 
			
		||||
@ -68,8 +68,8 @@ export class AddonModAssignSubmissionOnlineTextComponent extends AddonModAssignS
 | 
			
		||||
            return this.assignOfflineProvider.getSubmission(this.assign.id).catch(() => {
 | 
			
		||||
                // No offline data found.
 | 
			
		||||
            }).then((offlineData) => {
 | 
			
		||||
                if (offlineData && offlineData.plugindata && offlineData.plugindata.onlinetext_editor) {
 | 
			
		||||
                    return offlineData.plugindata.onlinetext_editor.text;
 | 
			
		||||
                if (offlineData && offlineData.pluginData && offlineData.pluginData.onlinetext_editor) {
 | 
			
		||||
                    return offlineData.pluginData.onlinetext_editor.text;
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                // No offline data found, return online text.
 | 
			
		||||
 | 
			
		||||
@ -188,8 +188,8 @@ export class AddonModAssignSubmissionOnlineTextHandler implements AddonModAssign
 | 
			
		||||
        return this.assignOfflineProvider.getSubmission(assign.id, submission.userid).catch(() => {
 | 
			
		||||
            // No offline data found.
 | 
			
		||||
        }).then((data) => {
 | 
			
		||||
            if (data && data.plugindata && data.plugindata.onlinetext_editor) {
 | 
			
		||||
                return data.plugindata.onlinetext_editor.text;
 | 
			
		||||
            if (data && data.pluginData && data.pluginData.onlinetext_editor) {
 | 
			
		||||
                return data.pluginData.onlinetext_editor.text;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            // No offline data found, get text from plugin.
 | 
			
		||||
 | 
			
		||||
@ -128,12 +128,12 @@ export class CoreCourseModuleComponent implements OnInit, OnDestroy {
 | 
			
		||||
        this.spinner = true;
 | 
			
		||||
 | 
			
		||||
        // Get download size to ask for confirm if it's high.
 | 
			
		||||
        this.prefetchHandler.getDownloadSize(module, this.courseId).then((size) => {
 | 
			
		||||
        this.prefetchHandler.getDownloadSize(this.module, this.courseId).then((size) => {
 | 
			
		||||
            return this.courseHelper.prefetchModule(this.prefetchHandler, this.module, size, this.courseId, refresh);
 | 
			
		||||
        }).catch((error) => {
 | 
			
		||||
            // Error, hide spinner.
 | 
			
		||||
            this.spinner = false;
 | 
			
		||||
            if (!this.isDestroyed && error) {
 | 
			
		||||
            if (!this.isDestroyed) {
 | 
			
		||||
                this.domUtils.showErrorModalDefault(error, 'core.errordownloading', true);
 | 
			
		||||
            }
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
@ -426,6 +426,7 @@ export class CoreFileProvider {
 | 
			
		||||
 | 
			
		||||
        return new Promise((resolve, reject): void => {
 | 
			
		||||
            const reader = new FileReader();
 | 
			
		||||
 | 
			
		||||
            reader.onloadend = (evt): void => {
 | 
			
		||||
                const target = <any> evt.target; // Convert to <any> to be able to use non-standard properties.
 | 
			
		||||
                if (target.result !== undefined || target.result !== null) {
 | 
			
		||||
@ -437,6 +438,18 @@ export class CoreFileProvider {
 | 
			
		||||
                }
 | 
			
		||||
            };
 | 
			
		||||
 | 
			
		||||
            // Check if the load starts. If it doesn't start in 3 seconds, reject.
 | 
			
		||||
            // Sometimes in Android the read doesn't start for some reason, so the promise never finishes.
 | 
			
		||||
            let hasStarted = false;
 | 
			
		||||
            reader.onloadstart = (evt): void => {
 | 
			
		||||
                hasStarted = true;
 | 
			
		||||
            };
 | 
			
		||||
            setTimeout(() => {
 | 
			
		||||
                if (!hasStarted) {
 | 
			
		||||
                    reject();
 | 
			
		||||
                }
 | 
			
		||||
            }, 3000);
 | 
			
		||||
 | 
			
		||||
            switch (format) {
 | 
			
		||||
                case CoreFileProvider.FORMATDATAURL:
 | 
			
		||||
                    reader.readAsDataURL(fileData);
 | 
			
		||||
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user