Skip to content

Commit f284ab7

Browse files
committed
MOBILE-3401 courses: Refresh only right data on MY_COURSES_UPDATED
1 parent 536589c commit f284ab7

File tree

8 files changed

+190
-25
lines changed

8 files changed

+190
-25
lines changed

src/addon/block/myoverview/components/myoverview/myoverview.ts

Lines changed: 27 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ import { Searchbar } from 'ionic-angular';
1717
import { CoreEventsProvider } from '@providers/events';
1818
import { CoreTimeUtilsProvider } from '@providers/utils/time';
1919
import { CoreSitesProvider } from '@providers/sites';
20-
import { CoreCoursesProvider } from '@core/courses/providers/courses';
20+
import { CoreCoursesProvider, CoreCoursesMyCoursesUpdatedEventData } from '@core/courses/providers/courses';
2121
import { CoreCoursesHelperProvider } from '@core/courses/providers/helper';
2222
import { CoreCourseHelperProvider } from '@core/course/providers/helper';
2323
import { CoreCourseOptionsDelegate } from '@core/course/providers/options-delegate';
@@ -112,8 +112,12 @@ export class AddonBlockMyOverviewComponent extends CoreBlockBaseComponent implem
112112

113113
}, this.sitesProvider.getCurrentSiteId());
114114

115-
this.coursesObserver = this.eventsProvider.on(CoreCoursesProvider.EVENT_MY_COURSES_UPDATED, () => {
116-
this.refreshContent();
115+
this.coursesObserver = this.eventsProvider.on(CoreCoursesProvider.EVENT_MY_COURSES_UPDATED,
116+
(data: CoreCoursesMyCoursesUpdatedEventData) => {
117+
118+
if (data.action == CoreCoursesProvider.ACTION_ENROL || data.action == CoreCoursesProvider.ACTION_STATE_CHANGED) {
119+
this.refreshCourseList();
120+
}
117121
}, this.sitesProvider.getCurrentSiteId());
118122

119123
this.currentSite = this.sitesProvider.getCurrentSite();
@@ -151,12 +155,9 @@ export class AddonBlockMyOverviewComponent extends CoreBlockBaseComponent implem
151155

152156
promises.push(this.coursesProvider.invalidateUserCourses().finally(() => {
153157
// Invalidate course completion data.
154-
promises.push(this.coursesProvider.invalidateUserCourses().finally(() => {
155-
// Invalidate course completion data.
156-
return this.utils.allPromises(this.courseIds.map((courseId) => {
157-
return this.courseCompletionProvider.invalidateCourseCompletion(courseId);
158-
}));
159-
}));
158+
return this.utils.allPromises(this.courseIds.map((courseId) => {
159+
return this.courseCompletionProvider.invalidateCourseCompletion(courseId);
160+
}));
160161
}));
161162

162163
promises.push(this.courseOptionsDelegate.clearAndInvalidateCoursesOptions());
@@ -318,6 +319,23 @@ export class AddonBlockMyOverviewComponent extends CoreBlockBaseComponent implem
318319
});
319320
}
320321

322+
/**
323+
* Refresh the list of courses.
324+
*
325+
* @return Promise resolved when done.
326+
*/
327+
protected async refreshCourseList(): Promise<void> {
328+
this.eventsProvider.trigger(CoreCoursesProvider.EVENT_MY_COURSES_REFRESHED);
329+
330+
try {
331+
await this.coursesProvider.invalidateUserCourses();
332+
} catch (error) {
333+
// Ignore errors.
334+
}
335+
336+
await this.loadContent(true);
337+
}
338+
321339
/**
322340
* The selected courses filter have changed.
323341
*/

src/addon/block/recentlyaccessedcourses/components/recentlyaccessedcourses/recentlyaccessedcourses.ts

Lines changed: 67 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
import { Component, OnInit, OnDestroy, Injector, Input, OnChanges, SimpleChange } from '@angular/core';
1616
import { CoreEventsProvider } from '@providers/events';
1717
import { CoreSitesProvider } from '@providers/sites';
18-
import { CoreCoursesProvider } from '@core/courses/providers/courses';
18+
import { CoreCoursesProvider, CoreCoursesMyCoursesUpdatedEventData } from '@core/courses/providers/courses';
1919
import { CoreCoursesHelperProvider } from '@core/courses/providers/helper';
2020
import { CoreCourseHelperProvider } from '@core/course/providers/helper';
2121
import { CoreCourseOptionsDelegate } from '@core/course/providers/options-delegate';
@@ -72,8 +72,12 @@ export class AddonBlockRecentlyAccessedCoursesComponent extends CoreBlockBaseCom
7272

