From 4aa5d4a6a1c5825b2f57cba0e271c4de459df3dd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pau=20Ferrer=20Oca=C3=B1a?= Date: Tue, 22 Jan 2019 11:52:07 +0100 Subject: [PATCH 1/3] MOBILE-2843 course: Improve show prefetch group of courses --- src/components/empty-box/empty-box.scss | 1 + src/core/course/providers/helper.ts | 5 +++-- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/src/components/empty-box/empty-box.scss b/src/components/empty-box/empty-box.scss index 4eb024d88..5d265575c 100644 --- a/src/components/empty-box/empty-box.scss +++ b/src/components/empty-box/empty-box.scss @@ -29,6 +29,7 @@ ion-app.app-root core-empty-box { .icon { font-size: 120px; + width: auto; } img { height: 125px; diff --git a/src/core/course/providers/helper.ts b/src/core/course/providers/helper.ts index 3c1dcdb48..27a3dcfef 100644 --- a/src/core/course/providers/helper.ts +++ b/src/core/course/providers/helper.ts @@ -758,10 +758,11 @@ export class CoreCourseHelperProvider { * * @param {any[]} courses Courses array to get info from. * @param {any} prefetch Prefetch information. + * @param {number} [minCourses=2] Min course to show icon. * @return {Promise} Resolved with the prefetch information updated when done. */ - initPrefetchCoursesIcons(courses: any[], prefetch: any): Promise { - if (!courses || courses.length < 2) { + initPrefetchCoursesIcons(courses: any[], prefetch: any, minCourses: number = 2): Promise { + if (!courses || courses.length < minCourses) { // Not enough courses. prefetch.icon = ''; From 58746a9e449b17122be1741cb65ca2c27bc83b80 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pau=20Ferrer=20Oca=C3=B1a?= Date: Thu, 24 Jan 2019 09:27:05 +0100 Subject: [PATCH 2/3] MOBILE-2843 ux: Remove border of the refresher --- src/app/app.scss | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/app/app.scss b/src/app/app.scss index 508268db3..17b534f24 100644 --- a/src/app/app.scss +++ b/src/app/app.scss @@ -73,6 +73,10 @@ ion-app.app-root { } } + .has-refresher > .scroll-content { + border-top: 0 !important; + } + // Define an alternative way to set a heading in an item without using a heading tag. // This is done for accessibility reasons when a heading is semantically incorrect. .item .item-heading { From 67680550ce16e1a8e78359e605bda630cfacd535 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pau=20Ferrer=20Oca=C3=B1a?= Date: Wed, 23 Jan 2019 16:37:06 +0100 Subject: [PATCH 3/3] MOBILE-2843 notes: Move add note to the notes page --- .../components/list/addon-notes-list.html | 14 ++++- src/addon/notes/components/list/list.ts | 55 ++++++++++++++++--- src/addon/notes/notes.module.ts | 3 +- src/addon/notes/pages/add/add.html | 12 ++-- src/addon/notes/pages/add/add.ts | 12 ++-- src/addon/notes/pages/list/list.html | 7 +++ src/addon/notes/pages/list/list.module.ts | 33 +++++++++++ src/addon/notes/pages/list/list.ts | 34 ++++++++++++ .../notes/providers/course-option-handler.ts | 2 +- src/addon/notes/providers/notes-offline.ts | 18 ++++++ src/addon/notes/providers/notes-sync.ts | 4 +- src/addon/notes/providers/notes.ts | 45 +++++++++++---- src/addon/notes/providers/user-handler.ts | 36 ++++++------ 13 files changed, 219 insertions(+), 56 deletions(-) create mode 100644 src/addon/notes/pages/list/list.html create mode 100644 src/addon/notes/pages/list/list.module.ts create mode 100644 src/addon/notes/pages/list/list.ts diff --git a/src/addon/notes/components/list/addon-notes-list.html b/src/addon/notes/components/list/addon-notes-list.html index 0285ddd90..2c069ca78 100644 --- a/src/addon/notes/components/list/addon-notes-list.html +++ b/src/addon/notes/components/list/addon-notes-list.html @@ -10,6 +10,10 @@ + + +

{{user.fullname}}

+
@@ -29,8 +33,8 @@ - -

{{note.userfullname}}

+ +

{{note.userfullname}}

{{note.lastmodified | coreDateDayOrTime}}

{{ 'core.notsent' | translate }}

@@ -39,5 +43,11 @@
+ + + + diff --git a/src/addon/notes/components/list/list.ts b/src/addon/notes/components/list/list.ts index b51247b3d..0150edbfd 100644 --- a/src/addon/notes/components/list/list.ts +++ b/src/addon/notes/components/list/list.ts @@ -13,11 +13,12 @@ // limitations under the License. import { Component, Input, OnDestroy, OnInit, ViewChild } from '@angular/core'; -import { Content } from 'ionic-angular'; +import { Content, ModalController } from 'ionic-angular'; import { CoreDomUtilsProvider } from '@providers/utils/dom'; import { CoreEventsProvider } from '@providers/events'; import { CoreSitesProvider } from '@providers/sites'; import { CoreTextUtilsProvider } from '@providers/utils/text'; +import { CoreUserProvider } from '@core/user/providers/user'; import { AddonNotesProvider } from '../../providers/notes'; import { AddonNotesSyncProvider } from '../../providers/notes-sync'; @@ -30,6 +31,7 @@ import { AddonNotesSyncProvider } from '../../providers/notes-sync'; }) export class AddonNotesListComponent implements OnInit, OnDestroy { @Input() courseId: number; + @Input() userId?: number; @ViewChild(Content) content: Content; @@ -41,10 +43,12 @@ export class AddonNotesListComponent implements OnInit, OnDestroy { notes: any[]; hasOffline = false; notesLoaded = false; + user: any; constructor(private domUtils: CoreDomUtilsProvider, private textUtils: CoreTextUtilsProvider, - sitesProvider: CoreSitesProvider, eventsProvider: CoreEventsProvider, - private notesProvider: AddonNotesProvider, private notesSync: AddonNotesSyncProvider) { + sitesProvider: CoreSitesProvider, eventsProvider: CoreEventsProvider, private modalCtrl: ModalController, + private notesProvider: AddonNotesProvider, private notesSync: AddonNotesSyncProvider, + private userProvider: CoreUserProvider) { // Refresh data if notes are synchronized automatically. this.syncObserver = eventsProvider.on(AddonNotesSyncProvider.AUTO_SYNCED, (data) => { if (data.courseId == this.courseId) { @@ -67,7 +71,7 @@ export class AddonNotesListComponent implements OnInit, OnDestroy { */ ngOnInit(): void { this.fetchNotes(true).then(() => { - this.notesProvider.logView(this.courseId).catch(() => { + this.notesProvider.logView(this.courseId, this.userId).catch(() => { // Ignore errors. }); }); @@ -86,14 +90,23 @@ export class AddonNotesListComponent implements OnInit, OnDestroy { return promise.catch(() => { // Ignore errors. }).then(() => { - return this.notesProvider.getNotes(this.courseId).then((notes) => { + return this.notesProvider.getNotes(this.courseId, this.userId).then((notes) => { notes = notes[this.type + 'notes'] || []; this.hasOffline = notes.some((note) => note.offline); - return this.notesProvider.getNotesUserData(notes, this.courseId).then((notes) => { + if (this.userId) { this.notes = notes; - }); + + // Get the user profile to retrieve the user image. + return this.userProvider.getProfile(this.userId, this.courseId, true).then((user) => { + this.user = user; + }); + } else { + return this.notesProvider.getNotesUserData(notes, this.courseId).then((notes) => { + this.notes = notes; + }); + } }); }).catch((message) => { this.domUtils.showErrorModal(message); @@ -113,7 +126,7 @@ export class AddonNotesListComponent implements OnInit, OnDestroy { refreshNotes(showErrors: boolean, refresher?: any): void { this.refreshIcon = 'spinner'; this.syncIcon = 'spinner'; - this.notesProvider.invalidateNotes(this.courseId).finally(() => { + this.notesProvider.invalidateNotes(this.courseId, this.userId).finally(() => { this.fetchNotes(true, showErrors).finally(() => { if (refresher) { refresher.complete(); @@ -130,12 +143,36 @@ export class AddonNotesListComponent implements OnInit, OnDestroy { this.refreshIcon = 'spinner'; this.syncIcon = 'spinner'; this.fetchNotes(true).then(() => { - this.notesProvider.logView(this.courseId).catch(() => { + this.notesProvider.logView(this.courseId, this.userId).catch(() => { // Ignore errors. }); }); } + /** + * Add a new Note to user and course. + * @param {Event} e Event. + */ + addNote(e: Event): void { + e.preventDefault(); + e.stopPropagation(); + const modal = this.modalCtrl.create('AddonNotesAddPage', { userId: this.userId, courseId: this.courseId, type: this.type }); + modal.onDidDismiss((data) => { + if (data && data.sent && data.type) { + if (data.type != this.type) { + this.type = data.type; + this.notesLoaded = false; + } + + this.refreshNotes(true); + } else if (data && data.type && data.type != this.type) { + this.type = data.type; + this.typeChanged(); + } + }); + modal.present(); + } + /** * Tries to synchronize course notes. * diff --git a/src/addon/notes/notes.module.ts b/src/addon/notes/notes.module.ts index 425766440..002f60177 100644 --- a/src/addon/notes/notes.module.ts +++ b/src/addon/notes/notes.module.ts @@ -44,8 +44,7 @@ export const ADDON_NOTES_PROVIDERS: any[] = [ AddonNotesSyncProvider, AddonNotesCourseOptionHandler, AddonNotesSyncCronHandler, - AddonNotesUserHandler - ] + AddonNotesUserHandler ] }) export class AddonNotesModule { constructor(courseOptionsDelegate: CoreCourseOptionsDelegate, courseOptionHandler: AddonNotesCourseOptionHandler, diff --git a/src/addon/notes/pages/add/add.html b/src/addon/notes/pages/add/add.html index aaf3bfab8..b6df1d660 100644 --- a/src/addon/notes/pages/add/add.html +++ b/src/addon/notes/pages/add/add.html @@ -8,11 +8,11 @@ - +
{{ 'addon.notes.publishstate' | translate }} - + {{ 'addon.notes.personalnotes' | translate }} {{ 'addon.notes.coursenotes' | translate }} {{ 'addon.notes.sitenotes' | translate }} @@ -21,8 +21,10 @@ - +
+ +
diff --git a/src/addon/notes/pages/add/add.ts b/src/addon/notes/pages/add/add.ts index 92cc7e219..98c770c8f 100644 --- a/src/addon/notes/pages/add/add.ts +++ b/src/addon/notes/pages/add/add.ts @@ -29,7 +29,7 @@ import { AddonNotesProvider } from '../../providers/notes'; export class AddonNotesAddPage { userId: number; courseId: number; - publishState = 'personal'; + type = 'personal'; text = ''; processing = false; @@ -37,6 +37,7 @@ export class AddonNotesAddPage { private domUtils: CoreDomUtilsProvider, private notesProvider: AddonNotesProvider) { this.userId = params.get('userId'); this.courseId = params.get('courseId'); + this.type = params.get('type') || 'personal'; } /** @@ -52,10 +53,9 @@ export class AddonNotesAddPage { const loadingModal = this.domUtils.showModalLoading('core.sending', true); // Freeze the add note button. this.processing = true; - this.notesProvider.addNote(this.userId, this.courseId, this.publishState, this.text).then((sent) => { - this.viewCtrl.dismiss().finally(() => { - const message = sent ? 'addon.notes.eventnotecreated' : 'core.datastoredoffline'; - this.domUtils.showAlertTranslated('core.success', message); + this.notesProvider.addNote(this.userId, this.courseId, this.type, this.text).then((sent) => { + this.viewCtrl.dismiss({type: this.type, sent: true}).finally(() => { + this.domUtils.showToast(sent ? 'addon.notes.eventnotecreated' : 'core.datastoredoffline', true, 3000); }); }).catch((error) => { this.domUtils.showErrorModal(error); @@ -69,6 +69,6 @@ export class AddonNotesAddPage { * Close modal. */ closeModal(): void { - this.viewCtrl.dismiss(); + this.viewCtrl.dismiss({type: this.type}); } } diff --git a/src/addon/notes/pages/list/list.html b/src/addon/notes/pages/list/list.html new file mode 100644 index 000000000..f88fe2201 --- /dev/null +++ b/src/addon/notes/pages/list/list.html @@ -0,0 +1,7 @@ + + + {{ 'addon.notes.notes' | translate }} + + + + diff --git a/src/addon/notes/pages/list/list.module.ts b/src/addon/notes/pages/list/list.module.ts new file mode 100644 index 000000000..c983a9395 --- /dev/null +++ b/src/addon/notes/pages/list/list.module.ts @@ -0,0 +1,33 @@ +// (C) Copyright 2015 Martin Dougiamas +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +import { NgModule } from '@angular/core'; +import { IonicPageModule } from 'ionic-angular'; +import { TranslateModule } from '@ngx-translate/core'; +import { CoreDirectivesModule } from '@directives/directives.module'; +import { AddonNotesListPage } from './list'; +import { AddonNotesComponentsModule } from '../../components/components.module'; + +@NgModule({ + declarations: [ + AddonNotesListPage + ], + imports: [ + CoreDirectivesModule, + AddonNotesComponentsModule, + IonicPageModule.forChild(AddonNotesListPage), + TranslateModule.forChild() + ] +}) +export class AddonNotesListPageModule {} diff --git a/src/addon/notes/pages/list/list.ts b/src/addon/notes/pages/list/list.ts new file mode 100644 index 000000000..499ca2304 --- /dev/null +++ b/src/addon/notes/pages/list/list.ts @@ -0,0 +1,34 @@ +// (C) Copyright 2015 Martin Dougiamas +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +import { Component } from '@angular/core'; +import { IonicPage, NavParams } from 'ionic-angular'; + +/** + * Page that displays a list of notes. + */ +@IonicPage({ segment: 'addon-notes-list-page' }) +@Component({ + selector: 'page-addon-notes-list-page', + templateUrl: 'list.html', +}) +export class AddonNotesListPage { + userId: number; + courseId: number; + + constructor(params: NavParams) { + this.userId = params.get('userId'); + this.courseId = params.get('courseId'); + } +} diff --git a/src/addon/notes/providers/course-option-handler.ts b/src/addon/notes/providers/course-option-handler.ts index a1431a8c3..f00761ae8 100644 --- a/src/addon/notes/providers/course-option-handler.ts +++ b/src/addon/notes/providers/course-option-handler.ts @@ -79,6 +79,6 @@ export class AddonNotesCourseOptionHandler implements CoreCourseOptionsHandler { * @return {Promise} Promise resolved when done. */ prefetch(course: any): Promise { - return this.notesProvider.getNotes(course.id, true); + return this.notesProvider.getNotes(course.id, undefined, true); } } diff --git a/src/addon/notes/providers/notes-offline.ts b/src/addon/notes/providers/notes-offline.ts index b75a69067..dd9fbf50b 100644 --- a/src/addon/notes/providers/notes-offline.ts +++ b/src/addon/notes/providers/notes-offline.ts @@ -118,6 +118,24 @@ export class AddonNotesOfflineProvider { }); } + /** + * Get offline notes for a certain course and user. + * + * @param {number} courseId Course ID. + * @param {number} [userId] User ID. + * @param {string} [siteId] Site ID. If not defined, current site. + * @return {Promise} Promise resolved with notes. + */ + getNotesForCourseAndUser(courseId: number, userId?: number, siteId?: string): Promise { + if (!userId) { + return this.getNotesForCourse(courseId, siteId); + } + + return this.sitesProvider.getSite(siteId).then((site) => { + return site.getDb().getRecords(AddonNotesOfflineProvider.NOTES_TABLE, {userid: userId, courseid: courseId}); + }); + } + /** * Get offline notes for a certain course. * diff --git a/src/addon/notes/providers/notes-sync.ts b/src/addon/notes/providers/notes-sync.ts index e02baf438..376e5b673 100644 --- a/src/addon/notes/providers/notes-sync.ts +++ b/src/addon/notes/providers/notes-sync.ts @@ -154,8 +154,8 @@ export class AddonNotesSyncProvider extends CoreSyncBaseProvider { }); // Fetch the notes from server to be sure they're up to date. - return this.notesProvider.invalidateNotes(courseId, siteId).then(() => { - return this.notesProvider.getNotes(courseId, false, true, siteId); + return this.notesProvider.invalidateNotes(courseId, undefined, siteId).then(() => { + return this.notesProvider.getNotes(courseId, undefined, false, true, siteId); }).catch(() => { // Ignore errors. }); diff --git a/src/addon/notes/providers/notes.ts b/src/addon/notes/providers/notes.ts index 9e065ca01..8226e0139 100644 --- a/src/addon/notes/providers/notes.ts +++ b/src/addon/notes/providers/notes.ts @@ -104,7 +104,7 @@ export class AddonNotesProvider { } // A note was added, invalidate the course notes. - return this.invalidateNotes(courseId, siteId).catch(() => { + return this.invalidateNotes(courseId, undefined, siteId).catch(() => { // Ignore errors. }); }); @@ -184,37 +184,54 @@ export class AddonNotesProvider { * @return {Promise} Promise resolved with true if enabled, resolved with false or rejected otherwise. */ isPluginViewNotesEnabledForCourse(courseId: number, siteId?: string): Promise { - return this.utils.promiseWorks(this.getNotes(courseId, false, true, siteId)); + return this.utils.promiseWorks(this.getNotes(courseId, undefined, false, true, siteId)); + } + + /** + * Get prefix cache key for course notes. + * + * @param {number} courseId ID of the course to get the notes from. + * @return {string} Cache key. + */ + getNotesPrefixCacheKey(courseId: number): string { + return this.ROOT_CACHE_KEY + 'notes:' + courseId + ':'; } /** * Get the cache key for the get notes call. * * @param {number} courseId ID of the course to get the notes from. + * @param {number} [userId] ID of the user to get the notes from if requested. * @return {string} Cache key. */ - getNotesCacheKey(courseId: number): string { - return this.ROOT_CACHE_KEY + 'notes:' + courseId; + getNotesCacheKey(courseId: number, userId?: number): string { + return this.getNotesPrefixCacheKey(courseId) + (userId ? userId : ''); } /** * Get users notes for a certain site, course and personal notes. * * @param {number} courseId ID of the course to get the notes from. + * @param {number} [userId] ID of the user to get the notes from if requested. * @param {boolean} [ignoreCache] True when we should not get the value from the cache. * @param {boolean} [onlyOnline] True to return only online notes, false to return both online and offline. * @param {string} [siteId] Site ID. If not defined, current site. * @return {Promise} Promise to be resolved when the notes are retrieved. */ - getNotes(courseId: number, ignoreCache?: boolean, onlyOnline?: boolean, siteId?: string): Promise { + getNotes(courseId: number, userId?: number, ignoreCache?: boolean, onlyOnline?: boolean, siteId?: string): Promise { this.logger.debug('Get notes for course ' + courseId); return this.sitesProvider.getSite(siteId).then((site) => { const data = { courseid: courseId }; + + if (userId) { + data['userid'] = userId; + } + const preSets: CoreSiteWSPreSets = { - cacheKey: this.getNotesCacheKey(courseId) + cacheKey: this.getNotesCacheKey(courseId, userId) }; if (ignoreCache) { @@ -228,7 +245,7 @@ export class AddonNotesProvider { } // Get offline notes and add them to the list. - return this.notesOffline.getNotesForCourse(courseId, siteId).then((offlineNotes) => { + return this.notesOffline.getNotesForCourseAndUser(courseId, userId, siteId).then((offlineNotes) => { offlineNotes.forEach((note) => { const fieldName = note.publishstate + 'notes'; if (!notes[fieldName]) { @@ -272,12 +289,17 @@ export class AddonNotesProvider { * Invalidate get notes WS call. * * @param {number} courseId Course ID. + * @param {number} [userId] User ID if needed. * @param {string} [siteId] Site ID. If not defined, current site. * @return {Promise} Promise resolved when data is invalidated. */ - invalidateNotes(courseId: number, siteId?: string): Promise { + invalidateNotes(courseId: number, userId?: number, siteId?: string): Promise { return this.sitesProvider.getSite(siteId).then((site) => { - return site.invalidateWsCacheForKey(this.getNotesCacheKey(courseId)); + if (userId) { + return site.invalidateWsCacheForKey(this.getNotesCacheKey(courseId, userId)); + } + + return site.invalidateWsCacheForKeyStartingWith(this.getNotesPrefixCacheKey(courseId)); }); } @@ -285,14 +307,15 @@ export class AddonNotesProvider { * Report notes as being viewed. * * @param {number} courseId ID of the course. + * @param {number} [userId] User ID if needed. * @param {string} [siteId] Site ID. If not defined, current site. * @return {Promise} Promise resolved when the WS call is successful. */ - logView(courseId: number, siteId?: string): Promise { + logView(courseId: number, userId?: number, siteId?: string): Promise { return this.sitesProvider.getSite(siteId).then((site) => { const params = { courseid: courseId, - userid: 0 + userid: userId || 0 }; return site.write('core_notes_view_notes', params); diff --git a/src/addon/notes/providers/user-handler.ts b/src/addon/notes/providers/user-handler.ts index ffa1c367c..a5a409ded 100644 --- a/src/addon/notes/providers/user-handler.ts +++ b/src/addon/notes/providers/user-handler.ts @@ -13,10 +13,10 @@ // limitations under the License. import { Injectable } from '@angular/core'; -import { ModalController } from 'ionic-angular'; import { CoreEventsProvider } from '@providers/events'; import { CoreUserProvider } from '@core/user/providers/user'; import { CoreUserDelegate, CoreUserProfileHandler, CoreUserProfileHandlerData } from '@core/user/providers/user-delegate'; +import { CoreContentLinksHelperProvider } from '@core/contentlinks/providers/helper'; import { CoreSitesProvider } from '@providers/sites'; import { AddonNotesProvider } from './notes'; @@ -25,30 +25,30 @@ import { AddonNotesProvider } from './notes'; */ @Injectable() export class AddonNotesUserHandler implements CoreUserProfileHandler { - name = 'AddonNotes:addNote'; - priority = 200; - type = CoreUserDelegate.TYPE_COMMUNICATION; - addNoteEnabledCache = {}; + name = 'AddonNotes:notes'; + priority = 100; + type = CoreUserDelegate.TYPE_NEW_PAGE; + noteEnabledCache = {}; - constructor(private modalCtrl: ModalController, private sitesProvider: CoreSitesProvider, + constructor(private linkHelper: CoreContentLinksHelperProvider, private sitesProvider: CoreSitesProvider, private notesProvider: AddonNotesProvider, eventsProvider: CoreEventsProvider) { - eventsProvider.on(CoreEventsProvider.LOGOUT, this.clearAddNoteCache.bind(this)); + eventsProvider.on(CoreEventsProvider.LOGOUT, this.clearNoteCache.bind(this)); eventsProvider.on(CoreUserProvider.PROFILE_REFRESHED, (data) => { - this.clearAddNoteCache(data.courseId); + this.clearNoteCache(data.courseId); }); } /** - * Clear add note cache. + * Clear note cache. * If a courseId is specified, it will only delete the entry for that course. * * @param {number} [courseId] Course ID. */ - private clearAddNoteCache(courseId?: number): void { + private clearNoteCache(courseId?: number): void { if (courseId) { - delete this.addNoteEnabledCache[courseId]; + delete this.noteEnabledCache[courseId]; } else { - this.addNoteEnabledCache = {}; + this.noteEnabledCache = {}; } } @@ -75,12 +75,12 @@ export class AddonNotesUserHandler implements CoreUserProfileHandler { return Promise.resolve(false); } - if (typeof this.addNoteEnabledCache[courseId] != 'undefined') { - return this.addNoteEnabledCache[courseId]; + if (typeof this.noteEnabledCache[courseId] != 'undefined') { + return this.noteEnabledCache[courseId]; } return this.notesProvider.isPluginAddNoteEnabledForCourse(courseId).then((enabled) => { - this.addNoteEnabledCache[courseId] = enabled; + this.noteEnabledCache[courseId] = enabled; return enabled; }); @@ -94,13 +94,13 @@ export class AddonNotesUserHandler implements CoreUserProfileHandler { getDisplayData(user: any, courseId: number): CoreUserProfileHandlerData { return { icon: 'list', - title: 'addon.notes.addnewnote', + title: 'addon.notes.notes', class: 'addon-notes-handler', action: (event, navCtrl, user, courseId): void => { event.preventDefault(); event.stopPropagation(); - const modal = this.modalCtrl.create('AddonNotesAddPage', { userId: user.id, courseId }); - modal.present(); + // Always use redirect to make it the new history root (to avoid "loops" in history). + this.linkHelper.goInSite(navCtrl, 'AddonNotesListPage', { userId: user.id, courseId: courseId }); } }; }