forked from EVOgeek/Vmeda.Online
		
	MOBILE-3631 messages: Settings page
This commit is contained in:
		
							parent
							
								
									04c6f4480d
								
							
						
					
					
						commit
						7a0f6867d6
					
				| @ -18,6 +18,7 @@ import { RouterModule, ROUTES, Routes } from '@angular/router'; | |||||||
| import { buildTabMainRoutes } from '@features/mainmenu/mainmenu-tab-routing.module'; | import { buildTabMainRoutes } from '@features/mainmenu/mainmenu-tab-routing.module'; | ||||||
| import { AddonMessagesContactsRoutingModule } from './pages/contacts/messages-contacts-routing.module'; | import { AddonMessagesContactsRoutingModule } from './pages/contacts/messages-contacts-routing.module'; | ||||||
| import { AddonMessagesIndexRoutingModule } from './pages/index-35/messages-index-routing.module'; | import { AddonMessagesIndexRoutingModule } from './pages/index-35/messages-index-routing.module'; | ||||||
|  | import { AddonMessagesSettingsHandlerService } from './services/handlers/settings'; | ||||||
| 
 | 
 | ||||||
| function buildRoutes(injector: Injector): Routes { | function buildRoutes(injector: Injector): Routes { | ||||||
|     return [ |     return [ | ||||||
| @ -35,6 +36,11 @@ function buildRoutes(injector: Injector): Routes { | |||||||
|             loadChildren: () => import('./pages/search/search.module') |             loadChildren: () => import('./pages/search/search.module') | ||||||
|                 .then(m => m.AddonMessagesSearchPageModule), |                 .then(m => m.AddonMessagesSearchPageModule), | ||||||
|         }, |         }, | ||||||
|  |         { | ||||||
|  |             path: AddonMessagesSettingsHandlerService.PAGE_NAME, | ||||||
|  |             loadChildren: () => import('./pages/settings/settings.module') | ||||||
|  |                 .then(m => m.AddonMessagesSettingsPageModule), | ||||||
|  |         }, | ||||||
|         { |         { | ||||||
|             path: 'contacts', // 3.6 or greater.
 |             path: 'contacts', // 3.6 or greater.
 | ||||||
|             loadChildren: () => import('./pages/contacts/contacts.module') |             loadChildren: () => import('./pages/contacts/contacts.module') | ||||||
|  | |||||||
| @ -21,6 +21,9 @@ import { CORE_SITE_SCHEMAS } from '@services/sites'; | |||||||
| import { CoreMainMenuDelegate } from '@features/mainmenu/services/mainmenu-delegate'; | import { CoreMainMenuDelegate } from '@features/mainmenu/services/mainmenu-delegate'; | ||||||
| import { AddonMessagesMainMenuHandler, AddonMessagesMainMenuHandlerService } from './services/handlers/mainmenu'; | import { AddonMessagesMainMenuHandler, AddonMessagesMainMenuHandlerService } from './services/handlers/mainmenu'; | ||||||
| import { CoreCronDelegate } from '@services/cron'; | import { CoreCronDelegate } from '@services/cron'; | ||||||
|  | import { CoreSettingsDelegate } from '@features/settings/services/settings-delegate'; | ||||||
|  | import { AddonMessagesSettingsHandler } from './services/handlers/settings'; | ||||||
|  | import { CoreMainMenuTabRoutingModule } from '@features/mainmenu/mainmenu-tab-routing.module'; | ||||||
| 
 | 
 | ||||||
| const mainMenuChildrenRoutes: Routes = [ | const mainMenuChildrenRoutes: Routes = [ | ||||||
|     { |     { | ||||||
| @ -32,6 +35,7 @@ const mainMenuChildrenRoutes: Routes = [ | |||||||
| @NgModule({ | @NgModule({ | ||||||
|     imports: [ |     imports: [ | ||||||
|         CoreMainMenuRoutingModule.forChild({ children: mainMenuChildrenRoutes }), |         CoreMainMenuRoutingModule.forChild({ children: mainMenuChildrenRoutes }), | ||||||
|  |         CoreMainMenuTabRoutingModule.forChild( mainMenuChildrenRoutes), | ||||||
|     ], |     ], | ||||||
|     providers: [ |     providers: [ | ||||||
|         { |         { | ||||||
| @ -46,6 +50,7 @@ const mainMenuChildrenRoutes: Routes = [ | |||||||
|             useFactory: () => () => { |             useFactory: () => () => { | ||||||
|                 CoreMainMenuDelegate.instance.registerHandler(AddonMessagesMainMenuHandler.instance); |                 CoreMainMenuDelegate.instance.registerHandler(AddonMessagesMainMenuHandler.instance); | ||||||
|                 CoreCronDelegate.instance.register(AddonMessagesMainMenuHandler.instance); |                 CoreCronDelegate.instance.register(AddonMessagesMainMenuHandler.instance); | ||||||
|  |                 CoreSettingsDelegate.instance.registerHandler(AddonMessagesSettingsHandler.instance); | ||||||
|             }, |             }, | ||||||
|         }, |         }, | ||||||
| 
 | 
 | ||||||
| @ -67,8 +72,6 @@ export class AddonMessagesModule { | |||||||
|         messagesProvider: AddonMessagesProvider, |         messagesProvider: AddonMessagesProvider, | ||||||
|         sitesProvider: CoreSitesProvider, |         sitesProvider: CoreSitesProvider, | ||||||
|         linkHelper: CoreContentLinksHelperProvider, |         linkHelper: CoreContentLinksHelperProvider, | ||||||
|         settingsHandler: AddonMessagesSettingsHandler, |  | ||||||
|         settingsDelegate: CoreSettingsDelegate, |  | ||||||
|         pushNotificationsDelegate: CorePushNotificationsDelegate, |         pushNotificationsDelegate: CorePushNotificationsDelegate, | ||||||
|         addContactHandler: AddonMessagesAddContactUserHandler, |         addContactHandler: AddonMessagesAddContactUserHandler, | ||||||
|         blockContactHandler: AddonMessagesBlockContactUserHandler, |         blockContactHandler: AddonMessagesBlockContactUserHandler, | ||||||
| @ -83,7 +86,6 @@ export class AddonMessagesModule { | |||||||
|         userDelegate.registerHandler(addContactHandler); |         userDelegate.registerHandler(addContactHandler); | ||||||
|         userDelegate.registerHandler(blockContactHandler); |         userDelegate.registerHandler(blockContactHandler); | ||||||
|         cronDelegate.register(syncHandler); |         cronDelegate.register(syncHandler); | ||||||
|         settingsDelegate.registerHandler(settingsHandler); |  | ||||||
|         pushNotificationsDelegate.registerClickHandler(pushClickHandler); |         pushNotificationsDelegate.registerClickHandler(pushClickHandler); | ||||||
| 
 | 
 | ||||||
|         // Sync some discussions when device goes online.
 |         // Sync some discussions when device goes online.
 | ||||||
|  | |||||||
| @ -38,6 +38,7 @@ import { | |||||||
|     AddonMessagesOfflineConversationMessagesDBRecordFormatted, |     AddonMessagesOfflineConversationMessagesDBRecordFormatted, | ||||||
|     AddonMessagesOfflineMessagesDBRecordFormatted, |     AddonMessagesOfflineMessagesDBRecordFormatted, | ||||||
| } from '@addons/messages/services/database/messages'; | } from '@addons/messages/services/database/messages'; | ||||||
|  | import { AddonMessagesSettingsHandlerService } from '@addons/messages/services/handlers/settings'; | ||||||
| // import { CoreSplitViewComponent } from '@components/split-view/split-view';
 | // import { CoreSplitViewComponent } from '@components/split-view/split-view';
 | ||||||
| 
 | 
 | ||||||
| /** | /** | ||||||
| @ -522,7 +523,7 @@ export class AddonMessagesGroupConversationsPage implements OnInit, OnDestroy { | |||||||
|      */ |      */ | ||||||
|     gotoSettings(): void { |     gotoSettings(): void { | ||||||
|         // @todo this.splitviewCtrl.push
 |         // @todo this.splitviewCtrl.push
 | ||||||
|         CoreNavigator.instance.navigateToSitePath('settings'); |         CoreNavigator.instance.navigateToSitePath(AddonMessagesSettingsHandlerService.PAGE_NAME); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     /** |     /** | ||||||
|  | |||||||
							
								
								
									
										145
									
								
								src/addons/messages/pages/settings/settings.html
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										145
									
								
								src/addons/messages/pages/settings/settings.html
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,145 @@ | |||||||
|  | <ion-header> | ||||||
|  |     <ion-toolbar> | ||||||
|  |         <ion-buttons slot="start"> | ||||||
|  |             <ion-back-button [attr.aria-label]="'core.back' | translate"></ion-back-button> | ||||||
|  |         </ion-buttons> | ||||||
|  |         <ion-title>{{ 'addon.messages.messages' | translate }}</ion-title> | ||||||
|  |     </ion-toolbar> | ||||||
|  | </ion-header> | ||||||
|  | <ion-content> | ||||||
|  |     <ion-refresher slot="fixed" [disabled]="!preferencesLoaded" (ionRefresh)="refreshPreferences($event)"> | ||||||
|  |         <ion-refresher-content pullingText="{{ 'core.pulltorefresh' | translate }}"></ion-refresher-content> | ||||||
|  |     </ion-refresher> | ||||||
|  |     <core-loading [hideUntil]="preferencesLoaded"> | ||||||
|  |         <!-- Contactable privacy. --> | ||||||
|  |         <ion-card> | ||||||
|  |             <ion-item *ngIf="!advancedContactable"> | ||||||
|  |               <ion-label>{{ 'addon.messages.blocknoncontacts' | translate }}</ion-label> | ||||||
|  |               <ion-toggle [(ngModel)]="contactablePrivacy" (ngModelChange)="saveContactablePrivacy(contactablePrivacy)"> | ||||||
|  |               </ion-toggle> | ||||||
|  |             </ion-item> | ||||||
|  | 
 | ||||||
|  |             <ion-list *ngIf="advancedContactable" class="ion-text-wrap"> | ||||||
|  |                 <ion-radio-group [(ngModel)]="contactablePrivacy" (ionChange)="saveContactablePrivacy(contactablePrivacy)"> | ||||||
|  |                     <ion-item-divider> | ||||||
|  |                         <ion-label><h2>{{ 'addon.messages.contactableprivacy' | translate }}</h2></ion-label> | ||||||
|  |                     </ion-item-divider> | ||||||
|  |                     <ion-item> | ||||||
|  |                         <ion-label>{{ 'addon.messages.contactableprivacy_onlycontacts' | translate }}</ion-label> | ||||||
|  |                         <ion-radio slot="start" [value]="onlyContactsValue"></ion-radio> | ||||||
|  |                     </ion-item> | ||||||
|  |                     <ion-item> | ||||||
|  |                         <ion-label>{{ 'addon.messages.contactableprivacy_coursemember' | translate }}</ion-label> | ||||||
|  |                         <ion-radio slot="start" [value]="courseMemberValue"></ion-radio> | ||||||
|  |                     </ion-item> | ||||||
|  |                     <ion-item *ngIf="allowSiteMessaging"> | ||||||
|  |                         <ion-label>{{ 'addon.messages.contactableprivacy_site' | translate }}</ion-label> | ||||||
|  |                         <ion-radio slot="start" [value]="siteValue"></ion-radio> | ||||||
|  |                     </ion-item> | ||||||
|  |                 </ion-radio-group> | ||||||
|  |             </ion-list> | ||||||
|  |         </ion-card> | ||||||
|  | 
 | ||||||
|  |         <!-- Notifications. --> | ||||||
|  |         <ng-container *ngIf="preferences"> | ||||||
|  |             <div *ngFor="let component of preferences.components"> | ||||||
|  |                 <ion-card list *ngFor="let notification of component.notifications"> | ||||||
|  |                     <ion-item-divider class="ion-text-wrap"> | ||||||
|  |                         <ion-label> | ||||||
|  |                             <ion-row class="ion-no-padding" *ngIf="!groupMessagingEnabled"> | ||||||
|  |                                 <ion-col class="ion-no-padding"> | ||||||
|  |                                     <h2>{{ notification.displayname }}</h2> | ||||||
|  |                                 </ion-col> | ||||||
|  |                                 <ion-col size="2" class="ion-text-center ion-no-padding ion-hide-md-down"> | ||||||
|  |                                     <h2>{{ 'core.settings.loggedin' | translate }}</h2> | ||||||
|  |                                 </ion-col> | ||||||
|  |                                 <ion-col *ngIf="!groupMessagingEnabled" size="2" class="ion-text-center ion-no-padding | ||||||
|  |                                     ion-hide-md-down"> | ||||||
|  |                                     <h2>{{ 'core.settings.loggedoff' | translate }}</h2> | ||||||
|  |                                 </ion-col> | ||||||
|  |                             </ion-row> | ||||||
|  |                             <h2 *ngIf="groupMessagingEnabled">{{ 'addon.notifications.notificationpreferences' | translate }}</h2> | ||||||
|  |                         </ion-label> | ||||||
|  |                     </ion-item-divider> | ||||||
|  |                     <ng-container *ngFor="let processor of notification.processors"> | ||||||
|  |                         <!-- If group messaging is enabled, display a simplified view. --> | ||||||
|  |                         <ng-container *ngIf="groupMessagingEnabled"> | ||||||
|  |                             <ion-item class="ion-text-wrap"> | ||||||
|  |                                 <ion-label>{{ processor.displayname }}</ion-label> | ||||||
|  |                                 <ion-spinner slot="end" *ngIf="!preferences.disableall && notification.updating"></ion-spinner> | ||||||
|  |                                 <ion-toggle slot="end" *ngIf="!preferences.disableall && !processor.locked" | ||||||
|  |                                     [(ngModel)]="processor.checked" (ngModelChange)="changePreference(notification, '', processor)" | ||||||
|  |                                     [disabled]="notification.updating"> | ||||||
|  |                                 </ion-toggle> | ||||||
|  |                                 <ion-note slot="end" *ngIf="!preferences.disableall && processor.locked"> | ||||||
|  |                                     {{ processor.lockedmessage }} | ||||||
|  |                                 </ion-note> | ||||||
|  |                                 <ion-note slot="end" *ngIf="preferences.disableall"> | ||||||
|  |                                     {{ 'core.settings.disabled' | translate }} | ||||||
|  |                                 </ion-note> | ||||||
|  |                             </ion-item> | ||||||
|  |                         </ng-container> | ||||||
|  | 
 | ||||||
|  |                         <ng-container *ngIf="!groupMessagingEnabled"> | ||||||
|  |                             <!-- Tablet view --> | ||||||
|  |                             <ion-row class="ion-text-wrap ion-hide-md-down ion-align-items-center"> | ||||||
|  |                                 <ion-col  class="ion-margin-horizontal">{{ processor.displayname }}</ion-col> | ||||||
|  |                                 <ion-col size="2" class="ion-text-center" *ngFor="let state of ['loggedin', 'loggedoff']"> | ||||||
|  |                                     <!-- If notifications not disabled, show toggle. --> | ||||||
|  |                                     <ion-spinner [hidden]="preferences.disableall || | ||||||
|  |                                         !(notification.updating && notification.updating[state])"></ion-spinner> | ||||||
|  |                                     <ion-toggle *ngIf="!preferences.disableall && !processor.locked" | ||||||
|  |                                         [(ngModel)]="processor[state].checked" | ||||||
|  |                                         (ngModelChange)="changePreference(notification, state, processor)" | ||||||
|  |                                         [disabled]="notification.updating && notification.updating[state]"> | ||||||
|  |                                     </ion-toggle> | ||||||
|  |                                     <div class="ion-padding text-gray" *ngIf="!preferences.disableall && processor.locked"> | ||||||
|  |                                         {{'core.settings.locked' | translate }} | ||||||
|  |                                     </div> | ||||||
|  |                                     <!-- If notifications are disabled, show "Disabled" instead of toggle. --> | ||||||
|  |                                     <span *ngIf="preferences.disableall">{{ 'core.settings.disabled' | translate }}</span> | ||||||
|  |                                 </ion-col> | ||||||
|  |                             </ion-row> | ||||||
|  |                             <!-- Phone view --> | ||||||
|  |                             <ion-list-header class="ion-text-wrap ion-hide-md-up"> | ||||||
|  |                                 <ion-label>{{ processor.displayname }}</ion-label> | ||||||
|  |                             </ion-list-header> | ||||||
|  |                             <!-- If notifications not disabled, show toggles. | ||||||
|  |                                 If notifications are disabled, show "Disabled" instead of toggle. --> | ||||||
|  |                             <ion-item *ngFor="let state of ['loggedin', 'loggedoff']" class="ion-text-wrap ion-hide-md-up"> | ||||||
|  |                                 <ion-label>{{ 'core.settings.' + state | translate }}</ion-label> | ||||||
|  |                                 <ion-spinner slot="end" | ||||||
|  |                                     *ngIf="!preferences.disableall && (notification.updating && notification.updating[state])"> | ||||||
|  |                                 </ion-spinner> | ||||||
|  |                                 <ion-toggle slot="end" *ngIf="!preferences.disableall && !processor.locked" | ||||||
|  |                                     [(ngModel)]="processor[state].checked" | ||||||
|  |                                     (ngModelChange)="changePreference(notification, state, processor)" | ||||||
|  |                                     [disabled]="notification.updating && notification.updating[state]"> | ||||||
|  |                                 </ion-toggle> | ||||||
|  |                                 <ion-note slot="end" *ngIf="!preferences.disableall && processor.locked"> | ||||||
|  |                                     {{'core.settings.locked' | translate }} | ||||||
|  |                                 </ion-note> | ||||||
|  |                                 <ion-note slot="end" *ngIf="preferences.disableall"> | ||||||
|  |                                     {{ 'core.settings.disabled' | translate }} | ||||||
|  |                                 </ion-note> | ||||||
|  |                             </ion-item> | ||||||
|  |                         </ng-container> | ||||||
|  |                     </ng-container> | ||||||
|  |                 </ion-card> | ||||||
|  |             </div> | ||||||
|  |         </ng-container> | ||||||
|  | 
 | ||||||
|  |         <!-- General settings. --> | ||||||
|  |         <ion-card> | ||||||
|  |             <ion-list class="ion-text-wrap"> | ||||||
|  |                 <ion-item-divider><ion-label><h2>{{ 'core.settings.general' | translate }}</h2></ion-label></ion-item-divider> | ||||||
|  |                 <ion-item class="ion-text-wrap"> | ||||||
|  |                     <ion-label> | ||||||
|  |                         <h2>{{ 'addon.messages.useentertosend' | translate }}</h2> | ||||||
|  |                     </ion-label> | ||||||
|  |                     <ion-toggle [(ngModel)]="sendOnEnter" (ngModelChange)="sendOnEnterChanged()"></ion-toggle> | ||||||
|  |                 </ion-item> | ||||||
|  |             </ion-list> | ||||||
|  |         </ion-card> | ||||||
|  |     </core-loading> | ||||||
|  | </ion-content> | ||||||
							
								
								
									
										47
									
								
								src/addons/messages/pages/settings/settings.module.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										47
									
								
								src/addons/messages/pages/settings/settings.module.ts
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,47 @@ | |||||||
|  | // (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 { IonicModule } from '@ionic/angular'; | ||||||
|  | import { TranslateModule } from '@ngx-translate/core'; | ||||||
|  | import { RouterModule, Routes } from '@angular/router'; | ||||||
|  | import { CommonModule } from '@angular/common'; | ||||||
|  | import { FormsModule } from '@angular/forms'; | ||||||
|  | 
 | ||||||
|  | import { CoreSharedModule } from '@/core/shared.module'; | ||||||
|  | 
 | ||||||
|  | import { AddonMessagesSettingsPage } from './settings.page'; | ||||||
|  | 
 | ||||||
|  | const routes: Routes = [ | ||||||
|  |     { | ||||||
|  |         path: '', | ||||||
|  |         component: AddonMessagesSettingsPage, | ||||||
|  |     }, | ||||||
|  | ]; | ||||||
|  | 
 | ||||||
|  | @NgModule({ | ||||||
|  |     imports: [ | ||||||
|  |         RouterModule.forChild(routes), | ||||||
|  |         CommonModule, | ||||||
|  |         IonicModule, | ||||||
|  |         FormsModule, | ||||||
|  |         TranslateModule.forChild(), | ||||||
|  |         CoreSharedModule, | ||||||
|  |     ], | ||||||
|  |     declarations: [ | ||||||
|  |         AddonMessagesSettingsPage, | ||||||
|  |     ], | ||||||
|  |     exports: [RouterModule], | ||||||
|  | }) | ||||||
|  | export class AddonMessagesSettingsPageModule {} | ||||||
							
								
								
									
										300
									
								
								src/addons/messages/pages/settings/settings.page.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										300
									
								
								src/addons/messages/pages/settings/settings.page.ts
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,300 @@ | |||||||
|  | // (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 { Component, OnDestroy, OnInit } from '@angular/core'; | ||||||
|  | import { | ||||||
|  |     AddonMessagesProvider, AddonMessagesMessagePreferences, | ||||||
|  |     AddonMessagesMessagePreferencesNotification, | ||||||
|  |     AddonMessagesMessagePreferencesNotificationProcessor, | ||||||
|  |     AddonMessages, | ||||||
|  | } from '../../services/messages'; | ||||||
|  | import { CoreUser } from '@features/user/services/user'; | ||||||
|  | import { CoreApp } from '@services/app'; | ||||||
|  | import { CoreConfig } from '@services/config'; | ||||||
|  | import { CoreEvents } from '@singletons/events'; | ||||||
|  | import { CoreSites } from '@services/sites'; | ||||||
|  | import { CoreDomUtils } from '@services/utils/dom'; | ||||||
|  | import { CoreConstants } from '@/core/constants'; | ||||||
|  | import { IonRefresher } from '@ionic/angular'; | ||||||
|  | 
 | ||||||
|  | /** | ||||||
|  |  * Page that displays the messages settings page. | ||||||
|  |  */ | ||||||
|  | @Component({ | ||||||
|  |     selector: 'page-addon-messages-settings', | ||||||
|  |     templateUrl: 'settings.html', | ||||||
|  |     styleUrls: ['settings.scss'], | ||||||
|  | }) | ||||||
|  | export class AddonMessagesSettingsPage implements OnInit, OnDestroy { | ||||||
|  | 
 | ||||||
|  |     protected updateTimeout?: number; | ||||||
|  | 
 | ||||||
|  |     preferences?: AddonMessagesMessagePreferences; | ||||||
|  |     preferencesLoaded = false; | ||||||
|  |     contactablePrivacy?: number | boolean; | ||||||
|  |     advancedContactable = false; // Whether the site supports "advanced" contactable privacy.
 | ||||||
|  |     allowSiteMessaging = false; | ||||||
|  |     onlyContactsValue = AddonMessagesProvider.MESSAGE_PRIVACY_ONLYCONTACTS; | ||||||
|  |     courseMemberValue = AddonMessagesProvider.MESSAGE_PRIVACY_COURSEMEMBER; | ||||||
|  |     siteValue = AddonMessagesProvider.MESSAGE_PRIVACY_SITE; | ||||||
|  |     groupMessagingEnabled = false; | ||||||
|  |     sendOnEnter = false; | ||||||
|  | 
 | ||||||
|  |     protected previousContactableValue?: number | boolean; | ||||||
|  | 
 | ||||||
|  |     constructor() { | ||||||
|  | 
 | ||||||
|  |         const currentSite = CoreSites.instance.getCurrentSite(); | ||||||
|  |         this.advancedContactable = !!currentSite?.isVersionGreaterEqualThan('3.6'); | ||||||
|  |         this.allowSiteMessaging = !!currentSite?.canUseAdvancedFeature('messagingallusers'); | ||||||
|  |         this.groupMessagingEnabled = AddonMessages.instance.isGroupMessagingEnabled(); | ||||||
|  | 
 | ||||||
|  |         this.asyncInit(); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     protected async asyncInit(): Promise<void> { | ||||||
|  |         this.sendOnEnter = !!(await CoreConfig.instance.get(CoreConstants.SETTINGS_SEND_ON_ENTER, !CoreApp.instance.isMobile())); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     /** | ||||||
|  |      * Runs when the page has loaded. This event only happens once per page being created. | ||||||
|  |      * If a page leaves but is cached, then this event will not fire again on a subsequent viewing. | ||||||
|  |      * Setup code for the page. | ||||||
|  |      */ | ||||||
|  |     ngOnInit(): void { | ||||||
|  |         this.fetchPreferences(); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     /** | ||||||
|  |      * Fetches preference data. | ||||||
|  |      * | ||||||
|  |      * @return Promise resolved when done. | ||||||
|  |      */ | ||||||
|  |     protected async fetchPreferences(): Promise<void> { | ||||||
|  |         try { | ||||||
|  |             const preferences = await AddonMessages.instance.getMessagePreferences(); | ||||||
|  |             if (this.groupMessagingEnabled) { | ||||||
|  |                 // Simplify the preferences.
 | ||||||
|  |                 for (const component of preferences.components) { | ||||||
|  |                     // Only display get the notification preferences.
 | ||||||
|  |                     component.notifications = component.notifications.filter((notification) => | ||||||
|  |                         notification.preferencekey == AddonMessagesProvider.NOTIFICATION_PREFERENCES_KEY); | ||||||
|  | 
 | ||||||
|  |                     component.notifications.forEach((notification) => { | ||||||
|  |                         notification.processors.forEach( | ||||||
|  |                             (processor: AddonMessagesMessagePreferencesNotificationProcessorFormatted) => { | ||||||
|  |                                 processor.checked = processor.loggedin.checked || processor.loggedoff.checked; | ||||||
|  |                             }, | ||||||
|  |                         ); | ||||||
|  |                     }); | ||||||
|  |                 } | ||||||
|  |             } | ||||||
|  | 
 | ||||||
|  |             this.preferences = preferences; | ||||||
|  |             this.contactablePrivacy = preferences.blocknoncontacts; | ||||||
|  |             this.previousContactableValue = this.contactablePrivacy; | ||||||
|  |         } catch (error) { | ||||||
|  |             CoreDomUtils.instance.showErrorModal(error); | ||||||
|  |         } finally { | ||||||
|  |             this.preferencesLoaded = true; | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     /** | ||||||
|  |      * Update preferences. The purpose is to store the updated data, it won't be reflected in the view. | ||||||
|  |      */ | ||||||
|  |     protected updatePreferences(): void { | ||||||
|  |         AddonMessages.instance.invalidateMessagePreferences().finally(() => { | ||||||
|  |             this.fetchPreferences(); | ||||||
|  |         }); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     /** | ||||||
|  |      * Update preferences after a certain time. The purpose is to store the updated data, it won't be reflected in the view. | ||||||
|  |      */ | ||||||
|  |     protected updatePreferencesAfterDelay(): void { | ||||||
|  |         // Cancel pending updates.
 | ||||||
|  |         clearTimeout(this.updateTimeout); | ||||||
|  | 
 | ||||||
|  |         this.updateTimeout = window.setTimeout(() => { | ||||||
|  |             this.updateTimeout = undefined; | ||||||
|  |             this.updatePreferences(); | ||||||
|  |         }, 5000); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     /** | ||||||
|  |      * Save the contactable privacy setting.. | ||||||
|  |      * | ||||||
|  |      * @param value The value to set. | ||||||
|  |      */ | ||||||
|  |     async saveContactablePrivacy(value?: number | boolean): Promise<void> { | ||||||
|  |         if (this.contactablePrivacy == this.previousContactableValue) { | ||||||
|  |             // Value hasn't changed from previous, it probably means that we just fetched the value from the server.
 | ||||||
|  |             return; | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         const modal = await CoreDomUtils.instance.showModalLoading('core.sending', true); | ||||||
|  | 
 | ||||||
|  |         if (!this.advancedContactable) { | ||||||
|  |             // Convert from boolean to number.
 | ||||||
|  |             value = value ? 1 : 0; | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         try { | ||||||
|  |             await CoreUser.instance.updateUserPreference('message_blocknoncontacts', String(value)); | ||||||
|  |             // Update the preferences since they were modified.
 | ||||||
|  |             this.updatePreferencesAfterDelay(); | ||||||
|  |             this.previousContactableValue = this.contactablePrivacy; | ||||||
|  |         } catch (message) { | ||||||
|  |             // Show error and revert change.
 | ||||||
|  |             CoreDomUtils.instance.showErrorModal(message); | ||||||
|  |             this.contactablePrivacy = this.previousContactableValue; | ||||||
|  |         } finally { | ||||||
|  |             modal.dismiss(); | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     /** | ||||||
|  |      * Change the value of a certain preference. | ||||||
|  |      * | ||||||
|  |      * @param notification Notification object. | ||||||
|  |      * @param state State name, ['loggedin', 'loggedoff']. | ||||||
|  |      * @param processor Notification processor. | ||||||
|  |      */ | ||||||
|  |     async changePreference( | ||||||
|  |         notification: AddonMessagesMessagePreferencesNotificationFormatted, | ||||||
|  |         state: string, | ||||||
|  |         processor: AddonMessagesMessagePreferencesNotificationProcessorFormatted, | ||||||
|  |     ): Promise<void> { | ||||||
|  | 
 | ||||||
|  |         const valueArray: string[] = []; | ||||||
|  |         let value = 'none'; | ||||||
|  | 
 | ||||||
|  |         if (this.groupMessagingEnabled) { | ||||||
|  |             // Update both states at the same time.
 | ||||||
|  |             const promises: Promise<void>[] = []; | ||||||
|  | 
 | ||||||
|  |             notification.processors.forEach((processor: AddonMessagesMessagePreferencesNotificationProcessorFormatted) => { | ||||||
|  |                 if (processor.checked) { | ||||||
|  |                     valueArray.push(processor.name); | ||||||
|  |                 } | ||||||
|  |             }); | ||||||
|  | 
 | ||||||
|  |             if (value.length > 0) { | ||||||
|  |                 value = valueArray.join(','); | ||||||
|  |             } | ||||||
|  | 
 | ||||||
|  |             notification.updating = true; | ||||||
|  | 
 | ||||||
|  |             promises.push(CoreUser.instance.updateUserPreference(notification.preferencekey + '_loggedin', value)); | ||||||
|  |             promises.push(CoreUser.instance.updateUserPreference(notification.preferencekey + '_loggedoff', value)); | ||||||
|  | 
 | ||||||
|  |             try { | ||||||
|  |                 await Promise.all(promises); | ||||||
|  |                 // Update the preferences since they were modified.
 | ||||||
|  |                 this.updatePreferencesAfterDelay(); | ||||||
|  |             } catch (error) { | ||||||
|  |                 // Show error and revert change.
 | ||||||
|  |                 CoreDomUtils.instance.showErrorModal(error); | ||||||
|  |                 processor.checked = !processor.checked; | ||||||
|  |             } finally { | ||||||
|  |                 notification.updating = false; | ||||||
|  |             } | ||||||
|  | 
 | ||||||
|  |             return; | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         // Update only the specified state.
 | ||||||
|  |         const processorState = processor[state]; | ||||||
|  |         const preferenceName = notification.preferencekey + '_' + processorState.name; | ||||||
|  | 
 | ||||||
|  |         notification.processors.forEach((processor) => { | ||||||
|  |             if (processor[state].checked) { | ||||||
|  |                 valueArray.push(processor.name); | ||||||
|  |             } | ||||||
|  |         }); | ||||||
|  | 
 | ||||||
|  |         if (value.length > 0) { | ||||||
|  |             value = valueArray.join(','); | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         if (!notification.updating) { | ||||||
|  |             notification.updating = {}; | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         notification.updating[state] = true; | ||||||
|  |         try { | ||||||
|  |             await CoreUser.instance.updateUserPreference(preferenceName, value); | ||||||
|  |             // Update the preferences since they were modified.
 | ||||||
|  |             this.updatePreferencesAfterDelay(); | ||||||
|  |         } catch (error) { | ||||||
|  |             // Show error and revert change.
 | ||||||
|  |             CoreDomUtils.instance.showErrorModal(error); | ||||||
|  |             processorState.checked = !processorState.checked; | ||||||
|  |         } finally { | ||||||
|  |             notification.updating[state] = false; | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     /** | ||||||
|  |      * Refresh the list of preferences. | ||||||
|  |      * | ||||||
|  |      * @param refresher Refresher. | ||||||
|  |      */ | ||||||
|  |     refreshPreferences(refresher?: CustomEvent<IonRefresher>): void { | ||||||
|  |         AddonMessages.instance.invalidateMessagePreferences().finally(() => { | ||||||
|  |             this.fetchPreferences().finally(() => { | ||||||
|  |                 refresher?.detail.complete(); | ||||||
|  |             }); | ||||||
|  |         }); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     sendOnEnterChanged(): void { | ||||||
|  |         // Save the value.
 | ||||||
|  |         CoreConfig.instance.set(CoreConstants.SETTINGS_SEND_ON_ENTER, this.sendOnEnter ? 1 : 0); | ||||||
|  | 
 | ||||||
|  |         // Notify the app.
 | ||||||
|  |         CoreEvents.trigger( | ||||||
|  |             CoreEvents.SEND_ON_ENTER_CHANGED, | ||||||
|  |             { sendOnEnter: !!this.sendOnEnter }, | ||||||
|  |             CoreSites.instance.getCurrentSiteId(), | ||||||
|  |         ); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     /** | ||||||
|  |      * Page destroyed. | ||||||
|  |      */ | ||||||
|  |     ngOnDestroy(): void { | ||||||
|  |         // If there is a pending action to update preferences, execute it right now.
 | ||||||
|  |         if (this.updateTimeout) { | ||||||
|  |             clearTimeout(this.updateTimeout); | ||||||
|  |             this.updatePreferences(); | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /** | ||||||
|  |  * Message preferences notification with some caclulated data. | ||||||
|  |  */ | ||||||
|  | type AddonMessagesMessagePreferencesNotificationFormatted = AddonMessagesMessagePreferencesNotification & { | ||||||
|  |     updating?: boolean | {[state: string]: boolean}; // Calculated in the app. Whether the notification is being updated.
 | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | /** | ||||||
|  |  * Message preferences notification processor with some caclulated data. | ||||||
|  |  */ | ||||||
|  | type AddonMessagesMessagePreferencesNotificationProcessorFormatted = AddonMessagesMessagePreferencesNotificationProcessor & { | ||||||
|  |     checked?: boolean; // Calculated in the app. Whether the processor is checked either for loggedin or loggedoff.
 | ||||||
|  | }; | ||||||
							
								
								
									
										10
									
								
								src/addons/messages/pages/settings/settings.scss
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										10
									
								
								src/addons/messages/pages/settings/settings.scss
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,10 @@ | |||||||
|  | ion-app.app-root page-addon-messages-settings { | ||||||
|  |     .list-header { | ||||||
|  |         margin-bottom: 0; | ||||||
|  |         border-top: 0; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     .toggle { | ||||||
|  |         display: inline-block; | ||||||
|  |     } | ||||||
|  | } | ||||||
							
								
								
									
										60
									
								
								src/addons/messages/services/handlers/settings.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										60
									
								
								src/addons/messages/services/handlers/settings.ts
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,60 @@ | |||||||
|  | // (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 { CoreSettingsHandler, CoreSettingsHandlerData } from '@features/settings/services/settings-delegate'; | ||||||
|  | import { makeSingleton } from '@singletons'; | ||||||
|  | import { AddonMessages } from '../messages'; | ||||||
|  | import { AddonMessagesMainMenuHandlerService } from './mainmenu'; | ||||||
|  | 
 | ||||||
|  | /** | ||||||
|  |  * Message settings handler. | ||||||
|  |  */ | ||||||
|  | @Injectable({ providedIn: 'root' }) | ||||||
|  | export class AddonMessagesSettingsHandlerService implements CoreSettingsHandler { | ||||||
|  | 
 | ||||||
|  |     static readonly PAGE_NAME = 'settings'; | ||||||
|  | 
 | ||||||
|  |     name = 'AddonMessages'; | ||||||
|  |     priority = 600; | ||||||
|  | 
 | ||||||
|  |     /** | ||||||
|  |      * 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> { | ||||||
|  |         const messagingEnabled = await AddonMessages.instance.isPluginEnabled(); | ||||||
|  | 
 | ||||||
|  |         return messagingEnabled && AddonMessages.instance.isMessagePreferencesEnabled(); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     /** | ||||||
|  |      * Returns the data needed to render the handler. | ||||||
|  |      * | ||||||
|  |      * @return Data needed to render the handler. | ||||||
|  |      */ | ||||||
|  |     getDisplayData(): CoreSettingsHandlerData { | ||||||
|  |         return { | ||||||
|  |             icon: 'fas-comments', | ||||||
|  |             title: 'addon.messages.messages', | ||||||
|  |             page: AddonMessagesMainMenuHandlerService.PAGE_NAME + '/' + AddonMessagesSettingsHandlerService.PAGE_NAME, | ||||||
|  |             class: 'addon-messages-settings-handler', | ||||||
|  |         }; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | export class AddonMessagesSettingsHandler extends makeSingleton(AddonMessagesSettingsHandlerService) {} | ||||||
|  | 
 | ||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user