commit
8d8e8a11b4
|
@ -72,6 +72,8 @@ export class CoreMainMenuMorePage implements OnDestroy {
|
||||||
*/
|
*/
|
||||||
ngOnDestroy(): void {
|
ngOnDestroy(): void {
|
||||||
window.removeEventListener('resize', this.initHandlers.bind(this));
|
window.removeEventListener('resize', this.initHandlers.bind(this));
|
||||||
|
this.langObserver && this.langObserver.off();
|
||||||
|
this.updateSiteObserver && this.updateSiteObserver.off();
|
||||||
|
|
||||||
if (this.subscription) {
|
if (this.subscription) {
|
||||||
this.subscription.unsubscribe();
|
this.subscription.unsubscribe();
|
||||||
|
|
|
@ -200,6 +200,15 @@ export class CorePushNotificationsProvider {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check whether the device can be registered in Moodle to receive push notifications.
|
||||||
|
*
|
||||||
|
* @return {boolean} Whether the device can be registered in Moodle.
|
||||||
|
*/
|
||||||
|
canRegisterOnMoodle(): boolean {
|
||||||
|
return this.pushID && this.appProvider.isMobile();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Delete all badge records for a given site.
|
* Delete all badge records for a given site.
|
||||||
*
|
*
|
||||||
|
@ -394,6 +403,11 @@ export class CorePushNotificationsProvider {
|
||||||
const data = notification ? notification.additionalData : {};
|
const data = notification ? notification.additionalData : {};
|
||||||
|
|
||||||
this.sitesProvider.getSite(data.site).then(() => {
|
this.sitesProvider.getSite(data.site).then(() => {
|
||||||
|
|
||||||
|
if (typeof data.customdata == 'string') {
|
||||||
|
data.customdata = this.textUtils.parseJSON(data.customdata, {});
|
||||||
|
}
|
||||||
|
|
||||||
if (this.utils.isTrueOrOne(data.foreground)) {
|
if (this.utils.isTrueOrOne(data.foreground)) {
|
||||||
// If the app is in foreground when the notification is received, it's not shown. Let's show it ourselves.
|
// If the app is in foreground when the notification is received, it's not shown. Let's show it ourselves.
|
||||||
if (this.localNotificationsProvider.isAvailable()) {
|
if (this.localNotificationsProvider.isAvailable()) {
|
||||||
|
@ -658,7 +672,7 @@ export class CorePushNotificationsProvider {
|
||||||
registerDeviceOnMoodle(siteId?: string, forceUnregister?: boolean): Promise<any> {
|
registerDeviceOnMoodle(siteId?: string, forceUnregister?: boolean): Promise<any> {
|
||||||
this.logger.debug('Register device on Moodle.');
|
this.logger.debug('Register device on Moodle.');
|
||||||
|
|
||||||
if (!this.pushID || !this.appProvider.isMobile()) {
|
if (!this.canRegisterOnMoodle()) {
|
||||||
return Promise.reject(null);
|
return Promise.reject(null);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -729,7 +743,7 @@ export class CorePushNotificationsProvider {
|
||||||
|
|
||||||
if (siteId) {
|
if (siteId) {
|
||||||
// Check if the site has a pending unregister.
|
// Check if the site has a pending unregister.
|
||||||
promise = this.appDB.getRecords(CorePushNotificationsProvider.REGISTERED_DEVICES_TABLE, {siteid: siteId});
|
promise = this.appDB.getRecords(CorePushNotificationsProvider.PENDING_UNREGISTER_TABLE, {siteid: siteId});
|
||||||
} else {
|
} else {
|
||||||
// Get all pending unregisters.
|
// Get all pending unregisters.
|
||||||
promise = this.appDB.getAllRecords(CorePushNotificationsProvider.PENDING_UNREGISTER_TABLE);
|
promise = this.appDB.getAllRecords(CorePushNotificationsProvider.PENDING_UNREGISTER_TABLE);
|
||||||
|
|
|
@ -42,7 +42,7 @@ export class CorePushNotificationsRegisterCronHandler implements CoreCronHandler
|
||||||
* @return {Promise<any>} Promise resolved when done, rejected if failure.
|
* @return {Promise<any>} Promise resolved when done, rejected if failure.
|
||||||
*/
|
*/
|
||||||
execute(siteId?: string): Promise<any> {
|
execute(siteId?: string): Promise<any> {
|
||||||
if (!siteId) {
|
if (!siteId || !this.pushNotificationsProvider.canRegisterOnMoodle()) {
|
||||||
// It's not a specific site, don't do anything.
|
// It's not a specific site, don't do anything.
|
||||||
return Promise.resolve();
|
return Promise.resolve();
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,10 +10,12 @@
|
||||||
<p class="item-heading">{{ 'core.sharedfiles.chooseaccountstorefile' | translate }}</p>
|
<p class="item-heading">{{ 'core.sharedfiles.chooseaccountstorefile' | translate }}</p>
|
||||||
<p>{{fileName}}</p>
|
<p>{{fileName}}</p>
|
||||||
</ion-item>
|
</ion-item>
|
||||||
<a ion-item *ngFor="let site of sites" (click)="storeInSite(site.id)">
|
<a ion-item *ngFor="let site of sites" (click)="storeInSite(site.id)" detail-none>
|
||||||
<img [src]="site.avatar" item-start>
|
<ion-avatar item-start>
|
||||||
|
<img [src]="site.avatar" core-external-content [siteId]="site.id" alt="{{ 'core.pictureof' | translate:{$a: site.fullname} }}" role="presentation" onError="this.src='assets/img/user-avatar.png'">
|
||||||
|
</ion-avatar>
|
||||||
<h2>{{site.fullName}}</h2>
|
<h2>{{site.fullName}}</h2>
|
||||||
<p><core-format-text clean="true" [text]="site.siteName"></core-format-text></p>
|
<p><core-format-text clean="true" [text]="site.siteName" [siteId]="site.id"></core-format-text></p>
|
||||||
<p>{{site.siteUrl}}</p>
|
<p>{{site.siteUrl}}</p>
|
||||||
</a>
|
</a>
|
||||||
</ion-list>
|
</ion-list>
|
||||||
|
|
|
@ -73,6 +73,7 @@ export class CoreAppProvider {
|
||||||
protected backActions = [];
|
protected backActions = [];
|
||||||
protected mainMenuId = 0;
|
protected mainMenuId = 0;
|
||||||
protected mainMenuOpen: number;
|
protected mainMenuOpen: number;
|
||||||
|
protected forceOffline = false;
|
||||||
|
|
||||||
constructor(dbProvider: CoreDbProvider, private platform: Platform, private keyboard: Keyboard, private appCtrl: App,
|
constructor(dbProvider: CoreDbProvider, private platform: Platform, private keyboard: Keyboard, private appCtrl: App,
|
||||||
private network: Network, logger: CoreLoggerProvider, private events: CoreEventsProvider, zone: NgZone,
|
private network: Network, logger: CoreLoggerProvider, private events: CoreEventsProvider, zone: NgZone,
|
||||||
|
@ -102,6 +103,9 @@ export class CoreAppProvider {
|
||||||
this.platform.registerBackButtonAction(() => {
|
this.platform.registerBackButtonAction(() => {
|
||||||
this.backButtonAction();
|
this.backButtonAction();
|
||||||
}, 100);
|
}, 100);
|
||||||
|
|
||||||
|
// Export the app provider so Behat tests can change the forceOffline flag.
|
||||||
|
(<any> window).appProvider = this;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -257,6 +261,10 @@ export class CoreAppProvider {
|
||||||
* @return {boolean} Whether the app is online.
|
* @return {boolean} Whether the app is online.
|
||||||
*/
|
*/
|
||||||
isOnline(): boolean {
|
isOnline(): boolean {
|
||||||
|
if (this.forceOffline) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
let online = this.network.type !== null && this.network.type != Connection.NONE && this.network.type != Connection.UNKNOWN;
|
let online = this.network.type !== null && this.network.type != Connection.NONE && this.network.type != Connection.UNKNOWN;
|
||||||
// Double check we are not online because we cannot rely 100% in Cordova APIs. Also, check it in browser.
|
// Double check we are not online because we cannot rely 100% in Cordova APIs. Also, check it in browser.
|
||||||
if (!online && navigator.onLine) {
|
if (!online && navigator.onLine) {
|
||||||
|
@ -567,4 +575,13 @@ export class CoreAppProvider {
|
||||||
this.statusBar.styleLightContent() : this.statusBar.styleDefault();
|
this.statusBar.styleLightContent() : this.statusBar.styleDefault();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set value of forceOffline flag. If true, the app will think the device is offline.
|
||||||
|
*
|
||||||
|
* @param {boolean} value Value to set.
|
||||||
|
*/
|
||||||
|
setForceOffline(value: boolean): void {
|
||||||
|
this.forceOffline = !!value;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -27,6 +27,7 @@ import { CoreConfigConstants } from '../configconstants';
|
||||||
import { CoreSite } from '@classes/site';
|
import { CoreSite } from '@classes/site';
|
||||||
import { SQLiteDB, SQLiteDBTableSchema } from '@classes/sqlitedb';
|
import { SQLiteDB, SQLiteDBTableSchema } from '@classes/sqlitedb';
|
||||||
import { Md5 } from 'ts-md5/dist/md5';
|
import { Md5 } from 'ts-md5/dist/md5';
|
||||||
|
import { Location } from '@angular/common';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Response of checking if a site exists and its configuration.
|
* Response of checking if a site exists and its configuration.
|
||||||
|
@ -320,7 +321,7 @@ export class CoreSitesProvider {
|
||||||
|
|
||||||
constructor(logger: CoreLoggerProvider, private http: HttpClient, private sitesFactory: CoreSitesFactoryProvider,
|
constructor(logger: CoreLoggerProvider, private http: HttpClient, private sitesFactory: CoreSitesFactoryProvider,
|
||||||
private appProvider: CoreAppProvider, private translate: TranslateService, private urlUtils: CoreUrlUtilsProvider,
|
private appProvider: CoreAppProvider, private translate: TranslateService, private urlUtils: CoreUrlUtilsProvider,
|
||||||
private eventsProvider: CoreEventsProvider, private textUtils: CoreTextUtilsProvider,
|
private eventsProvider: CoreEventsProvider, private textUtils: CoreTextUtilsProvider, private location: Location,
|
||||||
private utils: CoreUtilsProvider) {
|
private utils: CoreUtilsProvider) {
|
||||||
this.logger = logger.getInstance('CoreSitesProvider');
|
this.logger = logger.getInstance('CoreSitesProvider');
|
||||||
|
|
||||||
|
@ -1161,6 +1162,9 @@ export class CoreSitesProvider {
|
||||||
promises.push(this.appDB.deleteRecords(this.CURRENT_SITE_TABLE, { id: 1 }));
|
promises.push(this.appDB.deleteRecords(this.CURRENT_SITE_TABLE, { id: 1 }));
|
||||||
|
|
||||||
return Promise.all(promises).finally(() => {
|
return Promise.all(promises).finally(() => {
|
||||||
|
// Due to DeepLinker, we need to remove the path from the URL, otherwise some pages are re-created when they shouldn't.
|
||||||
|
this.location.replaceState('');
|
||||||
|
|
||||||
this.eventsProvider.trigger(CoreEventsProvider.LOGOUT, {}, siteId);
|
this.eventsProvider.trigger(CoreEventsProvider.LOGOUT, {}, siteId);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
@ -125,10 +125,6 @@ export class CoreCustomURLSchemesProvider {
|
||||||
// Some sites add a # at the end of the URL. If it's there, remove it.
|
// Some sites add a # at the end of the URL. If it's there, remove it.
|
||||||
url = url.replace(/\/?#?\/?$/, '');
|
url = url.replace(/\/?#?\/?$/, '');
|
||||||
|
|
||||||
// In iOS, the protocol after the scheme doesn't have ":". Add it.
|
|
||||||
// E.g. "moodlemobile://https://..." is received as "moodlemobile://https//..."
|
|
||||||
url = url.replace(/\/\/(https?)\/\//, '//$1://');
|
|
||||||
|
|
||||||
modal = this.domUtils.showModalLoading();
|
modal = this.domUtils.showModalLoading();
|
||||||
|
|
||||||
// Get the data from the URL.
|
// Get the data from the URL.
|
||||||
|
@ -137,8 +133,14 @@ export class CoreCustomURLSchemesProvider {
|
||||||
|
|
||||||
return this.getCustomURLTokenData(url);
|
return this.getCustomURLTokenData(url);
|
||||||
} else if (this.isCustomURLLink(url)) {
|
} else if (this.isCustomURLLink(url)) {
|
||||||
|
// In iOS, the protocol after the scheme doesn't have ":". Add it.
|
||||||
|
url = url.replace(/\/\/link=(https?)\/\//, '//link=$1://');
|
||||||
|
|
||||||
return this.getCustomURLLinkData(url);
|
return this.getCustomURLLinkData(url);
|
||||||
} else {
|
} else {
|
||||||
|
// In iOS, the protocol after the scheme doesn't have ":". Add it.
|
||||||
|
url = url.replace(/\/\/(https?)\/\//, '//$1://');
|
||||||
|
|
||||||
return this.getCustomURLData(url);
|
return this.getCustomURLData(url);
|
||||||
}
|
}
|
||||||
}).then((result) => {
|
}).then((result) => {
|
||||||
|
|
|
@ -742,11 +742,11 @@ export class CoreUtilsProvider {
|
||||||
* @return {boolean} Whether the error was returned by the WebService.
|
* @return {boolean} Whether the error was returned by the WebService.
|
||||||
*/
|
*/
|
||||||
isWebServiceError(error: any): boolean {
|
isWebServiceError(error: any): boolean {
|
||||||
return typeof error.warningcode != 'undefined' || (typeof error.errorcode != 'undefined' &&
|
return error && (typeof error.warningcode != 'undefined' || (typeof error.errorcode != 'undefined' &&
|
||||||
error.errorcode != 'invalidtoken' && error.errorcode != 'userdeleted' && error.errorcode != 'upgraderunning' &&
|
error.errorcode != 'invalidtoken' && error.errorcode != 'userdeleted' && error.errorcode != 'upgraderunning' &&
|
||||||
error.errorcode != 'forcepasswordchangenotice' && error.errorcode != 'usernotfullysetup' &&
|
error.errorcode != 'forcepasswordchangenotice' && error.errorcode != 'usernotfullysetup' &&
|
||||||
error.errorcode != 'sitepolicynotagreed' && error.errorcode != 'sitemaintenance' &&
|
error.errorcode != 'sitepolicynotagreed' && error.errorcode != 'sitemaintenance' &&
|
||||||
(error.errorcode != 'accessexception' || error.message.indexOf('Invalid token - token expired') == -1));
|
(error.errorcode != 'accessexception' || error.message.indexOf('Invalid token - token expired') == -1)));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
Loading…
Reference in New Issue