MOBILE-3633 notifications: Implement modules and main menu handler

main
Dani Palou 2020-12-18 15:43:52 +01:00
parent b2ad224950
commit 0d31e76daa
5 changed files with 285 additions and 44 deletions

View File

@ -14,63 +14,23 @@
import { NgModule } from '@angular/core';
import { AddonBlockActivityResultsModule } from './block/activityresults/activityresults.module';
import { AddonBlockBadgesModule } from './block/badges/badges.module';
import { AddonBlockBlogMenuModule } from './block/blogmenu/blogmenu.module';
import { AddonBlockBlogRecentModule } from './block/blogrecent/blogrecent.module';
import { AddonBlockBlogTagsModule } from './block/blogtags/blogtags.module';
import { AddonBlockCalendarMonthModule } from './block/calendarmonth/calendarmonth.module';
import { AddonBlockCalendarUpcomingModule } from './block/calendarupcoming/calendarupcoming.module';
import { AddonBlockCommentsModule } from './block/comments/comments.module';
import { AddonBlockCompletionStatusModule } from './block/completionstatus/completionstatus.module';
import { AddonBlockGlossaryRandomModule } from './block/glossaryrandom/glossaryrandom.module';
import { AddonBlockHtmlModule } from './block/html/html.module';
import { AddonBlockLearningPlansModule } from './block/learningplans/learningplans.module';
import { AddonBlockMyOverviewModule } from './block/myoverview/myoverview.module';
import { AddonBlockNewsItemsModule } from './block/newsitems/newsitems.module';
import { AddonBlockOnlineUsersModule } from './block/onlineusers/onlineusers.module';
import { AddonBlockPrivateFilesModule } from './block/privatefiles/privatefiles.module';
import { AddonBlockRecentlyAccessedCoursesModule } from './block/recentlyaccessedcourses/recentlyaccessedcourses.module';
import { AddonBlockRssClientModule } from './block/rssclient/rssclient.module';
import { AddonBlockSelfCompletionModule } from './block/selfcompletion/selfcompletion.module';
import { AddonBlockSiteMainMenuModule } from './block/sitemainmenu/sitemainmenu.module';
import { AddonBlockStarredCoursesModule } from './block/starredcourses/starredcourses.module';
import { AddonBlockTagsModule } from './block/tags/tags.module';
import { AddonBlockModule } from './block/block.module';
import { AddonPrivateFilesModule } from './privatefiles/privatefiles.module';
import { AddonFilterModule } from './filter/filter.module';
import { AddonUserProfileFieldModule } from './userprofilefield/userprofilefield.module';
import { AddonBadgesModule } from './badges/badges.module';
import { AddonCalendarModule } from './calendar/calendar.module';
import { AddonNotificationsModule } from './notifications/notifications.module';
@NgModule({
imports: [
AddonBlockModule,
AddonBadgesModule,
AddonCalendarModule,
AddonPrivateFilesModule,
AddonFilterModule,
AddonBlockActivityResultsModule,
AddonBlockBadgesModule,
AddonBlockBlogMenuModule,
AddonBlockBlogRecentModule,
AddonBlockBlogTagsModule,
AddonBlockCalendarMonthModule,
AddonBlockCalendarUpcomingModule,
AddonBlockCommentsModule,
AddonBlockCompletionStatusModule,
AddonBlockGlossaryRandomModule,
AddonBlockHtmlModule,
AddonBlockMyOverviewModule,
AddonBlockLearningPlansModule,
AddonBlockNewsItemsModule,
AddonBlockOnlineUsersModule,
AddonBlockPrivateFilesModule,
AddonBlockRecentlyAccessedCoursesModule,
AddonBlockRssClientModule,
AddonBlockSelfCompletionModule,
AddonBlockSiteMainMenuModule,
AddonBlockStarredCoursesModule,
AddonBlockTagsModule,
AddonUserProfileFieldModule,
AddonNotificationsModule,
],
})
export class AddonsModule {}

View File

