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 { AddonMessagesContactsRoutingModule } from './pages/contacts/messages-contacts-routing.module'; | ||||
| import { AddonMessagesIndexRoutingModule } from './pages/index-35/messages-index-routing.module'; | ||||
| import { AddonMessagesSettingsHandlerService } from './services/handlers/settings'; | ||||
| 
 | ||||
| function buildRoutes(injector: Injector): Routes { | ||||
|     return [ | ||||
| @ -35,6 +36,11 @@ function buildRoutes(injector: Injector): Routes { | ||||
|             loadChildren: () => import('./pages/search/search.module') | ||||
|                 .then(m => m.AddonMessagesSearchPageModule), | ||||
|         }, | ||||
|         { | ||||
|             path: AddonMessagesSettingsHandlerService.PAGE_NAME, | ||||
|             loadChildren: () => import('./pages/settings/settings.module') | ||||
|                 .then(m => m.AddonMessagesSettingsPageModule), | ||||
|         }, | ||||
|         { | ||||
|             path: 'contacts', // 3.6 or greater.
 | ||||
|             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 { AddonMessagesMainMenuHandler, AddonMessagesMainMenuHandlerService } from './services/handlers/mainmenu'; | ||||
| 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 = [ | ||||
|     { | ||||
| @ -32,6 +35,7 @@ const mainMenuChildrenRoutes: Routes = [ | ||||
| @NgModule({ | ||||
|     imports: [ | ||||
|         CoreMainMenuRoutingModule.forChild({ children: mainMenuChildrenRoutes }), | ||||
|         CoreMainMenuTabRoutingModule.forChild( mainMenuChildrenRoutes), | ||||
|     ], | ||||
|     providers: [ | ||||
|         { | ||||
| @ -46,6 +50,7 @@ const mainMenuChildrenRoutes: Routes = [ | ||||
|             useFactory: () => () => { | ||||
|                 CoreMainMenuDelegate.instance.registerHandler(AddonMessagesMainMenuHandler.instance); | ||||
|                 CoreCronDelegate.instance.register(AddonMessagesMainMenuHandler.instance); | ||||
|                 CoreSettingsDelegate.instance.registerHandler(AddonMessagesSettingsHandler.instance); | ||||
|             }, | ||||
|         }, | ||||
| 
 | ||||
| @ -67,8 +72,6 @@ export class AddonMessagesModule { | ||||
|         messagesProvider: AddonMessagesProvider, | ||||
|         sitesProvider: CoreSitesProvider, | ||||
|         linkHelper: CoreContentLinksHelperProvider, | ||||
|         settingsHandler: AddonMessagesSettingsHandler, | ||||
|         settingsDelegate: CoreSettingsDelegate, | ||||
|         pushNotificationsDelegate: CorePushNotificationsDelegate, | ||||
|         addContactHandler: AddonMessagesAddContactUserHandler, | ||||
|         blockContactHandler: AddonMessagesBlockContactUserHandler, | ||||
| @ -83,7 +86,6 @@ export class AddonMessagesModule { | ||||
|         userDelegate.registerHandler(addContactHandler); | ||||
|         userDelegate.registerHandler(blockContactHandler); | ||||
|         cronDelegate.register(syncHandler); | ||||
|         settingsDelegate.registerHandler(settingsHandler); | ||||
|         pushNotificationsDelegate.registerClickHandler(pushClickHandler); | ||||
| 
 | ||||
|         // Sync some discussions when device goes online.
 | ||||
|  | ||||
| @ -38,6 +38,7 @@ import { | ||||
|     AddonMessagesOfflineConversationMessagesDBRecordFormatted, | ||||
|     AddonMessagesOfflineMessagesDBRecordFormatted, | ||||
| } from '@addons/messages/services/database/messages'; | ||||
| import { AddonMessagesSettingsHandlerService } from '@addons/messages/services/handlers/settings'; | ||||
| // import { CoreSplitViewComponent } from '@components/split-view/split-view';
 | ||||
| 
 | ||||
| /** | ||||
| @ -522,7 +523,7 @@ export class AddonMessagesGroupConversationsPage implements OnInit, OnDestroy { | ||||
|      */ | ||||
|     gotoSettings(): void { | ||||
|         // @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