7373
}, this.sitesProvider.getCurrentSiteId());
7474

75-
this.coursesObserver = this.eventsProvider.on(CoreCoursesProvider.EVENT_MY_COURSES_UPDATED, () => {
76-
this.refreshContent();
75+
this.coursesObserver = this.eventsProvider.on(CoreCoursesProvider.EVENT_MY_COURSES_UPDATED,
76+
(data: CoreCoursesMyCoursesUpdatedEventData) => {
77+
78+
if (this.shouldRefreshOnUpdatedEvent(data)) {
79+
this.refreshCourseList();
80+
}
7781
}, this.sitesProvider.getCurrentSiteId());
7882

7983
super.ngOnInit();
@@ -130,6 +134,23 @@ export class AddonBlockRecentlyAccessedCoursesComponent extends CoreBlockBaseCom
130134
});
131135
}
132136

137+
/**
138+
* Refresh the list of courses.
139+
*
140+
* @return Promise resolved when done.
141+
*/
142+
protected async refreshCourseList(): Promise<void> {
143+
this.eventsProvider.trigger(CoreCoursesProvider.EVENT_MY_COURSES_REFRESHED);
144+
145+
try {
146+
await this.coursesProvider.invalidateUserCourses();
147+
} catch (error) {
148+
// Ignore errors.
149+
}
150+
151+
await this.loadContent(true);
152+
}
153+
133154
/**
134155
* Initialize the prefetch icon for selected courses.
135156
*/
@@ -146,6 +167,49 @@ export class AddonBlockRecentlyAccessedCoursesComponent extends CoreBlockBaseCom
146167
});
147168
}
148169

170+
/**
171+
* Whether list should be refreshed based on a EVENT_MY_COURSES_UPDATED event.
172+
*
173+
* @param data Event data.
174+
* @return Whether to refresh.
175+
*/
176+
protected shouldRefreshOnUpdatedEvent(data: CoreCoursesMyCoursesUpdatedEventData): boolean {
177+
if (data.action == CoreCoursesProvider.ACTION_ENROL) {
178+
// Always update if user enrolled in a course.
179+
return true;
180+
}
181+
182+
if (data.action == CoreCoursesProvider.ACTION_VIEW && data.courseId != this.sitesProvider.getCurrentSiteHomeId() &&
183+
this.courses[0] && data.courseId != this.courses[0].id) {
184+
// Update list if user viewed a course that isn't the most recent one and isn't site home.
185+
return true;
186+
}
187+
188+
if (data.action == CoreCoursesProvider.ACTION_STATE_CHANGED && data.state == CoreCoursesProvider.STATE_FAVOURITE &&
189+
this.hasCourse(data.courseId)) {
190+
// Update list if a visible course is now favourite or unfavourite.
191+
return true;
192+
}
193+
194+
return false;
195+
}
196+
197+
/**
198+
* Check if a certain course is in the list of courses.
199+
*
200+
* @param courseId Course ID to search.
201+
* @return Whether it's in the list.
202+
*/
203+
protected hasCourse(courseId: number): boolean {
204+
if (!this.courses) {
205+
return false;
206+
}
207+
208+
return !!this.courses.find((course) => {
209+
return course.id == courseId;
210+
});
211+
}
212+
149213
/**
150214
* Prefetch all the shown courses.
151215
*

src/addon/block/starredcourses/components/starredcourses/starredcourses.ts

Lines changed: 45 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
import { Component, OnInit, OnDestroy, Injector, Input, OnChanges, SimpleChange } from '@angular/core';
1616
import { CoreEventsProvider } from '@providers/events';
1717
import { CoreSitesProvider } from '@providers/sites';
18-
import { CoreCoursesProvider } from '@core/courses/providers/courses';
18+
import { CoreCoursesProvider, CoreCoursesMyCoursesUpdatedEventData } from '@core/courses/providers/courses';
1919
import { CoreCoursesHelperProvider } from '@core/courses/providers/helper';
2020
import { CoreCourseHelperProvider } from '@core/course/providers/helper';
2121
import { CoreCourseOptionsDelegate } from '@core/course/providers/options-delegate';
@@ -72,7 +72,12 @@ export class AddonBlockStarredCoursesComponent extends CoreBlockBaseComponent im
7272

7373
}, this.sitesProvider.getCurrentSiteId());
7474

75-
this.coursesObserver = this.eventsProvider.on(CoreCoursesProvider.EVENT_MY_COURSES_UPDATED, () => {
75+
this.coursesObserver = this.eventsProvider.on(CoreCoursesProvider.EVENT_MY_COURSES_UPDATED,
76+
(data: CoreCoursesMyCoursesUpdatedEventData) => {
77+
78+
if (this.shouldRefreshOnUpdatedEvent(data)) {
79+
this.refreshCourseList();
80+
}
7681
this.refreshContent();
7782
}, this.sitesProvider.getCurrentSiteId());
7883

@@ -130,6 +135,44 @@ export class AddonBlockStarredCoursesComponent extends CoreBlockBaseComponent im
130135
});
131136
}
132137

138+
/**
139+
* Refresh the list of courses.
140+
*
141+
* @return Promise resolved when done.
142+
*/
143+
protected async refreshCourseList(): Promise<void> {
144+
this.eventsProvider.trigger(CoreCoursesProvider.EVENT_MY_COURSES_REFRESHED);
145+
146+
try {
147+
await this.coursesProvider.invalidateUserCourses();
148+
} catch (error) {
149+
// Ignore errors.
150+
}
151+
152+
await this.loadContent(true);
153+
}
154+
155+
/**
156+
* Whether list should be refreshed based on a EVENT_MY_COURSES_UPDATED event.
157+
*
158+
* @param data Event data.
159+
* @return Whether to refresh.
160+
*/
161+
protected shouldRefreshOnUpdatedEvent(data: CoreCoursesMyCoursesUpdatedEventData): boolean {
162+
if (data.action == CoreCoursesProvider.ACTION_ENROL) {
163+
// Always update if user enrolled in a course.
164+
// New courses shouldn't be favourite by default, but just in case.
165+
return true;
166+
}
167+
168+
if (data.action == CoreCoursesProvider.ACTION_STATE_CHANGED && data.state == CoreCoursesProvider.STATE_FAVOURITE) {
169+
// Update list when making a course favourite or not.
170+
return true;
171+
}
172+
173+
return false;
174+
}
175+
133176
/**
134177
* Initialize the prefetch icon for selected courses.
135178
*/