@ -0,0 +1,69 @@
// (C) Copyright 2015 Moodle Pty Ltd.
//
// 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 { AddonBlockActivityResultsModule } from './activityresults/activityresults.module';
import { AddonBlockBadgesModule } from './badges/badges.module';
import { AddonBlockBlogMenuModule } from './blogmenu/blogmenu.module';
import { AddonBlockBlogRecentModule } from './blogrecent/blogrecent.module';
import { AddonBlockBlogTagsModule } from './blogtags/blogtags.module';
import { AddonBlockCalendarMonthModule } from './calendarmonth/calendarmonth.module';
import { AddonBlockCalendarUpcomingModule } from './calendarupcoming/calendarupcoming.module';
import { AddonBlockCommentsModule } from './comments/comments.module';
import { AddonBlockCompletionStatusModule } from './completionstatus/completionstatus.module';
import { AddonBlockGlossaryRandomModule } from './glossaryrandom/glossaryrandom.module';
import { AddonBlockHtmlModule } from './html/html.module';
import { AddonBlockLearningPlansModule } from './learningplans/learningplans.module';
import { AddonBlockMyOverviewModule } from './myoverview/myoverview.module';
import { AddonBlockNewsItemsModule } from './newsitems/newsitems.module';
import { AddonBlockOnlineUsersModule } from './onlineusers/onlineusers.module';
import { AddonBlockPrivateFilesModule } from './privatefiles/privatefiles.module';
import { AddonBlockRecentlyAccessedCoursesModule } from './recentlyaccessedcourses/recentlyaccessedcourses.module';
import { AddonBlockRssClientModule } from './rssclient/rssclient.module';
import { AddonBlockSelfCompletionModule } from './selfcompletion/selfcompletion.module';
import { AddonBlockSiteMainMenuModule } from './sitemainmenu/sitemainmenu.module';
import { AddonBlockStarredCoursesModule } from './starredcourses/starredcourses.module';
import { AddonBlockTagsModule } from './tags/tags.module';
@NgModule({
declarations: [],
imports: [
AddonBlockActivityResultsModule,
AddonBlockBadgesModule,
AddonBlockBlogMenuModule,
AddonBlockBlogRecentModule,
AddonBlockBlogTagsModule,
AddonBlockCalendarMonthModule,
AddonBlockCalendarUpcomingModule,
AddonBlockCommentsModule,
AddonBlockCompletionStatusModule,
AddonBlockGlossaryRandomModule,
AddonBlockHtmlModule,
AddonBlockMyOverviewModule,
AddonBlockLearningPlansModule,
AddonBlockNewsItemsModule,
AddonBlockOnlineUsersModule,
AddonBlockPrivateFilesModule,
AddonBlockRecentlyAccessedCoursesModule,
AddonBlockRssClientModule,
AddonBlockSelfCompletionModule,
AddonBlockSiteMainMenuModule,
AddonBlockStarredCoursesModule,
AddonBlockTagsModule,
],
providers: [],
exports: [],
})
export class AddonBlockModule { }

View File

@ -0,0 +1,44 @@
// (C) Copyright 2015 Moodle Pty Ltd.
//
// 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 { Injector, NgModule } from '@angular/core';
import { RouterModule, ROUTES, Routes } from '@angular/router';
import { buildTabMainRoutes } from '@features/mainmenu/mainmenu-tab-routing.module';
function buildRoutes(injector: Injector): Routes {
return [
{
path: 'list',
loadChildren: () => import('./pages/list/list.module').then(m => m.AddonNotificationsListPageModule),
},
...buildTabMainRoutes(injector, {
redirectTo: 'list',
pathMatch: 'full',
}),
];
}
@NgModule({
exports: [RouterModule],
providers: [
{
provide: ROUTES,
multi: true,
deps: [Injector],
useFactory: buildRoutes,
},
],
})
export class AddonNotificationsLazyModule {}

View File

@ -0,0 +1,43 @@
// (C) Copyright 2015 Moodle Pty Ltd.
//
// 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 { APP_INITIALIZER, NgModule } from '@angular/core';
import { Routes } from '@angular/router';
import { CoreMainMenuDelegate } from '@features/mainmenu/services/mainmenu-delegate';
import { CoreMainMenuRoutingModule } from '@features/mainmenu/mainmenu-routing.module';
import { AddonNotificationsMainMenuHandler, AddonNotificationsMainMenuHandlerService } from './services/handlers/mainmenu';
const routes: Routes = [
{
path: AddonNotificationsMainMenuHandlerService.PAGE_NAME,
loadChildren: () => import('@/addons/notifications/notifications-lazy.module').then(m => m.AddonNotificationsLazyModule),
},
];
@NgModule({
imports: [CoreMainMenuRoutingModule.forChild({ children: routes })],
exports: [CoreMainMenuRoutingModule],
providers: [
{
provide: APP_INITIALIZER,
multi: true,
deps: [],
useFactory: () => () => {
CoreMainMenuDelegate.instance.registerHandler(AddonNotificationsMainMenuHandler.instance);
},
},
],
})
export class AddonNotificationsModule {}

