MOBILE-3976 notifications: Use new enabled setting on 4.0 onward
parent
0b50611700
commit
93251a5594
|
@ -35,75 +35,144 @@
|
|||
</ion-card>
|
||||
|
||||
<!-- Show processor selector. -->
|
||||
<core-combobox *ngIf="preferences && preferences.processors && preferences.processors.length > 0"
|
||||
[selection]="currentProcessor!.name" (onChange)="changeProcessor($event)">
|
||||
<core-combobox *ngIf="preferences && preferences.processors && preferences.processors.length > 0" [selection]="currentProcessorName"
|
||||
(onChange)="changeProcessor($event)">
|
||||
<ion-select-option class="ion-text-wrap" *ngFor="let processor of preferences.processors" [value]="processor.name">
|
||||
{{ processor.displayname }}
|
||||
</ion-select-option>
|
||||
</core-combobox>
|
||||
|
||||
<ion-card list *ngFor="let component of components" class="ion-margin-top">
|
||||
<ion-item-divider class="ion-text-wrap">
|
||||
<ion-grid class="ion-no-padding">
|
||||
<ion-row class="ion-no-padding">
|
||||
<ion-col class="ion-no-padding">{{ component.displayname }}</ion-col>
|
||||
<ion-col size="2" class="ion-text-center ion-no-padding ion-hide-md-down">
|
||||
{{ 'core.settings.loggedin' | translate }}
|
||||
</ion-col>
|
||||
<ion-col size="2" class="ion-text-center ion-no-padding ion-hide-md-down">
|
||||
{{ 'core.settings.loggedoff' | translate }}
|
||||
</ion-col>
|
||||
</ion-row>
|
||||
</ion-grid>
|
||||
</ion-item-divider>
|
||||
<ng-container *ngFor="let notification of component.notifications">
|
||||
<!-- Tablet view -->
|
||||
<ion-grid class="ion-text-wrap ion-hide-md-down addon-notifications-table-content">
|
||||
<ion-row class="ion-align-items-center">
|
||||
<ion-col class="ion-margin-horizontal">{{ notification.displayname }}</ion-col>
|
||||
<ion-col size="2" class="ion-text-center" *ngFor="let state of ['loggedin', 'loggedoff']">
|
||||
<!-- If notifications enabled, show toggle. -->
|
||||
<ion-spinner [hidden]="!preferences!.enableall ||
|
||||
!(notification.processorsByName[currentProcessor!.name][state] &&
|
||||
notification.processorsByName[currentProcessor!.name][state].updating)">
|
||||
</ion-spinner>
|
||||
<ion-toggle *ngIf="preferences!.enableall && !notification.processorsByName[currentProcessor!.name].locked"
|
||||
[(ngModel)]="notification.processorsByName[currentProcessor!.name][state].checked"
|
||||
(ngModelChange)="changePreference(notification, state)"
|
||||
[disabled]="notification.processorsByName[currentProcessor!.name][state].updating">
|
||||
</ion-toggle>
|
||||
<span class="text-gray"
|
||||
*ngIf="preferences!.enableall && notification.processorsByName[currentProcessor!.name].locked">
|
||||
{{'core.settings.locked' | translate }}
|
||||
</span>
|
||||
<!-- If notifications are disabled, show "Disabled" instead of toggle. -->
|
||||
<span *ngIf="!preferences!.enableall">{{ 'core.settings.disabled' | translate }}</span>
|
||||
</ion-col>
|
||||
</ion-row>
|
||||
</ion-grid>
|
||||
<ng-container *ngIf="loggedInOffLegacyMode">
|
||||
<ng-container *ngTemplateOutlet="legacySettings; context: {preferences: preferences}"></ng-container>
|
||||
</ng-container>
|
||||
|
||||
<!-- Phone view -->
|
||||
<ion-list-header class="ion-text-wrap ion-no-margin ion-hide-md-up">
|
||||
{{ notification.displayname }}
|
||||
</ion-list-header>
|
||||
<!-- If notifications enabled, show toggles. If disabled, show "Disabled" instead of toggle. -->
|
||||
<ion-item *ngFor="let state of ['loggedin', 'loggedoff']" class="ion-text-wrap ion-hide-md-up" lines="none">
|
||||
<ion-label>{{ 'core.settings.' + state | translate }}</ion-label>
|
||||
<ion-spinner slot="end" *ngIf="preferences!.enableall && (notification.processorsByName[currentProcessor!.name][state] &&
|
||||
notification.processorsByName[currentProcessor!.name][state].updating)">
|
||||
</ion-spinner>
|
||||
<ion-toggle slot="end" *ngIf="preferences!.enableall && !notification.processorsByName[currentProcessor!.name].locked"
|
||||
[(ngModel)]="notification.processorsByName[currentProcessor!.name][state].checked"
|
||||
(ngModelChange)="changePreference(notification, state)"
|
||||
[disabled]="notification.processorsByName[currentProcessor!.name][state].updating">
|
||||
</ion-toggle>
|
||||
<span slot="end" *ngIf="preferences!.enableall && notification.processorsByName[currentProcessor!.name].locked"
|
||||
class="text-gray">
|
||||
{{'core.settings.locked' | translate }}
|
||||
</span>
|
||||
<ion-note slot="end" *ngIf="!preferences!.enableall">{{ 'core.settings.disabled' | translate }}</ion-note>
|
||||
</ion-item>
|
||||
</ng-container>
|
||||
</ion-card>
|
||||
<ng-container *ngIf="!loggedInOffLegacyMode">
|
||||
<ng-container *ngTemplateOutlet="settings; context: {preferences: preferences}"></ng-container>
|
||||
</ng-container>
|
||||
</core-loading>
|
||||
</ion-content>
|
||||
|
||||
|
||||
<!-- 3.11 or downwards version -->
|
||||
<ng-template #legacySettings let-preferences="preferences">
|
||||
<ion-card *ngFor="let component of components" class="ion-margin-top">
|
||||
<ion-card-header class="ion-no-padding">
|
||||
<ion-item class="ion-text-wrap divider">
|
||||
<ion-label class="ion-text-wrap">
|
||||
<ion-row class="ion-no-padding">
|
||||
<ion-col class="ion-no-padding">
|
||||
<p class="item-heading">{{ component.displayname }}</p>
|
||||
</ion-col>
|
||||
<ion-col size="2" class="ion-text-center ion-no-padding ion-hide-md-down">
|
||||
<p>{{ 'core.settings.loggedin' | translate }}</p>
|
||||
</ion-col>
|
||||
<ion-col size="2" class="ion-text-center ion-no-padding ion-hide-md-down">
|
||||
<p>{{ 'core.settings.loggedoff' | translate }}</p>
|
||||
</ion-col>
|
||||
</ion-row>
|
||||
</ion-label>
|
||||
</ion-item>
|
||||
</ion-card-header>
|
||||
<ng-container *ngFor="let notification of component.notifications">
|
||||
<!-- Tablet view -->
|
||||
<ion-item class="ion-text-wrap ion-hide-md-down addon-notifications-table-content only-links">
|
||||
<ion-label>
|
||||
<ion-row class="ion-no-padding ion-align-items-center">
|
||||
<ion-col class="ion-margin-horizontal ion-no-padding">
|
||||
<p class="item-heading">{{ notification.displayname }}</p>
|
||||
</ion-col>
|
||||
<ion-col size="2" class="ion-text-center ion-no-padding" *ngFor="let state of ['loggedin', 'loggedoff']">
|
||||
<ng-container *ngIf="preferences!.enableall && notification.processorsByName[currentProcessorName][state]">
|
||||
<!-- If notifications enabled, show toggle. -->
|
||||
<core-button-with-spinner *ngIf="!notification.processorsByName[currentProcessorName].locked"
|
||||
[loading]="notification.processorsByName[currentProcessorName][state].updating">
|
||||
<ion-toggle [(ngModel)]="notification.processorsByName[currentProcessorName][state].checked"
|
||||
(ngModelChange)="changePreferenceLegacy(notification, state)">
|
||||
</ion-toggle>
|
||||
</core-button-with-spinner>
|
||||
<span class="text-gray" *ngIf="notification.processorsByName[currentProcessorName].locked &&
|
||||
notification.processorsByName[currentProcessorName][state].checked">
|
||||
{{'core.settings.forced' | translate }}
|
||||
</span>
|
||||
<span class="text-gray" *ngIf="notification.processorsByName[currentProcessorName].locked &&
|
||||
!notification.processorsByName[currentProcessorName][state].checked">
|
||||
{{'core.settings.disallowed' | translate }}
|
||||
</span>
|
||||
</ng-container>
|
||||
<!-- If notifications are disabled, show "Disabled" instead of toggle. -->
|
||||
<span *ngIf="!preferences!.enableall" class="text-gray">{{ 'core.settings.disabled' | translate }}</span>
|
||||
</ion-col>
|
||||
</ion-row>
|
||||
</ion-label>
|
||||
</ion-item>
|
||||
|
||||
<!-- Phone view -->
|
||||
<ion-item class="ion-text-wrap ion-no-margin ion-hide-md-up" lines="none">
|
||||
<p class="item-heading">{{ notification.displayname }}</p>
|
||||
</ion-item>
|
||||
<!-- If notifications enabled, show toggles. If disabled, show "Disabled" instead of toggle. -->
|
||||
<ion-item *ngFor="let state of ['loggedin', 'loggedoff']" class="ion-text-wrap ion-hide-md-up" lines="none">
|
||||
<ion-label class="ion-margin-horizontal">
|
||||
<p>{{ 'core.settings.' + state | translate }}</p>
|
||||
</ion-label>
|
||||
<div slot="end" *ngIf="preferences!.enableall && notification.processorsByName[currentProcessorName][state]">
|
||||
<core-button-with-spinner *ngIf="!notification.processorsByName[currentProcessorName].locked"
|
||||
[loading]="notification.processorsByName[currentProcessorName][state].updating">
|
||||
<ion-toggle *ngIf="!notification.processorsByName[currentProcessorName].locked"
|
||||
[(ngModel)]="notification.processorsByName[currentProcessorName][state].checked"
|
||||
(ngModelChange)="changePreferenceLegacy(notification, state)">
|
||||
</ion-toggle>
|
||||
</core-button-with-spinner>
|
||||
<span class="text-gray" *ngIf="notification.processorsByName[currentProcessorName].locked &&
|
||||
notification.processorsByName[currentProcessorName][state].checked">
|
||||
{{'core.settings.forced' | translate }}
|
||||
</span>
|
||||
<span class="text-gray" *ngIf="notification.processorsByName[currentProcessorName].locked &&
|
||||
!notification.processorsByName[currentProcessorName][state].checked">
|
||||
{{'core.settings.disallowed' | translate }}
|
||||
</span>
|
||||
</div>
|
||||
<span class="text-gray" slot="end" *ngIf="!preferences!.enableall">{{ 'core.settings.disabled' | translate }}</span>
|
||||
</ion-item>
|
||||
</ng-container>
|
||||
</ion-card>
|
||||
</ng-template>
|
||||
|
||||
<!-- 4.0 or downwards version -->
|
||||
<ng-template #settings let-preferences="preferences">
|
||||
<ion-card *ngFor="let component of components" class="ion-margin-top">
|
||||
<ion-item-divider class="ion-text-wrap">
|
||||
<ion-label>
|
||||
<p class="item-heading">{{ component.displayname }}</p>
|
||||
</ion-label>
|
||||
</ion-item-divider>
|
||||
<ng-container *ngFor="let notification of component.notifications">
|
||||
<!-- If notifications enabled, show toggles. If disabled, show "Disabled" instead of toggle. -->
|
||||
<ion-item class="ion-text-wrap" lines="none">
|
||||
<ion-label>
|
||||
<p>{{ notification.displayname }}</p>
|
||||
</ion-label>
|
||||
|
||||
<div slot="end" *ngIf="preferences!.enableall">
|
||||
<core-button-with-spinner *ngIf="!notification.processorsByName[currentProcessorName].locked"
|
||||
[loading]="notification.processorsByName[currentProcessorName].updating">
|
||||
<ion-toggle *ngIf="!notification.processorsByName[currentProcessorName].locked"
|
||||
[(ngModel)]="notification.processorsByName[currentProcessorName].enabled"
|
||||
(ngModelChange)="changePreference(notification)">
|
||||
</ion-toggle>
|
||||
</core-button-with-spinner>
|
||||
<span class="text-gray" *ngIf=" notification.processorsByName[currentProcessorName].locked &&
|
||||
notification.processorsByName[currentProcessorName].enabled">
|
||||
{{'core.settings.forced' | translate }}
|
||||
</span>
|
||||
<span class="text-gray" *ngIf=" notification.processorsByName[currentProcessorName].locked &&
|
||||
!notification.processorsByName[currentProcessorName].enabled">
|
||||
{{'core.settings.disallowed' | translate }}
|
||||
</span>
|
||||
</div>
|
||||
<span class="text-gray" slot="end" *ngIf="!preferences!.enableall">{{ 'core.settings.disabled' | translate }}</span>
|
||||
</ion-item>
|
||||
</ng-container>
|
||||
</ion-card>
|
||||
|
||||
</ng-template>
|
||||
|
|
|
@ -1,5 +1,3 @@
|
|||
:host {
|
||||
.addon-notifications-table-content ion-row {
|
||||
min-height: 35px;
|
||||
}
|
||||
.addon-notifications-table-content ion-row {
|
||||
min-height: 35px;
|
||||
}
|
||||
|
|
|
@ -27,7 +27,6 @@ import { CoreError } from '@classes/errors/error';
|
|||
import { CoreEvents } from '@singletons/events';
|
||||
import {
|
||||
AddonNotifications,
|
||||
AddonNotificationsPreferencesProcessor,
|
||||
AddonNotificationsPreferencesNotificationProcessorState,
|
||||
} from '../../services/notifications';
|
||||
import {
|
||||
|
@ -51,16 +50,20 @@ export class AddonNotificationsSettingsPage implements OnInit, OnDestroy {
|
|||
|
||||
preferences?: AddonNotificationsPreferencesFormatted;
|
||||
components?: AddonNotificationsPreferencesComponentFormatted[];
|
||||
currentProcessor?: AddonNotificationsPreferencesProcessor;
|
||||
currentProcessorName = 'airnotifier';
|
||||
preferencesLoaded = false;
|
||||
notificationSound = false;
|
||||
canChangeSound: boolean;
|
||||
processorHandlers: AddonMessageOutputHandlerData[] = [];
|
||||
loggedInOffLegacyMode = false;
|
||||
|
||||
protected updateTimeout?: number;
|
||||
|
||||
constructor() {
|
||||
this.canChangeSound = CoreLocalNotifications.canDisableSound();
|
||||
|
||||
const currentSite = CoreSites.getRequiredCurrentSite();
|
||||
this.loggedInOffLegacyMode = !currentSite.isVersionGreaterEqualThan('4.0');
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -83,20 +86,20 @@ export class AddonNotificationsSettingsPage implements OnInit, OnDestroy {
|
|||
try {
|
||||
const preferences = await AddonNotifications.getNotificationPreferences();
|
||||
|
||||
if (!this.currentProcessor) {
|
||||
// Initialize current processor. Load "Mobile" (airnotifier) if available.
|
||||
this.currentProcessor = AddonNotificationsHelper.getProcessor(preferences.processors, 'airnotifier');
|
||||
// Initialize current processor. Load "Mobile" (airnotifier) if available.
|
||||
let currentProcessor = preferences.processors.find((processor) => processor.name == this.currentProcessorName);
|
||||
if (!currentProcessor) {
|
||||
currentProcessor = preferences.processors[0];
|
||||
}
|
||||
|
||||
if (!this.currentProcessor) {
|
||||
if (!currentProcessor) {
|
||||
// Shouldn't happen.
|
||||
throw new CoreError('No processor found');
|
||||
}
|
||||
|
||||
preferences.enableall = !preferences.disableall;
|
||||
this.preferences = AddonNotificationsHelper.formatPreferences(preferences);
|
||||
this.loadProcessor(this.currentProcessor);
|
||||
|
||||
this.loadProcessor(currentProcessor);
|
||||
} catch (error) {
|
||||
CoreDomUtils.showErrorModal(error);
|
||||
} finally {
|
||||
|
@ -114,7 +117,7 @@ export class AddonNotificationsSettingsPage implements OnInit, OnDestroy {
|
|||
return;
|
||||
}
|
||||
|
||||
this.currentProcessor = processor;
|
||||
this.currentProcessorName = processor.name;
|
||||
this.processorHandlers = [];
|
||||
this.components = AddonNotificationsHelper.getProcessorComponents(
|
||||
processor.name,
|
||||
|
@ -199,27 +202,21 @@ export class AddonNotificationsSettingsPage implements OnInit, OnDestroy {
|
|||
* @param state State name, ['loggedin', 'loggedoff'].
|
||||
* @return Promise resolved when done.
|
||||
*/
|
||||
async changePreference(notification: AddonNotificationsPreferencesNotificationFormatted, state: string): Promise<void> {
|
||||
const processor = notification.processorsByName?.[this.currentProcessor?.name || ''];
|
||||
async changePreferenceLegacy(notification: AddonNotificationsPreferencesNotificationFormatted, state: string): Promise<void> {
|
||||
const processor = notification.processorsByName?.[this.currentProcessorName];
|
||||
if (!processor) {
|
||||
return;
|
||||
}
|
||||
|
||||
const processorState: ProcessorStateFormatted = processor[state];
|
||||
const preferenceName = notification.preferencekey + '_' + processorState.name;
|
||||
let value: string | undefined;
|
||||
|
||||
notification.processors.forEach((processor) => {
|
||||
if (processor[state].checked) {
|
||||
if (!value) {
|
||||
value = processor.name;
|
||||
} else {
|
||||
value += ',' + processor.name;
|
||||
}
|
||||
}
|
||||
});
|
||||
let value = notification.processors
|
||||
.filter((processor) => processor[state].checked)
|
||||
.map((processor) => processor.name)
|
||||
.join(',');
|
||||
|
||||
if (!value) {
|
||||
if (value == '') {
|
||||
value = 'none';
|
||||
}
|
||||
|
||||
|
@ -239,6 +236,45 @@ export class AddonNotificationsSettingsPage implements OnInit, OnDestroy {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Change the value of a certain preference.
|
||||
*
|
||||
* @param notification Notification object.
|
||||
* @return Promise resolved when done.
|
||||
*/
|
||||
async changePreference(notification: AddonNotificationsPreferencesNotificationFormatted): Promise<void> {
|
||||
const processor = notification.processorsByName?.[this.currentProcessorName];
|
||||
if (!processor) {
|
||||
return;
|
||||
}
|
||||
|
||||
const preferenceName = notification.preferencekey + '_enabled';
|
||||
|
||||
let value = notification.processors
|
||||
.filter((processor) => processor.enabled)
|
||||
.map((processor) => processor.name)
|
||||
.join(',');
|
||||
|
||||
if (value == '') {
|
||||
value = 'none';
|
||||
}
|
||||
|
||||
processor.updating = true;
|
||||
|
||||
try {
|
||||
await CoreUser.updateUserPreference(preferenceName, value);
|
||||
|
||||
// Update the preferences since they were modified.
|
||||
this.updatePreferencesAfterDelay();
|
||||
} catch (error) {
|
||||
// Show error and revert change.
|
||||
CoreDomUtils.showErrorModal(error);
|
||||
processor.enabled = !processor.enabled;
|
||||
} finally {
|
||||
processor.updating = false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Enable all notifications changed.
|
||||
*
|
||||
|
@ -294,6 +330,8 @@ export class AddonNotificationsSettingsPage implements OnInit, OnDestroy {
|
|||
|
||||
/**
|
||||
* State in notification processor in notification preferences component with some calculated data.
|
||||
*
|
||||
* @deprecated 4.0
|
||||
*/
|
||||
type ProcessorStateFormatted = AddonNotificationsPreferencesNotificationProcessorState & {
|
||||
updating?: boolean; // Calculated in the app. Whether the state is being updated.
|
||||
|
|
|
@ -77,34 +77,6 @@ export class AddonNotificationsHelperProvider {
|
|||
return formattedPreferences;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a certain processor from a list of processors.
|
||||
*
|
||||
* @param processors List of processors.
|
||||
* @param name Name of the processor to get.
|
||||
* @param fallback True to return first processor if not found, false to not return any. Defaults to true.
|
||||
* @return Processor.
|
||||
*/
|
||||
getProcessor(
|
||||
processors: AddonNotificationsPreferencesProcessor[],
|
||||
name: string,
|
||||
fallback: boolean = true,
|
||||
): AddonNotificationsPreferencesProcessor | undefined {
|
||||
if (!processors || !processors.length) {
|
||||
return;
|
||||
}
|
||||
|
||||
const processor = processors.find((processor) => processor.name == name);
|
||||
if (processor) {
|
||||
return processor;
|
||||
}
|
||||
|
||||
// Processor not found, return first if requested.
|
||||
if (fallback) {
|
||||
return processors[0];
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the components and notifications that have a certain processor.
|
||||
*
|
||||
|
@ -166,7 +138,11 @@ export type AddonNotificationsPreferencesComponentFormatted = Omit<AddonNotifica
|
|||
* Preferences notification with some calculated data.
|
||||
*/
|
||||
export type AddonNotificationsPreferencesNotificationFormatted = AddonNotificationsPreferencesNotification & {
|
||||
processorsByName?: Record<string, AddonNotificationsPreferencesNotificationProcessor>; // Calculated in the app.
|
||||
processorsByName?: Record<string, AddonNotificationsPreferencesNotificationProcessorFormatted>; // Calculated in the app.
|
||||
};
|
||||
|
||||
type AddonNotificationsPreferencesNotificationProcessorFormatted = AddonNotificationsPreferencesNotificationProcessor & {
|
||||
updating?: boolean; // Calculated in the app. Whether the state is being updated.
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
|
@ -451,6 +451,8 @@ export type AddonNotificationsPreferencesNotificationProcessorState = {
|
|||
checked: boolean; // Is checked?.
|
||||
};
|
||||
|
||||
export type AddonNotificationsPreferencesNotificationProcessorStateSetting = 'loggedoff' | 'loggedin' | 'enabled';
|
||||
|
||||
/**
|
||||
* Params of core_message_get_messages WS.
|
||||
*/
|
||||
|
|
Loading…
Reference in New Issue