src/core/course/providers/course.ts

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -862,8 +862,10 @@ export class CoreCourseProvider {
862862
if (!response.status) {
863863
return Promise.reject(null);
864864
} else {
865-
this.eventsProvider.trigger(
866-
CoreCoursesProvider.EVENT_MY_COURSES_UPDATED, {course: courseId}, site.getId());
865+
this.eventsProvider.trigger(CoreCoursesProvider.EVENT_MY_COURSES_UPDATED, {
866+
courseId: courseId,
867+
action: CoreCoursesProvider.ACTION_VIEW,
868+
}, site.getId());
867869
}
868870
});
869871
});

src/core/courses/components/course-progress/course-progress.ts

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -218,8 +218,13 @@ export class CoreCoursesCourseProgressComponent implements OnInit, OnDestroy {
218218
// We should use null to unset the preference.
219219
this.userProvider.updateUserPreference('block_myoverview_hidden_course_' + this.course.id, hide ? 1 : null).then(() => {
220220
this.course.hidden = hide;
221-
this.eventsProvider.trigger(
222-
CoreCoursesProvider.EVENT_MY_COURSES_UPDATED, {course: this.course}, this.sitesProvider.getCurrentSiteId());
221+
this.eventsProvider.trigger(CoreCoursesProvider.EVENT_MY_COURSES_UPDATED, {
222+
courseId: this.course.id,
223+
course: this.course,
224+
action: CoreCoursesProvider.ACTION_STATE_CHANGED,
225+
state: CoreCoursesProvider.STATE_HIDDEN,
226+
value: hide,
227+
}, this.sitesProvider.getCurrentSiteId());
223228
}).catch((error) => {
224229
if (!this.isDestroyed) {
225230
this.domUtils.showErrorModalDefault(error, 'Error changing course visibility.');
@@ -239,8 +244,13 @@ export class CoreCoursesCourseProgressComponent implements OnInit, OnDestroy {
239244

240245
this.coursesProvider.setFavouriteCourse(this.course.id, favourite).then(() => {
241246
this.course.isfavourite = favourite;
242-
this.eventsProvider.trigger(
243-
CoreCoursesProvider.EVENT_MY_COURSES_UPDATED, {course: this.course}, this.sitesProvider.getCurrentSiteId());
247+
this.eventsProvider.trigger(CoreCoursesProvider.EVENT_MY_COURSES_UPDATED, {
248+
courseId: this.course.id,
249+
course: this.course,
250+
action: CoreCoursesProvider.ACTION_STATE_CHANGED,
251+
state: CoreCoursesProvider.STATE_FAVOURITE,
252+
value: favourite,
253+
}, this.sitesProvider.getCurrentSiteId());
244254
}).catch((error) => {
245255
if (!this.isDestroyed) {
246256
this.domUtils.showErrorModalDefault(error, 'Error changing course favourite attribute.');

src/core/courses/components/my-courses/my-courses.ts

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ import { Searchbar } from 'ionic-angular';
1717
import { CoreEventsProvider } from '@providers/events';
1818
import { CoreSitesProvider } from '@providers/sites';
1919
import { CoreDomUtilsProvider } from '@providers/utils/dom';
20-
import { CoreCoursesProvider } from '../../providers/courses';
20+
import { CoreCoursesProvider, CoreCoursesMyCoursesUpdatedEventData } from '../../providers/courses';
2121
import { CoreCoursesHelperProvider } from '../../providers/helper';
2222
import { CoreCourseHelperProvider } from '@core/course/providers/helper';
2323
import { CoreCourseOptionsDelegate } from '@core/course/providers/options-delegate';
@@ -63,8 +63,13 @@ export class CoreCoursesMyCoursesComponent implements OnInit, OnDestroy {
6363
this.coursesLoaded = true;
6464
});
6565

66-
this.myCoursesObserver = this.eventsProvider.on(CoreCoursesProvider.EVENT_MY_COURSES_UPDATED, () => {
67-
this.fetchCourses();
66+
// Update list if user enrols in a course.
67+
this.myCoursesObserver = this.eventsProvider.on(CoreCoursesProvider.EVENT_MY_COURSES_UPDATED,
68+
(data: CoreCoursesMyCoursesUpdatedEventData) => {
69+
70+
if (data.action == CoreCoursesProvider.ACTION_ENROL) {
71+
this.fetchCourses();
72+
}
6873
}, this.sitesProvider.getCurrentSiteId());
6974

7075
// Refresh the enabled flags if site is updated.

src/core/courses/pages/course-preview/course-preview.ts

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -365,8 +365,11 @@ export class CoreCoursesCoursePreviewPage implements OnDestroy {
365365
this.waitForEnrolled(true).then(() => {
366366
this.refreshData().finally(() => {
367367
// My courses have been updated, trigger event.
368-
this.eventsProvider.trigger(
369-
CoreCoursesProvider.EVENT_MY_COURSES_UPDATED, {course: this.course}, this.sitesProvider.getCurrentSiteId());
368+
this.eventsProvider.trigger(CoreCoursesProvider.EVENT_MY_COURSES_UPDATED, {
369+
courseId: this.course.id,
370+
course: this.course,
371+
action: CoreCoursesProvider.ACTION_ENROL,
372+
}, this.sitesProvider.getCurrentSiteId());
370373
});
371374
});
372375
}).catch((error) => {

src/core/courses/providers/courses.ts

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,17 @@ import { CoreLoggerProvider } from '@providers/logger';
1818
import { CoreSitesProvider, CoreSitesReadingStrategy } from '@providers/sites';
1919
import { CoreSite } from '@classes/site';
2020

21+
/**
22+
* Data sent to the EVENT_MY_COURSES_UPDATED.
23+
*/
24+
export type CoreCoursesMyCoursesUpdatedEventData = {
25+
action: string; // Action performed.
26+
courseId?: number; // Course ID affected (if any).
27+
course?: any; // Course affected (if any).
28+
state?: string; // Only for ACTION_STATE_CHANGED. The state that changed (hidden, favourite).
29+
value?: boolean; // The new value for the state changed.
30+
};
31+
2132
/**
2233
* Service that provides some features regarding lists of courses and categories.
2334
*/
@@ -30,6 +41,15 @@ export class CoreCoursesProvider {
3041
static EVENT_MY_COURSES_REFRESHED = 'courses_my_courses_refreshed';
3142
static EVENT_DASHBOARD_DOWNLOAD_ENABLED_CHANGED = 'dashboard_download_enabled_changed';
3243

44+
// Actions for event EVENT_MY_COURSES_UPDATED.
45+
static ACTION_ENROL = 'enrol'; // User enrolled in a course.
46+
static ACTION_STATE_CHANGED = 'state_changed'; // Course state changed (hidden, favourite).
47+
static ACTION_VIEW = 'view'; // Course viewed.
48+
49+
// Possible states changed.
50+
static STATE_HIDDEN = 'hidden';
51+
static STATE_FAVOURITE = 'favourite';
52+
3353
protected ROOT_CACHE_KEY = 'mmCourses:';
3454
protected logger;
3555
protected userCoursesIds: {[id: number]: boolean}; // Use an object to make it faster to search.

0 commit comments

Comments
 (0)