View File

@ -0,0 +1,125 @@
// (C) Copyright 2015 Moodle Pty Ltd.
//
// 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 { Injectable } from '@angular/core';
import { CoreSites } from '@services/sites';
import { CoreUtils } from '@services/utils/utils';
import { makeSingleton } from '@singletons';
import { CoreEvents, CoreEventSiteData } from '@singletons/events';
import { CoreMainMenuHandler, CoreMainMenuHandlerData } from '@features/mainmenu/services/mainmenu-delegate';
import { CorePushNotifications } from '@features/pushnotifications/services/pushnotifications';
import { CorePushNotificationsDelegate } from '@features/pushnotifications/services/push-delegate';
import { AddonNotifications, AddonNotificationsProvider } from '../notifications';
/**
* Handler to inject an option into main menu.
*/
@Injectable({ providedIn: 'root' })
export class AddonNotificationsMainMenuHandlerService implements CoreMainMenuHandler {
static readonly PAGE_NAME = 'notifications';
name = 'AddonNotifications';
priority = 700;
protected handlerData: CoreMainMenuHandlerData = {
icon: 'fas-bell',
title: 'addon.notifications.notifications',
page: AddonNotificationsMainMenuHandlerService.PAGE_NAME,
class: 'addon-notifications-handler',
showBadge: true,
badge: '',
loading: true,
};
/**
* Initialize the handler.
*/
initialize(): void {
CoreEvents.on(AddonNotificationsProvider.READ_CHANGED_EVENT, (data: CoreEventSiteData) => {
this.updateBadge(data.siteId);
});
CoreEvents.on(AddonNotificationsProvider.READ_CRON_EVENT, (data: CoreEventSiteData) => {
this.updateBadge(data.siteId);
});
// Reset info on logout.
CoreEvents.on(CoreEvents.LOGOUT, () => {
this.handlerData.badge = '';
this.handlerData.loading = true;
});
// If a push notification is received, refresh the count.
CorePushNotificationsDelegate.instance.on('receive').subscribe((notification) => {
// New notification received. If it's from current site, refresh the data.
if (CoreUtils.instance.isTrueOrOne(notification.notif) && CoreSites.instance.isCurrentSite(notification.site)) {
this.updateBadge(notification.site);
}
});
// Register Badge counter.
CorePushNotificationsDelegate.instance.registerCounterHandler('AddonNotifications');
}
/**
* Check if the handler is enabled on a site level.
*
* @return Whether or not the handler is enabled on a site level.
*/
async isEnabled(): Promise<boolean> {
return true;
}
/**
* Returns the data needed to render the handler.
*
* @return Data needed to render the handler.
*/
getDisplayData(): CoreMainMenuHandlerData {
if (this.handlerData.loading) {
this.updateBadge();
}
return this.handlerData;
}
/**
* Triggers an update for the badge number and loading status. Mandatory if showBadge is enabled.
*
* @param siteId Site ID or current Site if undefined.
* @return Promise resolved when done.
*/
protected async updateBadge(siteId?: string): Promise<void> {
siteId = siteId || CoreSites.instance.getCurrentSiteId();
if (!siteId) {
return;
}
try {
const unreadCount = await AddonNotifications.instance.getUnreadNotificationsCount(undefined, siteId);
this.handlerData.badge = unreadCount > 0 ? String(unreadCount) : '';
CorePushNotifications.instance.updateAddonCounter('AddonNotifications', unreadCount, siteId);
} catch {
this.handlerData.badge = '';
} finally {
this.handlerData.loading = false;
}
}
}
export class AddonNotificationsMainMenuHandler extends makeSingleton(AddonNotificationsMainMenuHandlerService) {}