commit
409d1bac3e
|
@ -35,6 +35,7 @@
|
|||
<preference name="SplashScreen" value="screen" />
|
||||
<preference name="SplashScreenDelay" value="15000" />
|
||||
<preference name="SplashMaintainAspectRatio" value="true" />
|
||||
<preference name="LoadUrlTimeoutValue" value="60000" />
|
||||
<feature name="StatusBar">
|
||||
<param name="ios-package" onload="true" value="CDVStatusBar" />
|
||||
</feature>
|
||||
|
@ -90,8 +91,6 @@
|
|||
<splash height="960" src="resources/ios/splash/Default@2x~iphone.png" width="640" />
|
||||
<splash height="480" src="resources/ios/splash/Default~iphone.png" width="320" />
|
||||
</platform>
|
||||
<engine name="android" spec="6.1.2" />
|
||||
<engine name="ios" spec="4.3.1" />
|
||||
<plugin name="cordova-plugin-file" spec="4.3.3" />
|
||||
<plugin name="cordova-plugin-file-transfer" spec="1.6.3" />
|
||||
<plugin name="cordova-plugin-camera" spec="2.4.1">
|
||||
|
@ -124,4 +123,7 @@
|
|||
<plugin name="cordova-plugin-file-opener2" spec="~2.0.19" />
|
||||
<plugin name="com-darryncampbell-cordova-plugin-intent" spec="~1.0.2" />
|
||||
<plugin name="cordova-sqlite-evcore-extbuild-free" spec="~0.9.7" />
|
||||
<plugin name="cordova-plugin-badge" spec="0.8.7" />
|
||||
<engine name="android" spec="6.1.2" />
|
||||
<engine name="ios" spec="4.3.1" />
|
||||
</widget>
|
||||
|
|
10
package.json
10
package.json
|
@ -82,7 +82,9 @@
|
|||
"rxjs": "5.5.11",
|
||||
"sw-toolbox": "3.6.0",
|
||||
"ts-md5": "^1.2.2",
|
||||
"zone.js": "0.8.26"
|
||||
"zone.js": "0.8.26",
|
||||
"cordova-android": "6.1.2",
|
||||
"cordova-ios": "4.3.1"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@ionic/app-scripts": "3.1.9",
|
||||
|
@ -97,5 +99,11 @@
|
|||
},
|
||||
"browser": {
|
||||
"electron": false
|
||||
},
|
||||
"cordova": {
|
||||
"platforms": [
|
||||
"android",
|
||||
"ios"
|
||||
]
|
||||
}
|
||||
}
|
|
@ -58,7 +58,7 @@ export class AddonCalendarModule {
|
|||
return;
|
||||
}
|
||||
|
||||
loginHelper.redirect('AddonCalendarListPage', {eventid: data.eventid}, data.siteId);
|
||||
loginHelper.redirect('AddonCalendarListPage', {eventId: data.eventid}, data.siteId);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
|
|
@ -78,7 +78,7 @@ export class AddonCalendarListPage implements OnDestroy {
|
|||
}, sitesProvider.getCurrentSiteId());
|
||||
}
|
||||
|
||||
this.eventId = navParams.get('eventid') || false;
|
||||
this.eventId = navParams.get('eventId') || false;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -52,7 +52,6 @@ export interface AddonModAssignSyncResult {
|
|||
export class AddonModAssignSyncProvider extends CoreSyncBaseProvider {
|
||||
|
||||
static AUTO_SYNCED = 'addon_mod_assign_autom_synced';
|
||||
static SYNC_TIME = 300000;
|
||||
|
||||
protected componentTranslate: string;
|
||||
|
||||
|
|
|
@ -42,6 +42,6 @@ export class AddonModAssignSyncCronHandler implements CoreCronHandler {
|
|||
* @return {number} Time between consecutive executions (in ms).
|
||||
*/
|
||||
getInterval(): number {
|
||||
return 600000; // 10 minutes.
|
||||
return this.assignSync.syncInterval;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -42,6 +42,6 @@ export class AddonModChoiceSyncCronHandler implements CoreCronHandler {
|
|||
* @return {number} Time between consecutive executions (in ms).
|
||||
*/
|
||||
getInterval(): number {
|
||||
return 600000; // 10 minutes.
|
||||
return this.choiceSync.syncInterval;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -77,7 +77,7 @@ export class AddonModChoiceSyncProvider extends CoreSyncBaseProvider {
|
|||
|
||||
// Sync all responses.
|
||||
responses.forEach((response) => {
|
||||
promises.push(this.syncChoice(response.choiceid, response.userid, siteId).then((result) => {
|
||||
promises.push(this.syncChoiceIfNeeded(response.choiceid, response.userid, siteId).then((result) => {
|
||||
if (result && result.updated) {
|
||||
// Sync successful, send event.
|
||||
this.eventsProvider.trigger(AddonModChoiceSyncProvider.AUTO_SYNCED, {
|
||||
|
@ -91,6 +91,24 @@ export class AddonModChoiceSyncProvider extends CoreSyncBaseProvider {
|
|||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Sync an choice only if a certain time has passed since the last time.
|
||||
*
|
||||
* @param {number} choiceId Choice ID to be synced.
|
||||
* @param {number} userId User the answers belong to.
|
||||
* @param {string} [siteId] Site ID. If not defined, current site.
|
||||
* @return {Promise<any>} Promise resolved when the choice is synced or it doesn't need to be synced.
|
||||
*/
|
||||
syncChoiceIfNeeded(choiceId: number, userId: number, siteId?: string): Promise<any> {
|
||||
const syncId = this.getSyncId(choiceId, userId);
|
||||
|
||||
return this.isSyncNeeded(syncId, siteId).then((needed) => {
|
||||
if (needed) {
|
||||
return this.syncChoice(choiceId, userId, siteId);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Synchronize a choice.
|
||||
*
|
||||
|
|
|
@ -42,6 +42,6 @@ export class AddonModDataSyncCronHandler implements CoreCronHandler {
|
|||
* @return {number} Time between consecutive executions (in ms).
|
||||
*/
|
||||
getInterval(): number {
|
||||
return 600000; // 10 minutes.
|
||||
return this.dataSync.syncInterval;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -42,6 +42,6 @@ export class AddonModFeedbackSyncCronHandler implements CoreCronHandler {
|
|||
* @return {number} Time between consecutive executions (in ms).
|
||||
*/
|
||||
getInterval(): number {
|
||||
return 600000; // 10 minutes.
|
||||
return this.feedbackSync.syncInterval;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -42,6 +42,6 @@ export class AddonModForumSyncCronHandler implements CoreCronHandler {
|
|||
* @return {number} Time between consecutive executions (in ms).
|
||||
*/
|
||||
getInterval(): number {
|
||||
return AddonModForumSyncProvider.SYNC_TIME;
|
||||
return this.forumSync.syncInterval;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -36,7 +36,6 @@ export class AddonModForumSyncProvider extends CoreSyncBaseProvider {
|
|||
|
||||
static AUTO_SYNCED = 'addon_mod_forum_autom_synced';
|
||||
static MANUAL_SYNCED = 'addon_mod_forum_manual_synced';
|
||||
static SYNC_TIME = 600000;
|
||||
|
||||
protected componentTranslate: string;
|
||||
|
||||
|
|
|
@ -42,6 +42,6 @@ export class AddonModGlossarySyncCronHandler implements CoreCronHandler {
|
|||
* @return {number} Time between consecutive executions (in ms).
|
||||
*/
|
||||
getInterval(): number {
|
||||
return AddonModGlossarySyncProvider.SYNC_TIME;
|
||||
return this.glossarySync.syncInterval;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -35,7 +35,6 @@ import { AddonModGlossaryOfflineProvider } from './offline';
|
|||
export class AddonModGlossarySyncProvider extends CoreSyncBaseProvider {
|
||||
|
||||
static AUTO_SYNCED = 'addon_mod_glossary_autom_synced';
|
||||
static SYNC_TIME = 600000; // 10 minutes.
|
||||
|
||||
protected componentTranslate: string;
|
||||
|
||||
|
|
|
@ -53,7 +53,6 @@ export interface AddonModLessonSyncResult {
|
|||
export class AddonModLessonSyncProvider extends CoreSyncBaseProvider {
|
||||
|
||||
static AUTO_SYNCED = 'addon_mod_lesson_autom_synced';
|
||||
static SYNC_TIME = 300000;
|
||||
|
||||
protected componentTranslate: string;
|
||||
|
||||
|
|
|
@ -42,6 +42,6 @@ export class AddonModLessonSyncCronHandler implements CoreCronHandler {
|
|||
* @return {number} Time between consecutive executions (in ms).
|
||||
*/
|
||||
getInterval(): number {
|
||||
return 600000;
|
||||
return this.lessonSync.syncInterval;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -26,7 +26,7 @@ export class AddonModQuizAccessOfflineAttemptsHandler implements AddonModQuizAcc
|
|||
name = 'AddonModQuizAccessOfflineAttempts';
|
||||
ruleName = 'quizaccess_offlineattempts';
|
||||
|
||||
constructor() {
|
||||
constructor(protected quizSync: AddonModQuizSyncProvider) {
|
||||
// Nothing to do.
|
||||
}
|
||||
|
||||
|
@ -86,6 +86,6 @@ export class AddonModQuizAccessOfflineAttemptsHandler implements AddonModQuizAcc
|
|||
}
|
||||
|
||||
// Show warning if last sync was a while ago.
|
||||
return Date.now() - AddonModQuizSyncProvider.SYNC_TIME > quiz.syncTime;
|
||||
return Date.now() - this.quizSync.syncInterval > quiz.syncTime;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -52,7 +52,6 @@ export interface AddonModQuizSyncResult {
|
|||
export class AddonModQuizSyncProvider extends CoreSyncBaseProvider {
|
||||
|
||||
static AUTO_SYNCED = 'addon_mod_quiz_autom_synced';
|
||||
static SYNC_TIME = 300000;
|
||||
|
||||
protected componentTranslate: string;
|
||||
|
||||
|
|
|
@ -42,6 +42,6 @@ export class AddonModQuizSyncCronHandler implements CoreCronHandler {
|
|||
* @return {number} Time between consecutive executions (in ms).
|
||||
*/
|
||||
getInterval(): number {
|
||||
return AddonModQuizSyncProvider.SYNC_TIME;
|
||||
return this.quizSync.syncInterval;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -57,7 +57,6 @@ export interface AddonModScormSyncResult {
|
|||
export class AddonModScormSyncProvider extends CoreSyncBaseProvider {
|
||||
|
||||
static AUTO_SYNCED = 'addon_mod_scorm_autom_synced';
|
||||
static SYNC_TIME = 600000;
|
||||
|
||||
protected componentTranslate: string;
|
||||
|
||||
|
|
|
@ -42,6 +42,6 @@ export class AddonModScormSyncCronHandler implements CoreCronHandler {
|
|||
* @return {number} Time between consecutive executions (in ms).
|
||||
*/
|
||||
getInterval(): number {
|
||||
return AddonModScormSyncProvider.SYNC_TIME;
|
||||
return this.scormSync.syncInterval;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -42,6 +42,6 @@ export class AddonModSurveySyncCronHandler implements CoreCronHandler {
|
|||
* @return {number} Time between consecutive executions (in ms).
|
||||
*/
|
||||
getInterval(): number {
|
||||
return 600000; // 10 minutes.
|
||||
return this.surveySync.syncInterval;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -42,6 +42,6 @@ export class AddonModWikiSyncCronHandler implements CoreCronHandler {
|
|||
* @return {number} Time between consecutive executions (in ms).
|
||||
*/
|
||||
getInterval(): number {
|
||||
return 600000; // 10 minutes.
|
||||
return this.wikiSync.syncInterval;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -96,7 +96,6 @@ export class AddonModWikiSyncProvider extends CoreSyncBaseProvider {
|
|||
|
||||
static AUTO_SYNCED = 'addon_mod_wiki_autom_synced';
|
||||
static MANUAL_SYNCED = 'addon_mod_wiki_manual_synced';
|
||||
static SYNC_TIME = 300000;
|
||||
|
||||
protected componentTranslate: string;
|
||||
|
||||
|
|
|
@ -42,6 +42,6 @@ export class AddonModWorkshopSyncCronHandler implements CoreCronHandler {
|
|||
* @return {number} Time between consecutive executions (in ms).
|
||||
*/
|
||||
getInterval(): number {
|
||||
return AddonModWorkshopSyncProvider.SYNC_TIME;
|
||||
return this.workshopSync.syncInterval;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -35,7 +35,6 @@ export class AddonModWorkshopSyncProvider extends CoreSyncBaseProvider {
|
|||
|
||||
static AUTO_SYNCED = 'addon_mod_workshop_autom_synced';
|
||||
static MANUAL_SYNCED = 'addon_mod_workshop_manual_synced';
|
||||
static SYNC_TIME = 300000;
|
||||
|
||||
protected componentTranslate: string;
|
||||
|
||||
|
|
|
@ -42,6 +42,6 @@ export class AddonNotesSyncCronHandler implements CoreCronHandler {
|
|||
* @return {number} Time between consecutive executions (in ms).
|
||||
*/
|
||||
getInterval(): number {
|
||||
return 600000; // 10 minutes.
|
||||
return 300000; // 5 minutes.
|
||||
}
|
||||
}
|
||||
|
|
|
@ -18,7 +18,7 @@
|
|||
|
||||
<!-- Input to enter the answer. -->
|
||||
<ion-col>
|
||||
<ion-input padding-left type="text" placeholder="{{ 'core.question.answer' | translate }}" [attr.name]="question.input.name" [value]="question.input.value" [disabled]="question.input.readOnly" [ngClass]='{"core-question-answer-correct": question.input.isCorrect === 1, "core-question-answer-incorrect": question.input.isCorrect === 0}' autocorrect="off">
|
||||
<ion-input padding-left type="text" placeholder="{{ 'core.question.answer' | translate }}" [attr.name]="question.input.name" [value]="question.input.value" [disabled]="question.input.readOnly" [ngClass]="[question.input.correctClass]" autocorrect="off">
|
||||
</ion-input>
|
||||
</ion-col>
|
||||
|
||||
|
@ -40,7 +40,7 @@
|
|||
<ng-template #selectUnits>
|
||||
<ion-col>
|
||||
<label *ngIf="question.select.accessibilityLabel" class="accesshide" for="{{question.select.id}}">{{ question.select.accessibilityLabel }}</label>
|
||||
<ion-select id="{{question.select.id}}" [name]="question.select.name" [(ngModel)]="question.select.selected" interface="popover">
|
||||
<ion-select id="{{question.select.id}}" [name]="question.select.name" [(ngModel)]="question.select.selected" interface="popover" [disabled]="question.select.disabled">
|
||||
<ion-option *ngFor="let option of question.select.options" [value]="option.value">{{option.label}}</ion-option>
|
||||
</ion-select>
|
||||
|
||||
|
@ -56,7 +56,7 @@
|
|||
<ion-label>
|
||||
<p>{{option.text}}</p>
|
||||
</ion-label>
|
||||
<ion-radio [value]="option.value" [disabled]="option.disabled"></ion-radio>
|
||||
<ion-radio [value]="option.value" [disabled]="option.disabled || question.input.readOnly"></ion-radio>
|
||||
</ion-item>
|
||||
|
||||
<!-- ion-radio doesn't use an input. Create a hidden input to hold the selected value. -->
|
||||
|
|
|
@ -2,6 +2,6 @@
|
|||
<ion-item text-wrap>
|
||||
<p><core-format-text [component]="component" [componentId]="componentId" [text]="question.text"></core-format-text></p>
|
||||
</ion-item>
|
||||
<ion-input padding-left type="text" placeholder="{{ 'core.question.answer' | translate }}" [attr.name]="question.input.name" [value]="question.input.value" autocorrect="off" [disabled]="question.input.readOnly" [ngClass]='{"core-question-answer-correct": question.input.isCorrect === 1, "core-question-answer-incorrect": question.input.isCorrect === 0}'>
|
||||
<ion-input padding-left type="text" placeholder="{{ 'core.question.answer' | translate }}" [attr.name]="question.input.name" [value]="question.input.value" autocorrect="off" [disabled]="question.input.readOnly" [ngClass]="[question.input.correctClass]">
|
||||
</ion-input>
|
||||
</section>
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
<ion-item text-wrap>
|
||||
{{ 'core.maxsizeandattachments' | translate:{$a: {size: maxSizeReadable, attachments: maxSubmissionsReadable} } }}
|
||||
</ion-item>
|
||||
<ion-item text-wrap *ngIf="filetypes && filetypes.mimetypes && filetypes.mimetypes.length">
|
||||
<ion-item text-wrap *ngIf="fileTypes && fileTypes.mimetypes && fileTypes.mimetypes.length">
|
||||
<p>{{ 'core.fileuploader.filesofthesetypes' | translate }}</p>
|
||||
<ul class="list-with-style">
|
||||
<li *ngFor="let typeInfo of filetypes.info">
|
||||
<li *ngFor="let typeInfo of fileTypes.info">
|
||||
<strong *ngIf="typeInfo.name">{{typeInfo.name}} </strong>{{typeInfo.extlist}}
|
||||
</li>
|
||||
</ul>
|
||||
|
|
|
@ -47,7 +47,19 @@ export class CoreTabComponent implements OnInit, OnDestroy {
|
|||
@Input() badge?: string; // A badge to add in the tab.
|
||||
@Input() badgeStyle?: string; // The badge color.
|
||||
@Input() enabled = true; // Whether the tab is enabled.
|
||||
@Input() show = true; // Whether the tab should be shown.
|
||||
@Input() set show(val: boolean) { // Whether the tab should be shown. Use a setter to detect changes on the value.
|
||||
if (typeof val != 'undefined') {
|
||||
const hasChanged = this._show != val;
|
||||
this._show = val;
|
||||
|
||||
if (this.initialized && hasChanged) {
|
||||
this.tabs.tabVisibilityChanged();
|
||||
}
|
||||
}
|
||||
}
|
||||
get show(): boolean { // Getter to be able to access "_show" just using .show.
|
||||
return this._show;
|
||||
}
|
||||
@Input() id?: string; // An ID to identify the tab.
|
||||
@Output() ionSelect: EventEmitter<CoreTabComponent> = new EventEmitter<CoreTabComponent>();
|
||||
|
||||
|
@ -56,6 +68,8 @@ export class CoreTabComponent implements OnInit, OnDestroy {
|
|||
|
||||
element: HTMLElement; // The core-tab element.
|
||||
loaded = false;
|
||||
initialized = false;
|
||||
_show = true;
|
||||
|
||||
constructor(protected tabs: CoreTabsComponent, element: ElementRef, protected domUtils: CoreDomUtilsProvider) {
|
||||
this.element = element.nativeElement;
|
||||
|
@ -66,6 +80,7 @@ export class CoreTabComponent implements OnInit, OnDestroy {
|
|||
*/
|
||||
ngOnInit(): void {
|
||||
this.tabs.addTab(this);
|
||||
this.initialized = true;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -237,10 +237,13 @@ export class CoreTabsComponent implements OnInit, AfterViewInit, OnChanges {
|
|||
}, 0);
|
||||
|
||||
this.slidesShown = Math.min(this.maxSlides, this.numTabsShown);
|
||||
this.slides.update();
|
||||
this.slides.resize();
|
||||
|
||||
this.slideChanged();
|
||||
|
||||
setTimeout(() => {
|
||||
this.slides.update();
|
||||
this.slides.resize();
|
||||
});
|
||||
}
|
||||
|
||||
protected calculateMaxSlides(): void {
|
||||
|
@ -357,4 +360,11 @@ export class CoreTabsComponent implements OnInit, AfterViewInit, OnChanges {
|
|||
this.tabs = newTabs;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Function to call when the visibility of a tab has changed.
|
||||
*/
|
||||
tabVisibilityChanged(): void {
|
||||
this.updateSlides();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -160,11 +160,13 @@ export class CoreLoginHelperProvider {
|
|||
return false;
|
||||
}
|
||||
|
||||
const modal = this.domUtils.showModalLoading('core.login.authenticating', true);
|
||||
let siteData: CoreLoginSSOData;
|
||||
let siteData: CoreLoginSSOData,
|
||||
modal;
|
||||
|
||||
// Wait for app to be ready.
|
||||
this.initDelegate.ready().then(() => {
|
||||
modal = this.domUtils.showModalLoading('core.login.authenticating', true);
|
||||
|
||||
return this.validateBrowserSSOLogin(url);
|
||||
}).then((data) => {
|
||||
siteData = data;
|
||||
|
|
|
@ -89,8 +89,10 @@ export class CoreMainMenuPage implements OnDestroy {
|
|||
this.initialTab = 0;
|
||||
|
||||
for (let i = 0; i < this.tabs.length; i++) {
|
||||
if (this.tabs[i].page == this.redirectPage) {
|
||||
const tab = this.tabs[i];
|
||||
if (tab.page == this.redirectPage) {
|
||||
this.initialTab = i + 1;
|
||||
tab.pageParams = Object.assign(tab.pageParams || {}, this.redirectParams);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -291,10 +291,12 @@ export class CoreQuestionBaseComponent {
|
|||
};
|
||||
|
||||
// Check if question is marked as correct.
|
||||
if (input.className.indexOf('incorrect') >= 0) {
|
||||
this.question.input.isCorrect = 0;
|
||||
} else if (input.className.indexOf('correct') >= 0) {
|
||||
this.question.input.isCorrect = 1;
|
||||
if (input.classList.contains('incorrect')) {
|
||||
this.question.input.correctClass = 'core-question-incorrect';
|
||||
} else if (input.classList.contains('correct')) {
|
||||
this.question.input.correctClass = 'core-question-correct';
|
||||
} else if (input.classList.contains('partiallycorrect')) {
|
||||
this.question.input.correctClass = 'core-question-partiallycorrect';
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -609,7 +609,17 @@ export class CoreFileProvider {
|
|||
|
||||
return this.file.moveFile(commonPath, originalPath, commonPath, newPath);
|
||||
} else {
|
||||
return this.file.moveFile(this.basePath, originalPath, this.basePath, newPath);
|
||||
return this.file.moveFile(this.basePath, originalPath, this.basePath, newPath).catch((error) => {
|
||||
// The move can fail if the path has encoded characters. Try again if that's the case.
|
||||
const decodedOriginal = decodeURI(originalPath),
|
||||
decodedNew = decodeURI(newPath);
|
||||
|
||||
if (decodedOriginal != originalPath || decodedNew != newPath) {
|
||||
return this.file.moveFile(this.basePath, decodedOriginal, this.basePath, decodedNew);
|
||||
} else {
|
||||
return Promise.reject(error);
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
@ -645,7 +655,17 @@ export class CoreFileProvider {
|
|||
|
||||
return this.file.copyFile(fromDir, fromFileAndDir.name, toDir, toFileAndDir.name);
|
||||
} else {
|
||||
return this.file.copyFile(this.basePath, from, this.basePath, to);
|
||||
return this.file.copyFile(this.basePath, from, this.basePath, to).catch((error) => {
|
||||
// The copy can fail if the path has encoded characters. Try again if that's the case.
|
||||
const decodedFrom = decodeURI(from),
|
||||
decodedTo = decodeURI(to);
|
||||
|
||||
if (from != decodedFrom || to != decodedTo) {
|
||||
return this.file.copyFile(this.basePath, decodedFrom, this.basePath, decodedTo);
|
||||
} else {
|
||||
return Promise.reject(error);
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
|
|
@ -18,6 +18,7 @@ import { LocalNotifications, ILocalNotification } from '@ionic-native/local-noti
|
|||
import { TranslateService } from '@ngx-translate/core';
|
||||
import { CoreAppProvider } from './app';
|
||||
import { CoreConfigProvider } from './config';
|
||||
import { CoreEventsProvider } from './events';
|
||||
import { CoreLoggerProvider } from './logger';
|
||||
import { CoreTextUtilsProvider } from './utils/text';
|
||||
import { CoreUtilsProvider } from './utils/utils';
|
||||
|
@ -117,10 +118,31 @@ export class CoreLocalNotificationsProvider {
|
|||
|
||||
constructor(logger: CoreLoggerProvider, private localNotifications: LocalNotifications, private platform: Platform,
|
||||
private appProvider: CoreAppProvider, private utils: CoreUtilsProvider, private configProvider: CoreConfigProvider,
|
||||
private textUtils: CoreTextUtilsProvider, private translate: TranslateService, private alertCtrl: AlertController) {
|
||||
private textUtils: CoreTextUtilsProvider, private translate: TranslateService, private alertCtrl: AlertController,
|
||||
eventsProvider: CoreEventsProvider) {
|
||||
|
||||
this.logger = logger.getInstance('CoreLocalNotificationsProvider');
|
||||
this.appDB = appProvider.getDB();
|
||||
this.appDB.createTablesFromSchema(this.tablesSchema);
|
||||
|
||||
localNotifications.on('trigger', (notification, state) => {
|
||||
this.trigger(notification);
|
||||
});
|
||||
|
||||
localNotifications.on('click', (notification, state) => {
|
||||
if (notification && notification.data) {
|
||||
this.logger.debug('Notification clicked: ', notification.data);
|
||||
|
||||
const data = textUtils.parseJSON(notification.data);
|
||||
this.notifyClick(data);
|
||||
}
|
||||
});
|
||||
|
||||
eventsProvider.on(CoreEventsProvider.SITE_DELETED, (site) => {
|
||||
if (site) {
|
||||
this.cancelSiteNotifications(site.id);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
Loading…
Reference in New Issue