Skip to content

Commit 9a291e4

Browse files
authored
Merge pull request #1821 from dpalou/MOBILE-2915
Mobile 2915
2 parents c0697e4 + 644f3c8 commit 9a291e4

File tree

19 files changed

+147
-92
lines changed

19 files changed

+147
-92
lines changed

scripts/langindex.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1608,6 +1608,7 @@
16081608
"core.remove": "moodle",
16091609
"core.required": "moodle",
16101610
"core.requireduserdatamissing": "local_moodlemobileapp",
1611+
"core.resourcedisplayopen": "moodle",
16111612
"core.resources": "moodle",
16121613
"core.restore": "moodle",
16131614
"core.retry": "local_moodlemobileapp",

src/addon/mod/feedback/components/index/index.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ export class AddonModFeedbackIndexComponent extends CoreCourseModuleMainActivity
3636
@Input() tab = 'overview';
3737
@Input() group = 0;
3838

39+
component = AddonModFeedbackProvider.COMPONENT;
3940
moduleName = 'feedback';
4041

4142
access = {
@@ -67,6 +68,7 @@ export class AddonModFeedbackIndexComponent extends CoreCourseModuleMainActivity
6768
firstSelectedTab: number;
6869

6970
protected submitObserver: any;
71+
protected syncEventName = AddonModFeedbackSyncProvider.AUTO_SYNCED;
7072

7173
constructor(injector: Injector, private feedbackProvider: AddonModFeedbackProvider, @Optional() content: Content,
7274
private feedbackOffline: AddonModFeedbackOfflineProvider, private groupsProvider: CoreGroupsProvider,

src/addon/mod/forum/pages/discussion/discussion.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -357,7 +357,7 @@ export class AddonModForumDiscussionPage implements OnDestroy {
357357
protected syncDiscussion(showErrors: boolean): Promise<any> {
358358
const promises = [];
359359

360-
promises.push(this.forumSync.syncDiscussionReplies(this.forumId, this.discussionId).then((result) => {
360+
promises.push(this.forumSync.syncDiscussionReplies(this.discussionId).then((result) => {
361361
if (result.warnings && result.warnings.length) {
362362
this.domUtils.showErrorModal(result.warnings[0]);
363363
}

src/addon/mod/lesson/components/index/addon-mod-lesson-index.html

Lines changed: 50 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -51,53 +51,64 @@
5151
</ion-card>
5252

5353
<core-loading [hideUntil]="!showSpinner">
54-
<ion-list *ngIf="lesson && (!preventMessages || !preventMessages.length)">
54+
55+
<ion-list *ngIf="(lesson && (!preventMessages || !preventMessages.length)) || retakeToReview">
5556
<ion-item text-wrap *ngIf="retakeToReview">
5657
<!-- A retake was finished in a synchronization, allow reviewing it. -->
57-
<p>{{ 'addon.mod_lesson.retakefinishedinsync' | translate }}</p>
58+
<p padding-bottom>{{ 'addon.mod_lesson.retakefinishedinsync' | translate }}</p>
5859
<a ion-button block (click)="review()">{{ 'addon.mod_lesson.review' | translate }}</a>
5960
</ion-item>
6061

61-
<ion-item text-wrap *ngIf="leftDuringTimed && !lesson.timelimit">
62-
<!-- User left during the session and there is no time limit, ask to continue. -->
63-
<p [innerHTML]="'addon.mod_lesson.youhaveseen' | translate"></p>
64-
<ion-grid>
65-
<ion-row>
66-
<ion-col>
67-
<a ion-button block color="light" (click)="start(false)">{{ 'core.no' | translate }}</a>
68-
</ion-col>
69-
<ion-col>
70-
<a ion-button block (click)="start(true)">{{ 'core.yes' | translate }}</a>
71-
</ion-col>
72-
</ion-row>
73-
</ion-grid>
74-
</ion-item>
62+
<ng-container *ngIf="lesson && (!preventMessages || !preventMessages.length)">
63+
<ion-item text-wrap *ngIf="leftDuringTimed && !lesson.timelimit && !finishedOffline">
64+
<!-- User left during the session and there is no time limit, ask to continue. -->
65+
<p [innerHTML]="'addon.mod_lesson.youhaveseen' | translate"></p>
66+
<ion-grid>
67+
<ion-row>
68+
<ion-col>
69+
<a ion-button block color="light" (click)="start(false)">{{ 'core.no' | translate }}</a>
70+
</ion-col>
71+
<ion-col>
72+
<a ion-button block (click)="start(true)">{{ 'core.yes' | translate }}</a>
73+
</ion-col>
74+
</ion-row>
75+
</ion-grid>
76+
</ion-item>
7577

76-
<ion-item text-wrap *ngIf="leftDuringTimed && lesson.timelimit && lesson.retake">
77-
<!-- User left during the session with time limit and retakes allowed, ask to continue. -->
78-
<p [innerHTML]="'addon.mod_lesson.leftduringtimed' | translate"></p>
79-
<a ion-button block icon-end (click)="start(false)">
80-
{{ 'addon.mod_lesson.continue' | translate }}
81-
<ion-icon name="arrow-forward" md="ios-arrow-forward"></ion-icon>
82-
</a>
83-
</ion-item>
78+
<ion-item text-wrap *ngIf="leftDuringTimed && lesson.timelimit && lesson.retake && !finishedOffline">
79+
<!-- User left during the session with time limit and retakes allowed, ask to continue. -->
80+
<p [innerHTML]="'addon.mod_lesson.leftduringtimed' | translate"></p>
81+
<a ion-button block icon-end (click)="start(false)">
82+
{{ 'addon.mod_lesson.continue' | translate }}
83+
<ion-icon name="arrow-forward" md="ios-arrow-forward"></ion-icon>
84+
</a>
85+
</ion-item>
8486

85-
<ion-item text-wrap *ngIf="leftDuringTimed && lesson.timelimit && !lesson.retake">
86-
<!-- User left during the session with time limit and retakes not allowed. This should be handled by preventMessages -->
87-
<p [innerHTML]="'addon.mod_lesson.leftduringtimednoretake' | translate"></p>
88-
</ion-item>
87+
<ion-item text-wrap *ngIf="leftDuringTimed && lesson.timelimit && !lesson.retake">
88+
<!-- User left during the session with time limit and retakes not allowed. This should be handled by preventMessages -->
89+
<p [innerHTML]="'addon.mod_lesson.leftduringtimednoretake' | translate"></p>
90+
</ion-item>
8991

90-
<ion-item text-wrap *ngIf="!leftDuringTimed">
91-
<!-- User hasn't left during the session, show a start button. -->
92-
<a ion-button block *ngIf="!canManage" icon-end (click)="start(false)">
93-
{{ 'core.start' | translate }}
94-
<ion-icon name="arrow-forward" md="ios-arrow-forward"></ion-icon>
95-
</a>
96-
<a ion-button block *ngIf="canManage" icon-end (click)="start(false)">
97-
{{ 'addon.mod_lesson.preview' | translate }}
98-
<ion-icon name="search"></ion-icon>
99-
</a>
100-
</ion-item>
92+
<ion-item text-wrap *ngIf="!leftDuringTimed && !finishedOffline">
93+
<!-- User hasn't left during the session, show a start button. -->
94+
<a ion-button block *ngIf="!canManage" icon-end (click)="start(false)">
95+
{{ 'core.start' | translate }}
96+
<ion-icon name="arrow-forward" md="ios-arrow-forward"></ion-icon>
97+
</a>
98+
<a ion-button block *ngIf="canManage" icon-end (click)="start(false)">
99+
{{ 'addon.mod_lesson.preview' | translate }}
100+
<ion-icon name="search"></ion-icon>
101+
</a>
102+
</ion-item>
103+
104+
<ion-item text-wrap *ngIf="finishedOffline">
105+
<!-- There's an attempt finished in offline. Let the user continue, showing the end of lesson. -->
106+
<a ion-button block icon-end (click)="start(true)">
107+
{{ 'addon.mod_lesson.continue' | translate }}
108+
<ion-icon name="arrow-forward" md="ios-arrow-forward"></ion-icon>
109+
</a>
110+
</ion-item>
111+
</ng-container>
101112
</ion-list>
102113
</core-loading>
103114
</ng-template>

src/addon/mod/lesson/components/index/index.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,7 @@ export class AddonModLessonIndexComponent extends CoreCourseModuleMainActivityCo
5656
reportLoaded: boolean; // Whether the report data has been loaded.
5757
selectedGroupName: string; // The name of the selected group.
5858
overview: any; // Reports overview data.
59+
finishedOffline: boolean; // Whether a retake was finished in offline.
5960

6061
protected syncEventName = AddonModLessonSyncProvider.AUTO_SYNCED;
6162
protected accessInfo: any; // Lesson access info.
@@ -159,6 +160,11 @@ export class AddonModLessonIndexComponent extends CoreCourseModuleMainActivityCo
159160
}
160161
}));
161162

163+
// Check if the ser has a finished retake in offline.
164+
promises.push(this.lessonOffline.hasFinishedRetake(this.lesson.id).then((finished) => {
165+
this.finishedOffline = finished;
166+
}));
167+
162168
// Update the list of content pages viewed and question attempts.
163169
promises.push(this.lessonProvider.getContentPagesViewedOnline(this.lesson.id, info.attemptscount));
164170
promises.push(this.lessonProvider.getQuestionsAttemptsOnline(this.lesson.id, info.attemptscount));

src/addon/mod/lesson/pages/player/player.html

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -32,14 +32,14 @@
3232
<!-- Page content. -->
3333
<ion-card *ngIf="!eolData && !processData">
3434
<!-- Content page. -->
35-
<ion-item text-wrap *ngIf="!question">
35+
<ion-item text-wrap *ngIf="!question && pageContent">
3636
<core-format-text [component]="component" [componentId]="lesson.coursemodule" [text]="pageContent"></core-format-text>
3737
</ion-item>
3838

3939
<!-- Question page. -->
4040
<!-- We need to set ngIf loaded to make formGroup directive restart every time a page changes, see MOBILE-2540. -->
4141
<form *ngIf="question && loaded" ion-list [formGroup]="questionForm">
42-
<ion-item-divider text-wrap>
42+
<ion-item-divider text-wrap *ngIf="pageContent">
4343
<core-format-text [component]="component" [componentId]="lesson.coursemodule" [text]="pageContent"></core-format-text>
4444
</ion-item-divider>
4545

src/addon/mod/lesson/providers/helper.ts

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,8 @@ import { AddonModLessonProvider } from './lesson';
2727
export class AddonModLessonHelperProvider {
2828

2929
constructor(private domUtils: CoreDomUtilsProvider, private fb: FormBuilder, private translate: TranslateService,
30-
private textUtils: CoreTextUtilsProvider, private timeUtils: CoreTimeUtilsProvider) { }
30+
private textUtils: CoreTextUtilsProvider, private timeUtils: CoreTimeUtilsProvider,
31+
private lessonProvider: AddonModLessonProvider) { }
3132

3233
/**
3334
* Given the HTML of next activity link, format it to extract the href and the text.
@@ -149,8 +150,15 @@ export class AddonModLessonHelperProvider {
149150
return contents.innerHTML.trim();
150151
}
151152

152-
// Cannot find contents element, return the page.contents (some elements like videos might not work).
153-
return data.page.contents;
153+
// Cannot find contents element.
154+
if (this.lessonProvider.isQuestionPage(data.page.type) ||
155+
data.page.qtype == AddonModLessonProvider.LESSON_PAGE_BRANCHTABLE) {
156+
// Return page.contents to prevent having duplicated elements (some elements like videos might not work).
157+
return data.page.contents;
158+
} else {
159+
// It's an end of cluster, end of branch, etc. Return the whole pagecontent to match what's displayed in web.
160+
return data.pagecontent;
161+
}
154162
}
155163

156164
/**

src/addon/mod/workshop/components/index/index.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ import { AddonModWorkshopOfflineProvider } from '../../providers/offline';
3232
export class AddonModWorkshopIndexComponent extends CoreCourseModuleMainActivityComponent {
3333
@Input() group = 0;
3434

35+
component = AddonModWorkshopProvider.COMPONENT;
3536
moduleName = 'workshop';
3637
workshop: any;
3738
page = 0;
@@ -64,6 +65,7 @@ export class AddonModWorkshopIndexComponent extends CoreCourseModuleMainActivity
6465
protected obsAssessmentSaved: any;
6566
protected appResumeSubscription: any;
6667
protected syncObserver: any;
68+
protected syncEventName = AddonModWorkshopSyncProvider.AUTO_SYNCED;
6769

6870
constructor(injector: Injector, private workshopProvider: AddonModWorkshopProvider, @Optional() content: Content,
6971
private workshopOffline: AddonModWorkshopOfflineProvider, private groupsProvider: CoreGroupsProvider,

src/assets/lang/en.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1608,6 +1608,7 @@
16081608
"core.remove": "Remove",
16091609
"core.required": "Required",
16101610
"core.requireduserdatamissing": "This user lacks some required profile data. Please enter the data in your site and try again.<br>{{$a}}",
1611+
"core.resourcedisplayopen": "Open",
16111612
"core.resources": "Resources",
16121613
"core.restore": "Restore",
16131614
"core.retry": "Retry",

src/classes/site.ts

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -605,7 +605,7 @@ export class CoreSite {
605605

606606
// Session expired, trigger event.
607607
this.eventsProvider.trigger(CoreEventsProvider.SESSION_EXPIRED, {}, this.id);
608-
// Change error message. We'll try to get data from cache.
608+
// Change error message. Try to get data from cache, the event will handle the error.
609609
error.message = this.translate.instant('core.lostconnection');
610610
} else if (error.errorcode === 'userdeleted') {
611611
// User deleted, trigger event.
@@ -614,17 +614,15 @@ export class CoreSite {
614614

615615
return Promise.reject(error);
616616
} else if (error.errorcode === 'forcepasswordchangenotice') {
617-
// Password Change Forced, trigger event.
617+
// Password Change Forced, trigger event. Try to get data from cache, the event will handle the error.
618618
this.eventsProvider.trigger(CoreEventsProvider.PASSWORD_CHANGE_FORCED, {}, this.id);
619619
error.message = this.translate.instant('core.forcepasswordchangenotice');
620620

621-
return Promise.reject(error);
622621
} else if (error.errorcode === 'usernotfullysetup') {
623-
// User not fully setup, trigger event.
622+
// User not fully setup, trigger event. Try to get data from cache, the event will handle the error.
624623
this.eventsProvider.trigger(CoreEventsProvider.USER_NOT_FULLY_SETUP, {}, this.id);
625624
error.message = this.translate.instant('core.usernotfullysetup');
626625

627-
return Promise.reject(error);
628626
} else if (error.errorcode === 'sitepolicynotagreed') {
629627
// Site policy not agreed, trigger event.
630628
this.eventsProvider.trigger(CoreEventsProvider.SITE_POLICY_NOT_AGREED, {}, this.id);

0 commit comments

Comments
 (0)