MOBILE-2308 calendar: Settings page

main
Pau Ferrer Ocaña 2017-12-28 12:55:54 +01:00
parent a9a63e5668
commit 6f671fe39f
12 changed files with 168 additions and 14 deletions

View File

@ -1,4 +1,7 @@
{
"calendar": "Calendar",
"calendarevents": "Calendar events"
"calendarevents": "Calendar events",
"defaultnotificationtime": "Default notification time",
"errorloadevents": "Error loading events.",
"noevents": "There are no events"
}

View File

@ -67,12 +67,12 @@ export class AddonCalendarListPage implements OnDestroy {
private eventsProvider: CoreEventsProvider, private navCtrl: NavController) {
this.siteHomeId = sitesProvider.getCurrentSite().getSiteHomeId();
this.notificationsEnabled = localNotificationsProvider.isAvailable();
this.notificationsEnabled = true;//localNotificationsProvider.isAvailable();
if (this.notificationsEnabled) {
// Re-schedule events if default time changes.
this.obsDefaultTimeChange = eventsProvider.on(AddonCalendarProvider.DEFAULT_NOTIFICATION_TIME_CHANGED, () => {
calendarProvider.scheduleEventsNotifications(this.events);
});
}, sitesProvider.getCurrentSiteId());
}
// @TODO: Split view once single event is done.
@ -297,7 +297,6 @@ export class AddonCalendarListPage implements OnDestroy {
* Open calendar events settings.
*/
openSettings() {
// @TODO: Check the settings page name.
this.navCtrl.push('AddonCalendarSettingsPage');
};

View File

@ -0,0 +1,22 @@
<ion-header>
<ion-navbar>
<ion-title>{{ 'core.settings.settings' | translate }}</ion-title>
</ion-navbar>
</ion-header>
<ion-content>
<ion-list>
<ion-item>
<ion-label>{{ 'addon.calendar.defaultnotificationtime' | translate }}</ion-label>
<ion-select [(ngModel)]="defaultTime" (ionChange)="updateDefaultTime($event)">
<ion-option value="0">{{ 'core.settings.disabled' | translate }}</ion-option>
<ion-option value="10">{{ 600 | coreDuration }}</ion-option>
<ion-option value="30">{{ 1800 | coreDuration }}</ion-option>
<ion-option value="60">{{ 3600 | coreDuration }}</ion-option>
<ion-option value="120">{{ 7200 | coreDuration }}</ion-option>
<ion-option value="360">{{ 21600 | coreDuration }}</ion-option>
<ion-option value="720">{{ 43200 | coreDuration }}</ion-option>
<ion-option value="1440">{{ 86400 | coreDuration }}</ion-option>
</ion-select>
</ion-item>
</ion-list>
</ion-content>

View File

@ -0,0 +1,31 @@
// (C) Copyright 2015 Martin Dougiamas
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
import { NgModule } from '@angular/core';
import { IonicPageModule } from 'ionic-angular';
import { TranslateModule } from '@ngx-translate/core';
import { AddonCalendarSettingsPage } from './settings';
import { CorePipesModule } from '../../../../pipes/pipes.module';
@NgModule({
declarations: [
AddonCalendarSettingsPage,
],
imports: [
CorePipesModule,
IonicPageModule.forChild(AddonCalendarSettingsPage),
TranslateModule.forChild()
],
})
export class AddonCalendarSettingsPageModule {}

View File

@ -0,0 +1,3 @@
page-addon-calendar-settings {
}

View File

@ -0,0 +1,50 @@
// (C) Copyright 2015 Martin Dougiamas
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
import { Component } from '@angular/core';
import { IonicPage } from 'ionic-angular';
import { AddonCalendarProvider } from '../../providers/calendar';
import { CoreEventsProvider } from '../../../../providers/events';
import { CoreSitesProvider } from '../../../../providers/sites';
/**
* Page that displays the list of calendar events.
*/
@IonicPage()
@Component({
selector: 'page-addon-calendar-settings',
templateUrl: 'settings.html',
})
export class AddonCalendarSettingsPage {
defaultTime = 0;
constructor(private calendarProvider: AddonCalendarProvider, private eventsProvider: CoreEventsProvider,
private sitesProvider: CoreSitesProvider) {}
/**
* View loaded.
*/
ionViewDidLoad() {
this.calendarProvider.getDefaultNotificationTime().then((time) => {
this.defaultTime = time;
});
}
updateDefaultTime(newTime) {
this.calendarProvider.setDefaultNotificationTime(newTime);
this.eventsProvider.trigger(AddonCalendarProvider.DEFAULT_NOTIFICATION_TIME_CHANGED, {time: newTime},
this.sitesProvider.getCurrentSiteId());
};
}

View File

@ -350,6 +350,20 @@ export class AddonCalendarProvider {
return Promise.all(promises);
}
/**
* Set the default notification time.
*
* @param {number} time New default time.
* @param {string} [siteId] ID of the site. If not defined, use current site.
* @return {Promise<any[]>} Promise resolved when stored.
*/
setDefaultNotificationTime(time: number, siteId?: string) : Promise<any[]> {
siteId = siteId || this.sitesProvider.getCurrentSiteId();
let key = AddonCalendarProvider.DEFAULT_NOTIFICATION_TIME_SETTING + '#' + siteId;
return this.configProvider.set(key, time);
}
/**
* Store events in local DB.
*

View File

@ -24,6 +24,9 @@
}
}
.bar-buttons core-context-menu .button-clear-ios {
color: $toolbar-ios-button-color;
}
// Highlights inside the input element.
@if ($core-text-input-ios-show-highlight) {

View File

@ -12,8 +12,12 @@
height: calc(100% - #{($card-md-margin-end + $card-md-margin-start)});
}
.bar-buttons core-context-menu .button-clear-md {
color: $toolbar-md-button-color;
}
// Highlights inside the input element.
@if ($core-text-input-md-show-highlight) {
@if ($mm-text-input-md-show-highlight) {
.card-md, .list-md {
// In order to get a 2px border we need to add an inset
// box-shadow 1px (this is to avoid the div resizing)

View File

@ -153,16 +153,16 @@ core-format-text[maxHeight], *[core-format-text][maxHeight] {
display: none;
}
&:not(.core-shortened) {
&:not(.mm-shortened) {
max-height: none !important;
}
&.core-shortened {
&.mm-shortened {
color: $gray-darker;
overflow: hidden;
min-height: 50px;
.core-show-more {
.mm-show-more {
color: color($colors, dark);
text-align: right;
font-size: 14px;

View File

@ -11,3 +11,7 @@
.col[align-self-stretch] .card-wp {
height: calc(100% - #{($card-wp-margin-end + $card-wp-margin-start)});
}
.bar-buttons core-context-menu .button-clear-wp {
color: $toolbar-wp-button-color;
}

View File

@ -64,9 +64,10 @@ export class CoreEventsProvider {
*
* @param {string} eventName Name of the event to listen to.
* @param {Function} callBack Function to call when the event is triggered.
* @param {string} [siteId] Site where to trigger the event. Undefined won't check the site.
* @return {CoreEventObserver} Observer to stop listening.
*/
on(eventName: string, callBack: (value: any) => void) : CoreEventObserver {
on(eventName: string, callBack: (value: any) => void, siteId?: string) : CoreEventObserver {
// If it's a unique event and has been triggered already, call the callBack.
// We don't need to create an observer because the event won't be triggered again.
if (this.uniqueEvents[eventName]) {
@ -84,7 +85,11 @@ export class CoreEventsProvider {
this.observables[eventName] = new Subject<any>();
}
let subscription = this.observables[eventName].subscribe(callBack);
let subscription = this.observables[eventName].subscribe((value: any) => {
if (!siteId || value.siteId == siteId) {
callBack(value);
}
});
// Create and return a CoreEventObserver.
return {
@ -100,10 +105,17 @@ export class CoreEventsProvider {
*
* @param {string} event Name of the event to trigger.
* @param {any} [data] Data to pass to the observers.
* @param {string} [siteId] Site where to trigger the event. Undefined means no Site.
*/
trigger(eventName: string, data?: any) : void {
trigger(eventName: string, data?: any, siteId?: string) : void {
this.logger.debug(`Event '${eventName}' triggered.`);
if (this.observables[eventName]) {
if (siteId) {
if (!data) {
data = {};
}
data.siteId = siteId;
}
this.observables[eventName].next(data);
}
}
@ -113,12 +125,21 @@ export class CoreEventsProvider {
*
* @param {string} event Name of the event to trigger.
* @param {any} data Data to pass to the observers.
* @param {string} [siteId] Site where to trigger the event. Undefined means no Site.
*/
triggerUnique(eventName: string, data: any) : void {
triggerUnique(eventName: string, data: any, siteId?: string) : void {
if (this.uniqueEvents[eventName]) {
this.logger.debug(`Unique event '${eventName}' ignored because it was already triggered.`);
} else {
this.logger.debug(`Unique event '${eventName}' triggered.`);
if (siteId) {
if (!data) {
data = {};
}
data.siteId = siteId;
}
// Store the data so it can be passed to observers that register from now on.
this.uniqueEvents[eventName] = {
data: data