MOBILE-4653 app: Divide CoreApp in many services
parent
966edb8beb
commit
bc35290e15
|
@ -12,7 +12,7 @@
|
||||||
// See the License for the specific language governing permissions and
|
// See the License for the specific language governing permissions and
|
||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
|
|
||||||
import { CoreApp } from '@services/app';
|
import { CoreSSO } from '@singletons/sso';
|
||||||
import { CoreNetwork } from '@services/network';
|
import { CoreNetwork } from '@services/network';
|
||||||
import { CoreEventData, CoreEvents } from '@singletons/events';
|
import { CoreEventData, CoreEvents } from '@singletons/events';
|
||||||
import {
|
import {
|
||||||
|
@ -790,9 +790,9 @@ export class CoreAuthenticatedSite extends CoreUnauthenticatedSite {
|
||||||
wsPreSets.wsToken = this.token ?? '';
|
wsPreSets.wsToken = this.token ?? '';
|
||||||
|
|
||||||
return await this.callOrEnqueueRequest<T>(method, data, preSets, wsPreSets);
|
return await this.callOrEnqueueRequest<T>(method, data, preSets, wsPreSets);
|
||||||
} else if (CoreApp.isSSOAuthenticationOngoing()) {
|
} else if (CoreSSO.isSSOAuthenticationOngoing()) {
|
||||||
// There's an SSO authentication ongoing, wait for it to finish and try again.
|
// There's an SSO authentication ongoing, wait for it to finish and try again.
|
||||||
await CoreApp.waitForSSOAuthentication();
|
await CoreSSO.waitForSSOAuthentication();
|
||||||
|
|
||||||
return await this.callOrEnqueueRequest<T>(method, data, preSets, wsPreSets);
|
return await this.callOrEnqueueRequest<T>(method, data, preSets, wsPreSets);
|
||||||
}
|
}
|
||||||
|
|
|
@ -29,6 +29,7 @@ import { getInitializerProviders } from './initializers';
|
||||||
export async function getCoreServices(): Promise<Type<unknown>[]> {
|
export async function getCoreServices(): Promise<Type<unknown>[]> {
|
||||||
|
|
||||||
const { CoreAppProvider } = await import('@services/app');
|
const { CoreAppProvider } = await import('@services/app');
|
||||||
|
const { CoreAppDBService } = await import('@services/app-db');
|
||||||
const { CoreConfigProvider } = await import('@services/config');
|
const { CoreConfigProvider } = await import('@services/config');
|
||||||
const { CoreCronDelegateService } = await import('@services/cron');
|
const { CoreCronDelegateService } = await import('@services/cron');
|
||||||
const { CoreCustomURLSchemesProvider } = await import('@services/urlschemes');
|
const { CoreCustomURLSchemesProvider } = await import('@services/urlschemes');
|
||||||
|
@ -65,6 +66,7 @@ export async function getCoreServices(): Promise<Type<unknown>[]> {
|
||||||
|
|
||||||
return [
|
return [
|
||||||
CoreAppProvider,
|
CoreAppProvider,
|
||||||
|
CoreAppDBService,
|
||||||
CoreConfigProvider,
|
CoreConfigProvider,
|
||||||
CoreCronDelegateService,
|
CoreCronDelegateService,
|
||||||
CoreCustomURLSchemesProvider,
|
CoreCustomURLSchemesProvider,
|
||||||
|
|
|
@ -14,7 +14,7 @@
|
||||||
|
|
||||||
import { Injectable } from '@angular/core';
|
import { Injectable } from '@angular/core';
|
||||||
|
|
||||||
import { CoreApp } from '@services/app';
|
import { CoreMedia } from '@singletons/media';
|
||||||
import { CorePlatform } from '@services/platform';
|
import { CorePlatform } from '@services/platform';
|
||||||
import { CoreArray } from '@singletons/array';
|
import { CoreArray } from '@singletons/array';
|
||||||
import { makeSingleton } from '@singletons';
|
import { makeSingleton } from '@singletons';
|
||||||
|
@ -34,7 +34,7 @@ export class CoreFileUploaderAudioHandlerService implements CoreFileUploaderHand
|
||||||
* @inheritdoc
|
* @inheritdoc
|
||||||
*/
|
*/
|
||||||
async isEnabled(): Promise<boolean> {
|
async isEnabled(): Promise<boolean> {
|
||||||
return CorePlatform.isMobile() || (CoreApp.canGetUserMedia() && CoreApp.canRecordMedia());
|
return CorePlatform.isMobile() || (CoreMedia.canGetUserMedia() && CoreMedia.canRecordMedia());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -14,7 +14,7 @@
|
||||||
|
|
||||||
import { Injectable } from '@angular/core';
|
import { Injectable } from '@angular/core';
|
||||||
|
|
||||||
import { CoreApp } from '@services/app';
|
import { CoreMedia } from '@singletons/media';
|
||||||
import { CorePlatform } from '@services/platform';
|
import { CorePlatform } from '@services/platform';
|
||||||
import { CoreArray } from '@singletons/array';
|
import { CoreArray } from '@singletons/array';
|
||||||
import { makeSingleton } from '@singletons';
|
import { makeSingleton } from '@singletons';
|
||||||
|
@ -34,7 +34,7 @@ export class CoreFileUploaderCameraHandlerService implements CoreFileUploaderHan
|
||||||
* @inheritdoc
|
* @inheritdoc
|
||||||
*/
|
*/
|
||||||
async isEnabled(): Promise<boolean> {
|
async isEnabled(): Promise<boolean> {
|
||||||
return CorePlatform.isMobile() || CoreApp.canGetUserMedia();
|
return CorePlatform.isMobile() || CoreMedia.canGetUserMedia();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -14,7 +14,7 @@
|
||||||
|
|
||||||
import { Injectable } from '@angular/core';
|
import { Injectable } from '@angular/core';
|
||||||
|
|
||||||
import { CoreApp } from '@services/app';
|
import { CoreMedia } from '@singletons/media';
|
||||||
import { CorePlatform } from '@services/platform';
|
import { CorePlatform } from '@services/platform';
|
||||||
import { CoreArray } from '@singletons/array';
|
import { CoreArray } from '@singletons/array';
|
||||||
import { makeSingleton } from '@singletons';
|
import { makeSingleton } from '@singletons';
|
||||||
|
@ -34,7 +34,7 @@ export class CoreFileUploaderVideoHandlerService implements CoreFileUploaderHand
|
||||||
* @inheritdoc
|
* @inheritdoc
|
||||||
*/
|
*/
|
||||||
async isEnabled(): Promise<boolean> {
|
async isEnabled(): Promise<boolean> {
|
||||||
return CorePlatform.isMobile() || (CoreApp.canGetUserMedia() && CoreApp.canRecordMedia());
|
return CorePlatform.isMobile() || (CoreMedia.canGetUserMedia() && CoreMedia.canRecordMedia());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -17,7 +17,7 @@ import { FormBuilder, FormGroup, Validators } from '@angular/forms';
|
||||||
import { Subscription } from 'rxjs';
|
import { Subscription } from 'rxjs';
|
||||||
import { debounceTime } from 'rxjs/operators';
|
import { debounceTime } from 'rxjs/operators';
|
||||||
|
|
||||||
import { CoreApp } from '@services/app';
|
import { CoreSSO } from '@singletons/sso';
|
||||||
import { CoreNetwork } from '@services/network';
|
import { CoreNetwork } from '@services/network';
|
||||||
import { CoreSiteCheckResponse, CoreSites } from '@services/sites';
|
import { CoreSiteCheckResponse, CoreSites } from '@services/sites';
|
||||||
import { CoreDomUtils } from '@services/utils/dom';
|
import { CoreDomUtils } from '@services/utils/dom';
|
||||||
|
@ -251,7 +251,7 @@ export class CoreLoginCredentialsPage implements OnInit, OnDestroy {
|
||||||
e?.stopPropagation();
|
e?.stopPropagation();
|
||||||
|
|
||||||
// Check that there's no SSO authentication ongoing and the view hasn't changed.
|
// Check that there's no SSO authentication ongoing and the view hasn't changed.
|
||||||
if (CoreApp.isSSOAuthenticationOngoing() || this.viewLeft || !this.siteCheck) {
|
if (CoreSSO.isSSOAuthenticationOngoing() || this.viewLeft || !this.siteCheck) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -61,6 +61,7 @@ import { CoreSiteError, CoreSiteErrorDebug } from '@classes/errors/siteerror';
|
||||||
import { CoreQRScan } from '@services/qrscan';
|
import { CoreQRScan } from '@services/qrscan';
|
||||||
import { CoreLoadings } from '@services/loadings';
|
import { CoreLoadings } from '@services/loadings';
|
||||||
import { CoreErrorHelper } from '@services/error-helper';
|
import { CoreErrorHelper } from '@services/error-helper';
|
||||||
|
import { CoreSSO } from '@singletons/sso';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Helper provider that provides some common features regarding authentication.
|
* Helper provider that provides some common features regarding authentication.
|
||||||
|
@ -131,7 +132,7 @@ export class CoreLoginHelperProvider {
|
||||||
const currentSite = CoreSites.getCurrentSite();
|
const currentSite = CoreSites.getCurrentSite();
|
||||||
|
|
||||||
if (
|
if (
|
||||||
!CoreApp.isSSOAuthenticationOngoing() &&
|
!CoreSSO.isSSOAuthenticationOngoing() &&
|
||||||
currentSite?.isLoggedOut() &&
|
currentSite?.isLoggedOut() &&
|
||||||
CoreNavigator.isCurrent('/login/reconnect')
|
CoreNavigator.isCurrent('/login/reconnect')
|
||||||
) {
|
) {
|
||||||
|
|
|
@ -14,7 +14,7 @@
|
||||||
|
|
||||||
import { CanActivateFn } from '@angular/router';
|
import { CanActivateFn } from '@angular/router';
|
||||||
import { CoreLoginHelper } from '@features/login/services/login-helper';
|
import { CoreLoginHelper } from '@features/login/services/login-helper';
|
||||||
import { CoreApp } from '@services/app';
|
import { CoreRedirects } from '@singletons/redirects';
|
||||||
|
|
||||||
import { CoreSites } from '@services/sites';
|
import { CoreSites } from '@services/sites';
|
||||||
import { Router } from '@singletons';
|
import { Router } from '@singletons';
|
||||||
|
@ -35,7 +35,7 @@ export const authGuard: CanActivateFn = async () => {
|
||||||
const siteId = CoreSites.getCurrentSiteId();
|
const siteId = CoreSites.getCurrentSiteId();
|
||||||
|
|
||||||
// Pass redirect data (if any and belongs to same site).
|
// Pass redirect data (if any and belongs to same site).
|
||||||
let redirect = CoreApp.consumeMemoryRedirect();
|
let redirect = CoreRedirects.consumeMemoryRedirect();
|
||||||
if (redirect?.siteId !== siteId) {
|
if (redirect?.siteId !== siteId) {
|
||||||
redirect = null;
|
redirect = null;
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,7 +13,7 @@
|
||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
|
|
||||||
import { SQLiteDB } from '@classes/sqlitedb';
|
import { SQLiteDB } from '@classes/sqlitedb';
|
||||||
import { CoreAppSchema } from '@services/app';
|
import { CoreAppSchema } from '@services/app-db';
|
||||||
import { CoreSiteSchema } from '@services/sites';
|
import { CoreSiteSchema } from '@services/sites';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -16,7 +16,7 @@ import { Injectable } from '@angular/core';
|
||||||
import { ILocalNotification } from '@awesome-cordova-plugins/local-notifications';
|
import { ILocalNotification } from '@awesome-cordova-plugins/local-notifications';
|
||||||
import { NotificationEventResponse, PushOptions, RegistrationEventResponse } from '@awesome-cordova-plugins/push/ngx';
|
import { NotificationEventResponse, PushOptions, RegistrationEventResponse } from '@awesome-cordova-plugins/push/ngx';
|
||||||
|
|
||||||
import { CoreApp } from '@services/app';
|
import { CoreAppDB } from '@services/app-db';
|
||||||
import { CoreSites } from '@services/sites';
|
import { CoreSites } from '@services/sites';
|
||||||
import { CorePushNotificationsDelegate } from './push-delegate';
|
import { CorePushNotificationsDelegate } from './push-delegate';
|
||||||
import { CoreLocalNotifications } from '@services/local-notifications';
|
import { CoreLocalNotifications } from '@services/local-notifications';
|
||||||
|
@ -204,13 +204,9 @@ export class CorePushNotificationsProvider {
|
||||||
* @returns Promise resolved when done.
|
* @returns Promise resolved when done.
|
||||||
*/
|
*/
|
||||||
protected async initializeDatabase(): Promise<void> {
|
protected async initializeDatabase(): Promise<void> {
|
||||||
try {
|
await CoreAppDB.createTablesFromSchema(APP_SCHEMA);
|
||||||
await CoreApp.createTablesFromSchema(APP_SCHEMA);
|
|
||||||
} catch {
|
|
||||||
// Ignore errors.
|
|
||||||
}
|
|
||||||
|
|
||||||
const database = CoreApp.getDB();
|
const database = CoreAppDB.getDB();
|
||||||
const badgesTable = new CoreDatabaseTableProxy<CorePushNotificationsBadgeDBRecord, CorePushNotificationsBadgeDBPrimaryKeys>(
|
const badgesTable = new CoreDatabaseTableProxy<CorePushNotificationsBadgeDBRecord, CorePushNotificationsBadgeDBPrimaryKeys>(
|
||||||
{ cachingStrategy: CoreDatabaseCachingStrategy.Eager },
|
{ cachingStrategy: CoreDatabaseCachingStrategy.Eager },
|
||||||
database,
|
database,
|
||||||
|
|
|
@ -12,7 +12,7 @@
|
||||||
// See the License for the specific language governing permissions and
|
// See the License for the specific language governing permissions and
|
||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
|
|
||||||
import { CoreAppSchema } from '@services/app';
|
import { CoreAppSchema } from '@services/app-db';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Database variables for CoreSharedFilesProvider service.
|
* Database variables for CoreSharedFilesProvider service.
|
||||||
|
|
|
@ -17,7 +17,7 @@ import { FileEntry, DirectoryEntry } from '@awesome-cordova-plugins/file/ngx';
|
||||||
import { Md5 } from 'ts-md5/dist/md5';
|
import { Md5 } from 'ts-md5/dist/md5';
|
||||||
|
|
||||||
import { CoreLogger } from '@singletons/logger';
|
import { CoreLogger } from '@singletons/logger';
|
||||||
import { CoreApp } from '@services/app';
|
import { CoreAppDB } from '@services/app-db';
|
||||||
import { CoreFile } from '@services/file';
|
import { CoreFile } from '@services/file';
|
||||||
import { CoreUtils } from '@services/utils/utils';
|
import { CoreUtils } from '@services/utils/utils';
|
||||||
import { CoreMimetypeUtils } from '@services/utils/mimetype';
|
import { CoreMimetypeUtils } from '@services/utils/mimetype';
|
||||||
|
@ -51,13 +51,9 @@ export class CoreSharedFilesProvider {
|
||||||
* @returns Promise resolved when done.
|
* @returns Promise resolved when done.
|
||||||
*/
|
*/
|
||||||
async initializeDatabase(): Promise<void> {
|
async initializeDatabase(): Promise<void> {
|
||||||
try {
|
await CoreAppDB.createTablesFromSchema(APP_SCHEMA);
|
||||||
await CoreApp.createTablesFromSchema(APP_SCHEMA);
|
|
||||||
} catch (e) {
|
|
||||||
// Ignore errors.
|
|
||||||
}
|
|
||||||
|
|
||||||
const database = CoreApp.getDB();
|
const database = CoreAppDB.getDB();
|
||||||
const sharedFilesTable = new CoreDatabaseTableProxy<CoreSharedFilesDBRecord>(
|
const sharedFilesTable = new CoreDatabaseTableProxy<CoreSharedFilesDBRecord>(
|
||||||
{ cachingStrategy: CoreDatabaseCachingStrategy.None },
|
{ cachingStrategy: CoreDatabaseCachingStrategy.None },
|
||||||
database,
|
database,
|
||||||
|
|
|
@ -18,7 +18,6 @@ import { CoreCacheUpdateFrequency, CoreConstants } from '@/core/constants';
|
||||||
import { CoreSite } from '@classes/sites/site';
|
import { CoreSite } from '@classes/sites/site';
|
||||||
import { CoreCourseAnyModuleData } from '@features/course/services/course';
|
import { CoreCourseAnyModuleData } from '@features/course/services/course';
|
||||||
import { CoreCourses } from '@features/courses/services/courses';
|
import { CoreCourses } from '@features/courses/services/courses';
|
||||||
import { CoreApp } from '@services/app';
|
|
||||||
import { CoreFilepool } from '@services/filepool';
|
import { CoreFilepool } from '@services/filepool';
|
||||||
import { CoreLang, CoreLangFormat } from '@services/lang';
|
import { CoreLang, CoreLangFormat } from '@services/lang';
|
||||||
import { CoreSites } from '@services/sites';
|
import { CoreSites } from '@services/sites';
|
||||||
|
@ -101,7 +100,7 @@ export class CoreSitePluginsProvider {
|
||||||
appcustomurlscheme: CoreConstants.CONFIG.customurlscheme,
|
appcustomurlscheme: CoreConstants.CONFIG.customurlscheme,
|
||||||
appisdesktop: false,
|
appisdesktop: false,
|
||||||
appismobile: CorePlatform.isMobile(),
|
appismobile: CorePlatform.isMobile(),
|
||||||
appiswide: CoreApp.isWide(),
|
appiswide: CorePlatform.isWide(),
|
||||||
appplatform: 'browser',
|
appplatform: 'browser',
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -25,7 +25,6 @@ import {
|
||||||
USER_PROFILE_REFRESHED,
|
USER_PROFILE_REFRESHED,
|
||||||
USER_PROFILE_SERVER_TIMEZONE,
|
USER_PROFILE_SERVER_TIMEZONE,
|
||||||
} from '@features/user/services/user';
|
} from '@features/user/services/user';
|
||||||
import { CoreUserHelper } from '@features/user/services/user-helper';
|
|
||||||
import { CoreNavigator } from '@services/navigator';
|
import { CoreNavigator } from '@services/navigator';
|
||||||
import { CoreIonLoadingElement } from '@classes/ion-loading';
|
import { CoreIonLoadingElement } from '@classes/ion-loading';
|
||||||
import { CoreSite } from '@classes/sites/site';
|
import { CoreSite } from '@classes/sites/site';
|
||||||
|
@ -34,6 +33,7 @@ import { CoreMimetypeUtils } from '@services/utils/mimetype';
|
||||||
import { Translate } from '@singletons';
|
import { Translate } from '@singletons';
|
||||||
import { CoreUrl } from '@singletons/url';
|
import { CoreUrl } from '@singletons/url';
|
||||||
import { CoreLoadings } from '@services/loadings';
|
import { CoreLoadings } from '@services/loadings';
|
||||||
|
import { CoreTime } from '@singletons/time';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Page that displays info about a user.
|
* Page that displays info about a user.
|
||||||
|
@ -275,7 +275,7 @@ export class CoreUserAboutPage implements OnInit, OnDestroy {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this.user.timezone) {
|
if (this.user.timezone) {
|
||||||
this.user.timezone = CoreUserHelper.translateLegacyTimezone(this.user.timezone);
|
this.user.timezone = CoreTime.translateLegacyTimezone(this.user.timezone);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -18,6 +18,7 @@ import { CoreSites } from '@services/sites';
|
||||||
|
|
||||||
import { makeSingleton, Translate } from '@singletons';
|
import { makeSingleton, Translate } from '@singletons';
|
||||||
import { CoreUser, CoreUserProfile, CoreUserRole } from './user';
|
import { CoreUser, CoreUserProfile, CoreUserRole } from './user';
|
||||||
|
import { CoreTime } from '@singletons/time';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Service that provides some features regarding users information.
|
* Service that provides some features regarding users information.
|
||||||
|
@ -25,63 +26,6 @@ import { CoreUser, CoreUserProfile, CoreUserRole } from './user';
|
||||||
@Injectable({ providedIn: 'root' })
|
@Injectable({ providedIn: 'root' })
|
||||||
export class CoreUserHelperProvider {
|
export class CoreUserHelperProvider {
|
||||||
|
|
||||||
protected static readonly LEGACY_TIMEZONES = {
|
|
||||||
'-13.0': 'Australia/Perth',
|
|
||||||
'-12.5': 'Etc/GMT+12',
|
|
||||||
'-12.0': 'Etc/GMT+12',
|
|
||||||
'-11.5': 'Etc/GMT+11',
|
|
||||||
'-11.0': 'Etc/GMT+11',
|
|
||||||
'-10.5': 'Etc/GMT+10',
|
|
||||||
'-10.0': 'Etc/GMT+10',
|
|
||||||
'-9.5': 'Etc/GMT+9',
|
|
||||||
'-9.0': 'Etc/GMT+9',
|
|
||||||
'-8.5': 'Etc/GMT+8',
|
|
||||||
'-8.0': 'Etc/GMT+8',
|
|
||||||
'-7.5': 'Etc/GMT+7',
|
|
||||||
'-7.0': 'Etc/GMT+7',
|
|
||||||
'-6.5': 'Etc/GMT+6',
|
|
||||||
'-6.0': 'Etc/GMT+6',
|
|
||||||
'-5.5': 'Etc/GMT+5',
|
|
||||||
'-5.0': 'Etc/GMT+5',
|
|
||||||
'-4.5': 'Etc/GMT+4',
|
|
||||||
'-4.0': 'Etc/GMT+4',
|
|
||||||
'-3.5': 'Etc/GMT+3',
|
|
||||||
'-3.0': 'Etc/GMT+3',
|
|
||||||
'-2.5': 'Etc/GMT+2',
|
|
||||||
'-2.0': 'Etc/GMT+2',
|
|
||||||
'-1.5': 'Etc/GMT+1',
|
|
||||||
'-1.0': 'Etc/GMT+1',
|
|
||||||
'-0.5': 'Etc/GMT',
|
|
||||||
'0': 'Etc/GMT',
|
|
||||||
'0.0': 'Etc/GMT',
|
|
||||||
'0.5': 'Etc/GMT',
|
|
||||||
'1.0': 'Etc/GMT-1',
|
|
||||||
'1.5': 'Etc/GMT-1',
|
|
||||||
'2.0': 'Etc/GMT-2',
|
|
||||||
'2.5': 'Etc/GMT-2',
|
|
||||||
'3.0': 'Etc/GMT-3',
|
|
||||||
'3.5': 'Etc/GMT-3',
|
|
||||||
'4.0': 'Etc/GMT-4',
|
|
||||||
'4.5': 'Asia/Kabul',
|
|
||||||
'5.0': 'Etc/GMT-5',
|
|
||||||
'5.5': 'Asia/Kolkata',
|
|
||||||
'6.0': 'Etc/GMT-6',
|
|
||||||
'6.5': 'Asia/Rangoon',
|
|
||||||
'7.0': 'Etc/GMT-7',
|
|
||||||
'7.5': 'Etc/GMT-7',
|
|
||||||
'8.0': 'Etc/GMT-8',
|
|
||||||
'8.5': 'Etc/GMT-8',
|
|
||||||
'9.0': 'Etc/GMT-9',
|
|
||||||
'9.5': 'Australia/Darwin',
|
|
||||||
'10.0': 'Etc/GMT-10',
|
|
||||||
'10.5': 'Etc/GMT-10',
|
|
||||||
'11.0': 'Etc/GMT-11',
|
|
||||||
'11.5': 'Etc/GMT-11',
|
|
||||||
'12.0': 'Etc/GMT-12',
|
|
||||||
'12.5': 'Etc/GMT-12',
|
|
||||||
'13.0': 'Etc/GMT-13',
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Formats a user address, concatenating address, city and country.
|
* Formats a user address, concatenating address, city and country.
|
||||||
*
|
*
|
||||||
|
@ -192,9 +136,10 @@ export class CoreUserHelperProvider {
|
||||||
*
|
*
|
||||||
* @param tz Timezone name.
|
* @param tz Timezone name.
|
||||||
* @returns Readable timezone name.
|
* @returns Readable timezone name.
|
||||||
|
* @deprecated since 5.0. Use CoreTime.translateLegacyTimezone instead.
|
||||||
*/
|
*/
|
||||||
translateLegacyTimezone(tz: string): string {
|
translateLegacyTimezone(tz: string): string {
|
||||||
return CoreUserHelperProvider.LEGACY_TIMEZONES[tz] ?? tz;
|
return CoreTime.translateLegacyTimezone(tz);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,7 +12,7 @@
|
||||||
// See the License for the specific language governing permissions and
|
// See the License for the specific language governing permissions and
|
||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
|
|
||||||
import { CoreAppSchema } from '@services/app';
|
import { CoreAppSchema } from '@services/app-db';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Database variables for CoreUserTours service.
|
* Database variables for CoreUserTours service.
|
||||||
|
|
|
@ -18,13 +18,12 @@ import { Injectable } from '@angular/core';
|
||||||
import { CoreCancellablePromise } from '@classes/cancellable-promise';
|
import { CoreCancellablePromise } from '@classes/cancellable-promise';
|
||||||
import { CoreDatabaseTable } from '@classes/database/database-table';
|
import { CoreDatabaseTable } from '@classes/database/database-table';
|
||||||
import { CoreDatabaseCachingStrategy, CoreDatabaseTableProxy } from '@classes/database/database-table-proxy';
|
import { CoreDatabaseCachingStrategy, CoreDatabaseTableProxy } from '@classes/database/database-table-proxy';
|
||||||
import { CoreApp } from '@services/app';
|
import { CoreAppDB } from '@services/app-db';
|
||||||
import { CoreUtils } from '@services/utils/utils';
|
|
||||||
import { AngularFrameworkDelegate, makeSingleton } from '@singletons';
|
import { AngularFrameworkDelegate, makeSingleton } from '@singletons';
|
||||||
import { CoreDirectivesRegistry } from '@singletons/directives-registry';
|
import { CoreDirectivesRegistry } from '@singletons/directives-registry';
|
||||||
import { CoreDom } from '@singletons/dom';
|
import { CoreDom } from '@singletons/dom';
|
||||||
import { CoreSubscriptions } from '@singletons/subscriptions';
|
import { CoreSubscriptions } from '@singletons/subscriptions';
|
||||||
import { CoreUserToursUserTourComponent } from '../components/user-tour/user-tour';
|
import type { CoreUserToursUserTourComponent } from '../components/user-tour/user-tour';
|
||||||
import { APP_SCHEMA, CoreUserToursDBEntry, USER_TOURS_TABLE_NAME } from './database/user-tours';
|
import { APP_SCHEMA, CoreUserToursDBEntry, USER_TOURS_TABLE_NAME } from './database/user-tours';
|
||||||
import { CorePromisedValue } from '@classes/promised-value';
|
import { CorePromisedValue } from '@classes/promised-value';
|
||||||
import { CoreWait } from '@singletons/wait';
|
import { CoreWait } from '@singletons/wait';
|
||||||
|
@ -43,12 +42,12 @@ export class CoreUserToursService {
|
||||||
* Initialize database.
|
* Initialize database.
|
||||||
*/
|
*/
|
||||||
async initializeDatabase(): Promise<void> {
|
async initializeDatabase(): Promise<void> {
|
||||||
await CoreUtils.ignoreErrors(CoreApp.createTablesFromSchema(APP_SCHEMA));
|
await CoreAppDB.createTablesFromSchema(APP_SCHEMA);
|
||||||
|
|
||||||
this.table.setLazyConstructor(async () => {
|
this.table.setLazyConstructor(async () => {
|
||||||
const table = new CoreDatabaseTableProxy<CoreUserToursDBEntry>(
|
const table = new CoreDatabaseTableProxy<CoreUserToursDBEntry>(
|
||||||
{ cachingStrategy: CoreDatabaseCachingStrategy.Eager },
|
{ cachingStrategy: CoreDatabaseCachingStrategy.Eager },
|
||||||
CoreApp.getDB(),
|
CoreAppDB.getDB(),
|
||||||
USER_TOURS_TABLE_NAME,
|
USER_TOURS_TABLE_NAME,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -112,6 +111,8 @@ export class CoreUserToursService {
|
||||||
protected async show(options: CoreUserToursBasicOptions): Promise<CoreUserToursUserTour>;
|
protected async show(options: CoreUserToursBasicOptions): Promise<CoreUserToursUserTour>;
|
||||||
protected async show(options: CoreUserToursFocusedOptions): Promise<CoreUserToursUserTour>;
|
protected async show(options: CoreUserToursFocusedOptions): Promise<CoreUserToursUserTour>;
|
||||||
protected async show(options: CoreUserToursBasicOptions | CoreUserToursFocusedOptions): Promise<CoreUserToursUserTour> {
|
protected async show(options: CoreUserToursBasicOptions | CoreUserToursFocusedOptions): Promise<CoreUserToursUserTour> {
|
||||||
|
const { CoreUserToursUserTourComponent } = await import('../components/user-tour/user-tour');
|
||||||
|
|
||||||
const { delay, ...componentOptions } = options;
|
const { delay, ...componentOptions } = options;
|
||||||
|
|
||||||
await CoreWait.wait(delay ?? 200);
|
await CoreWait.wait(delay ?? 200);
|
||||||
|
|
|
@ -13,7 +13,7 @@
|
||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
|
|
||||||
import { CanActivateFn } from '@angular/router';
|
import { CanActivateFn } from '@angular/router';
|
||||||
import { CoreApp } from '@services/app';
|
import { CoreRedirects } from '@singletons/redirects';
|
||||||
import { CoreRedirectPayload } from '@services/navigator';
|
import { CoreRedirectPayload } from '@services/navigator';
|
||||||
import { CoreSites } from '@services/sites';
|
import { CoreSites } from '@services/sites';
|
||||||
import { Router } from '@singletons';
|
import { Router } from '@singletons';
|
||||||
|
@ -25,7 +25,7 @@ import { CoreConstants } from '../constants';
|
||||||
* @returns True if there's no redirect, redirection route otherwise.
|
* @returns True if there's no redirect, redirection route otherwise.
|
||||||
*/
|
*/
|
||||||
export const redirectGuard: CanActivateFn = async () => {
|
export const redirectGuard: CanActivateFn = async () => {
|
||||||
const redirect = CoreApp.consumeMemoryRedirect();
|
const redirect = CoreRedirects.consumeMemoryRedirect();
|
||||||
if (!redirect) {
|
if (!redirect) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,6 +12,7 @@
|
||||||
// See the License for the specific language governing permissions and
|
// See the License for the specific language governing permissions and
|
||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
|
|
||||||
|
import { CoreApp } from '@services/app';
|
||||||
import { CoreHTMLClasses } from '@singletons/html-classes';
|
import { CoreHTMLClasses } from '@singletons/html-classes';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -19,4 +20,5 @@ import { CoreHTMLClasses } from '@singletons/html-classes';
|
||||||
*/
|
*/
|
||||||
export default async function(): Promise<void> {
|
export default async function(): Promise<void> {
|
||||||
CoreHTMLClasses.initialize();
|
CoreHTMLClasses.initialize();
|
||||||
|
CoreApp.initialize();
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,7 +12,7 @@
|
||||||
// See the License for the specific language governing permissions and
|
// See the License for the specific language governing permissions and
|
||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
|
|
||||||
import { CoreApp } from '@services/app';
|
import { CoreRedirects } from '@singletons/redirects';
|
||||||
import { CoreUpdateManager } from '@services/update-manager';
|
import { CoreUpdateManager } from '@services/update-manager';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -21,5 +21,5 @@ import { CoreUpdateManager } from '@services/update-manager';
|
||||||
export default async function(): Promise<void> {
|
export default async function(): Promise<void> {
|
||||||
await CoreUpdateManager.donePromise;
|
await CoreUpdateManager.donePromise;
|
||||||
|
|
||||||
CoreApp.consumeStorageRedirect();
|
CoreRedirects.consumeStorageRedirect();
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,7 +12,7 @@
|
||||||
// See the License for the specific language governing permissions and
|
// See the License for the specific language governing permissions and
|
||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
|
|
||||||
import { CoreApp } from '@services/app';
|
import { CoreAppDB } from '@services/app-db';
|
||||||
import { CoreConfig } from '@services/config';
|
import { CoreConfig } from '@services/config';
|
||||||
import { CoreCronDelegate } from '@services/cron';
|
import { CoreCronDelegate } from '@services/cron';
|
||||||
import { CoreFilepool } from '@services/filepool';
|
import { CoreFilepool } from '@services/filepool';
|
||||||
|
@ -25,7 +25,7 @@ import { CoreStorage } from '@services/storage';
|
||||||
*/
|
*/
|
||||||
export default async function(): Promise<void> {
|
export default async function(): Promise<void> {
|
||||||
await Promise.all([
|
await Promise.all([
|
||||||
CoreApp.initializeDatabase(),
|
CoreAppDB.initializeDatabase(),
|
||||||
CoreConfig.initializeDatabase(),
|
CoreConfig.initializeDatabase(),
|
||||||
CoreCronDelegate.initializeDatabase(),
|
CoreCronDelegate.initializeDatabase(),
|
||||||
CoreFilepool.initializeDatabase(),
|
CoreFilepool.initializeDatabase(),
|
||||||
|
|
|
@ -13,16 +13,16 @@
|
||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
|
|
||||||
import { CorePushNotifications, CorePushNotificationsProvider } from '@features/pushnotifications/services/pushnotifications';
|
import { CorePushNotifications, CorePushNotificationsProvider } from '@features/pushnotifications/services/pushnotifications';
|
||||||
import { CoreApp, CoreAppProvider } from '@services/app';
|
|
||||||
import { CoreConfig, CoreConfigProvider } from '@services/config';
|
import { CoreConfig, CoreConfigProvider } from '@services/config';
|
||||||
import { CoreDB, CoreDbProvider } from '@services/db';
|
import { CoreDB, CoreDbProvider } from '@services/db';
|
||||||
import { CoreCustomURLSchemes, CoreCustomURLSchemesProvider } from '@services/urlschemes';
|
import { CoreCustomURLSchemes, CoreCustomURLSchemesProvider } from '@services/urlschemes';
|
||||||
import { CoreBrowser } from '@singletons/browser';
|
import { CoreBrowser } from '@singletons/browser';
|
||||||
import { CoreConstants } from '../constants';
|
import { CoreConstants } from '../constants';
|
||||||
|
import { CoreAppDB, CoreAppDBService } from '@services/app-db';
|
||||||
|
|
||||||
type DevelopmentWindow = Window & {
|
type DevelopmentWindow = Window & {
|
||||||
browser?: typeof CoreBrowser;
|
browser?: typeof CoreBrowser;
|
||||||
appProvider?: CoreAppProvider;
|
appDBService?: CoreAppDBService;
|
||||||
configProvider?: CoreConfigProvider;
|
configProvider?: CoreConfigProvider;
|
||||||
dbProvider?: CoreDbProvider;
|
dbProvider?: CoreDbProvider;
|
||||||
urlSchemes?: CoreCustomURLSchemesProvider;
|
urlSchemes?: CoreCustomURLSchemesProvider;
|
||||||
|
@ -36,7 +36,7 @@ type DevelopmentWindow = Window & {
|
||||||
*/
|
*/
|
||||||
function initializeDevelopmentWindow(window: DevelopmentWindow) {
|
function initializeDevelopmentWindow(window: DevelopmentWindow) {
|
||||||
window.browser = CoreBrowser;
|
window.browser = CoreBrowser;
|
||||||
window.appProvider = CoreApp.instance;
|
window.appDBService = CoreAppDB.instance;
|
||||||
window.configProvider = CoreConfig.instance;
|
window.configProvider = CoreConfig.instance;
|
||||||
window.dbProvider = CoreDB.instance;
|
window.dbProvider = CoreDB.instance;
|
||||||
window.urlSchemes = CoreCustomURLSchemes.instance;
|
window.urlSchemes = CoreCustomURLSchemes.instance;
|
||||||
|
|
|
@ -0,0 +1,188 @@
|
||||||
|
// (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 { CoreDB } from '@services/db';
|
||||||
|
import { SQLiteDB, SQLiteDBTableSchema } from '@classes/sqlitedb';
|
||||||
|
|
||||||
|
import { makeSingleton } from '@singletons';
|
||||||
|
import { CoreLogger } from '@singletons/logger';
|
||||||
|
import { DBNAME, SCHEMA_VERSIONS_TABLE_NAME, SCHEMA_VERSIONS_TABLE_SCHEMA, SchemaVersionsDBEntry } from '@services/database/app';
|
||||||
|
import { CoreDatabaseCachingStrategy, CoreDatabaseTableProxy } from '@classes/database/database-table-proxy';
|
||||||
|
import { asyncInstance } from '../utils/async-instance';
|
||||||
|
import { CoreDatabaseTable } from '@classes/database/database-table';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Factory to provide access to the global app database.
|
||||||
|
*
|
||||||
|
* @description
|
||||||
|
* Each service or component should be responsible of creating their own database tables. Example:
|
||||||
|
*
|
||||||
|
* ```ts
|
||||||
|
* CoreAppDB.getDB();
|
||||||
|
* CoreAppDB.createTableFromSchema(this.tableSchema);
|
||||||
|
* ```
|
||||||
|
*/
|
||||||
|
@Injectable({ providedIn: 'root' })
|
||||||
|
export class CoreAppDBService {
|
||||||
|
|
||||||
|
protected db?: SQLiteDB;
|
||||||
|
protected logger: CoreLogger;
|
||||||
|
protected schemaVersionsTable = asyncInstance<CoreDatabaseTable<SchemaVersionsDBEntry, 'name'>>();
|
||||||
|
|
||||||
|
constructor() {
|
||||||
|
this.logger = CoreLogger.getInstance('CoreAppDB');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Initialize database.
|
||||||
|
*/
|
||||||
|
async initializeDatabase(): Promise<void> {
|
||||||
|
const database = this.getDB();
|
||||||
|
|
||||||
|
await database.createTableFromSchema(SCHEMA_VERSIONS_TABLE_SCHEMA);
|
||||||
|
|
||||||
|
const schemaVersionsTable = new CoreDatabaseTableProxy<SchemaVersionsDBEntry, 'name'>(
|
||||||
|
{ cachingStrategy: CoreDatabaseCachingStrategy.Eager },
|
||||||
|
database,
|
||||||
|
SCHEMA_VERSIONS_TABLE_NAME,
|
||||||
|
['name'],
|
||||||
|
);
|
||||||
|
|
||||||
|
await schemaVersionsTable.initialize();
|
||||||
|
|
||||||
|
this.schemaVersionsTable.setInstance(schemaVersionsTable);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Install and upgrade a certain schema.
|
||||||
|
*
|
||||||
|
* @param schema The schema to create.
|
||||||
|
*/
|
||||||
|
async createTablesFromSchema(schema: CoreAppSchema): Promise<void> {
|
||||||
|
this.logger.debug(`Apply schema to app DB: ${schema.name}`);
|
||||||
|
|
||||||
|
try {
|
||||||
|
const oldVersion = await this.getInstalledSchemaVersion(schema);
|
||||||
|
|
||||||
|
if (oldVersion >= schema.version) {
|
||||||
|
// Version already installed, nothing else to do.
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.logger.debug(`Migrating schema '${schema.name}' of app DB from version ${oldVersion} to ${schema.version}`);
|
||||||
|
|
||||||
|
if (schema.tables) {
|
||||||
|
await this.getDB().createTablesFromSchema(schema.tables);
|
||||||
|
}
|
||||||
|
if (schema.install && oldVersion === 0) {
|
||||||
|
await schema.install(this.getDB());
|
||||||
|
}
|
||||||
|
if (schema.migrate && oldVersion > 0) {
|
||||||
|
await schema.migrate(this.getDB(), oldVersion);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set installed version.
|
||||||
|
await this.schemaVersionsTable.insert({ name: schema.name, version: schema.version });
|
||||||
|
} catch (error) {
|
||||||
|
// Only log the error, don't throw it.
|
||||||
|
this.logger.error(`Error applying schema to app DB: ${schema.name}`, error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Delete table schema.
|
||||||
|
*
|
||||||
|
* @param name Schema name.
|
||||||
|
*/
|
||||||
|
async deleteTableSchema(name: string): Promise<void> {
|
||||||
|
await this.schemaVersionsTable.deleteByPrimaryKey({ name });
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the application global database.
|
||||||
|
*
|
||||||
|
* @returns App's DB.
|
||||||
|
*/
|
||||||
|
getDB(): SQLiteDB {
|
||||||
|
if (!this.db) {
|
||||||
|
this.db = CoreDB.getDB(DBNAME);
|
||||||
|
}
|
||||||
|
|
||||||
|
return this.db;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the installed version for the given schema.
|
||||||
|
*
|
||||||
|
* @param schema App schema.
|
||||||
|
* @returns Installed version number, or 0 if the schema is not installed.
|
||||||
|
*/
|
||||||
|
protected async getInstalledSchemaVersion(schema: CoreAppSchema): Promise<number> {
|
||||||
|
try {
|
||||||
|
// Fetch installed version of the schema.
|
||||||
|
const entry = await this.schemaVersionsTable.getOneByPrimaryKey({ name: schema.name });
|
||||||
|
|
||||||
|
return entry.version;
|
||||||
|
} catch {
|
||||||
|
// No installed version yet.
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
export const CoreAppDB = makeSingleton(CoreAppDBService);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* App DB schema and migration function.
|
||||||
|
*/
|
||||||
|
export type CoreAppSchema = {
|
||||||
|
/**
|
||||||
|
* Name of the schema.
|
||||||
|
*/
|
||||||
|
name: string;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Latest version of the schema (integer greater than 0).
|
||||||
|
*/
|
||||||
|
version: number;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tables to create when installing or upgrading the schema.
|
||||||
|
*/
|
||||||
|
tables?: SQLiteDBTableSchema[];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Migrates the schema to the latest version.
|
||||||
|
*
|
||||||
|
* Called when upgrading the schema, after creating the defined tables.
|
||||||
|
*
|
||||||
|
* @param db The affected DB.
|
||||||
|
* @param oldVersion Old version of the schema or 0 if not installed.
|
||||||
|
* @returns Promise resolved when done.
|
||||||
|
*/
|
||||||
|
migrate?(db: SQLiteDB, oldVersion: number): Promise<void>;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Make changes to install the schema.
|
||||||
|
*
|
||||||
|
* Called when installing the schema, after creating the defined tables.
|
||||||
|
*
|
||||||
|
* @param db Site database.
|
||||||
|
* @returns Promise resolved when done.
|
||||||
|
*/
|
||||||
|
install?(db: SQLiteDB): Promise<void> | void;
|
||||||
|
};
|
|
@ -14,62 +14,43 @@
|
||||||
|
|
||||||
import { Injectable } from '@angular/core';
|
import { Injectable } from '@angular/core';
|
||||||
|
|
||||||
import { CoreDB } from '@services/db';
|
import { CoreAppDB, CoreAppSchema } from './app-db';
|
||||||
import { CoreEventObserver, CoreEvents } from '@singletons/events';
|
import { CoreEvents } from '@singletons/events';
|
||||||
import { SQLiteDB, SQLiteDBTableSchema } from '@classes/sqlitedb';
|
import { SQLiteDB } from '@classes/sqlitedb';
|
||||||
|
|
||||||
import { makeSingleton, StatusBar } from '@singletons';
|
import { makeSingleton, StatusBar } from '@singletons';
|
||||||
import { CoreLogger } from '@singletons/logger';
|
import { CoreLogger } from '@singletons/logger';
|
||||||
import { CoreColors } from '@singletons/colors';
|
import { CoreColors } from '@singletons/colors';
|
||||||
import { DBNAME, SCHEMA_VERSIONS_TABLE_NAME, SCHEMA_VERSIONS_TABLE_SCHEMA, SchemaVersionsDBEntry } from '@services/database/app';
|
|
||||||
import { CoreObject } from '@singletons/object';
|
|
||||||
import { CoreRedirectPayload } from './navigator';
|
import { CoreRedirectPayload } from './navigator';
|
||||||
import { CoreDatabaseCachingStrategy, CoreDatabaseTableProxy } from '@classes/database/database-table-proxy';
|
|
||||||
import { asyncInstance } from '../utils/async-instance';
|
|
||||||
import { CoreDatabaseTable } from '@classes/database/database-table';
|
|
||||||
import { CorePromisedValue } from '@classes/promised-value';
|
import { CorePromisedValue } from '@classes/promised-value';
|
||||||
import { Subscription } from 'rxjs';
|
import { Subscription } from 'rxjs';
|
||||||
import { CorePlatform } from '@services/platform';
|
import { CorePlatform } from '@services/platform';
|
||||||
import { CoreKeyboard } from '@singletons/keyboard';
|
import { CoreKeyboard } from '@singletons/keyboard';
|
||||||
import { CoreNetwork } from './network';
|
import { CoreNetwork } from './network';
|
||||||
|
import { CoreSSO } from '@singletons/sso';
|
||||||
|
import { CoreRedirectData, CoreRedirects } from '@singletons/redirects';
|
||||||
import { MAIN_MENU_VISIBILITY_UPDATED_EVENT } from '@features/mainmenu/constants';
|
import { MAIN_MENU_VISIBILITY_UPDATED_EVENT } from '@features/mainmenu/constants';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Factory to provide some global functionalities, like access to the global app database.
|
* Factory to provide some global functionalities.
|
||||||
*
|
|
||||||
* @description
|
|
||||||
* Each service or component should be responsible of creating their own database tables. Example:
|
|
||||||
*
|
|
||||||
* ```ts
|
|
||||||
* constructor(appProvider: CoreAppProvider) {
|
|
||||||
* this.appDB = appProvider.getDB();
|
|
||||||
* this.appDB.createTableFromSchema(this.tableSchema);
|
|
||||||
* }
|
|
||||||
* ```
|
|
||||||
*/
|
*/
|
||||||
@Injectable({ providedIn: 'root' })
|
@Injectable({ providedIn: 'root' })
|
||||||
export class CoreAppProvider {
|
export class CoreAppProvider {
|
||||||
|
|
||||||
protected db?: SQLiteDB;
|
protected logger: CoreLogger = CoreLogger.getInstance('CoreApp');
|
||||||
protected logger: CoreLogger;
|
|
||||||
protected ssoAuthenticationDeferred?: CorePromisedValue<void>;
|
|
||||||
protected redirect?: CoreRedirectData;
|
|
||||||
protected schemaVersionsTable = asyncInstance<CoreDatabaseTable<SchemaVersionsDBEntry, 'name'>>();
|
|
||||||
protected mainMenuListener?: CoreEventObserver;
|
|
||||||
|
|
||||||
constructor() {
|
initialize(): void {
|
||||||
this.logger = CoreLogger.getInstance('CoreAppProvider');
|
if (!CorePlatform.isAndroid()) {
|
||||||
if (CorePlatform.isAndroid()) {
|
return;
|
||||||
this.mainMenuListener =
|
|
||||||
CoreEvents.on(MAIN_MENU_VISIBILITY_UPDATED_EVENT, () => this.setAndroidNavigationBarColor());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
CoreEvents.on(MAIN_MENU_VISIBILITY_UPDATED_EVENT, () => this.setAndroidNavigationBarColor());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns whether the user agent is controlled by automation. I.e. Behat testing.
|
* Returns whether the user agent is controlled by automation. I.e. Behat testing.
|
||||||
*
|
*
|
||||||
* @deprecated since 4.4. Use CorePlatform.isAutomated() instead.
|
|
||||||
* @returns True if the user agent is controlled by automation, false otherwise.
|
* @returns True if the user agent is controlled by automation, false otherwise.
|
||||||
|
* @deprecated since 4.4. Use CorePlatform.isAutomated() instead.
|
||||||
*/
|
*/
|
||||||
static isAutomated(): boolean {
|
static isAutomated(): boolean {
|
||||||
return CorePlatform.isAutomated();
|
return CorePlatform.isAutomated();
|
||||||
|
@ -79,38 +60,18 @@ export class CoreAppProvider {
|
||||||
* Returns the forced timezone to use. Timezone is forced for automated tests.
|
* Returns the forced timezone to use. Timezone is forced for automated tests.
|
||||||
*
|
*
|
||||||
* @returns Timezone. Undefined to use the user's timezone.
|
* @returns Timezone. Undefined to use the user's timezone.
|
||||||
|
* @deprecated since 5.0. Use CoreTime.getForcedTimezone() instead.
|
||||||
*/
|
*/
|
||||||
static getForcedTimezone(): string | undefined {
|
static getForcedTimezone(): string | undefined {
|
||||||
if (CorePlatform.isAutomated()) {
|
|
||||||
// Use the same timezone forced for LMS in tests.
|
// Use the same timezone forced for LMS in tests.
|
||||||
return 'Australia/Perth';
|
return CorePlatform.isAutomated() ? 'Australia/Perth' : undefined;
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Initialize database.
|
|
||||||
*/
|
|
||||||
async initializeDatabase(): Promise<void> {
|
|
||||||
const database = this.getDB();
|
|
||||||
|
|
||||||
await database.createTableFromSchema(SCHEMA_VERSIONS_TABLE_SCHEMA);
|
|
||||||
|
|
||||||
const schemaVersionsTable = new CoreDatabaseTableProxy<SchemaVersionsDBEntry, 'name'>(
|
|
||||||
{ cachingStrategy: CoreDatabaseCachingStrategy.Eager },
|
|
||||||
database,
|
|
||||||
SCHEMA_VERSIONS_TABLE_NAME,
|
|
||||||
['name'],
|
|
||||||
);
|
|
||||||
|
|
||||||
await schemaVersionsTable.initialize();
|
|
||||||
|
|
||||||
this.schemaVersionsTable.setInstance(schemaVersionsTable);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Check if the browser supports mediaDevices.getUserMedia.
|
* Check if the browser supports mediaDevices.getUserMedia.
|
||||||
*
|
*
|
||||||
* @returns Whether the function is supported.
|
* @returns Whether the function is supported.
|
||||||
|
* @deprecated since 5.0. Use CoreMedia.canGetUserMedia() instead.
|
||||||
*/
|
*/
|
||||||
canGetUserMedia(): boolean {
|
canGetUserMedia(): boolean {
|
||||||
return !!(navigator && navigator.mediaDevices && navigator.mediaDevices.getUserMedia);
|
return !!(navigator && navigator.mediaDevices && navigator.mediaDevices.getUserMedia);
|
||||||
|
@ -120,6 +81,7 @@ export class CoreAppProvider {
|
||||||
* Check if the browser supports MediaRecorder.
|
* Check if the browser supports MediaRecorder.
|
||||||
*
|
*
|
||||||
* @returns Whether the function is supported.
|
* @returns Whether the function is supported.
|
||||||
|
* @deprecated since 5.0. Use CoreMedia.canRecordMedia() instead.
|
||||||
*/
|
*/
|
||||||
canRecordMedia(): boolean {
|
canRecordMedia(): boolean {
|
||||||
return !!window.MediaRecorder;
|
return !!window.MediaRecorder;
|
||||||
|
@ -134,60 +96,6 @@ export class CoreAppProvider {
|
||||||
CoreKeyboard.close();
|
CoreKeyboard.close();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Install and upgrade a certain schema.
|
|
||||||
*
|
|
||||||
* @param schema The schema to create.
|
|
||||||
* @returns Promise resolved when done.
|
|
||||||
*/
|
|
||||||
async createTablesFromSchema(schema: CoreAppSchema): Promise<void> {
|
|
||||||
this.logger.debug(`Apply schema to app DB: ${schema.name}`);
|
|
||||||
|
|
||||||
const oldVersion = await this.getInstalledSchemaVersion(schema);
|
|
||||||
|
|
||||||
if (oldVersion >= schema.version) {
|
|
||||||
// Version already installed, nothing else to do.
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
this.logger.debug(`Migrating schema '${schema.name}' of app DB from version ${oldVersion} to ${schema.version}`);
|
|
||||||
|
|
||||||
if (schema.tables) {
|
|
||||||
await this.getDB().createTablesFromSchema(schema.tables);
|
|
||||||
}
|
|
||||||
if (schema.install && oldVersion === 0) {
|
|
||||||
await schema.install(this.getDB());
|
|
||||||
}
|
|
||||||
if (schema.migrate && oldVersion > 0) {
|
|
||||||
await schema.migrate(this.getDB(), oldVersion);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Set installed version.
|
|
||||||
await this.schemaVersionsTable.insert({ name: schema.name, version: schema.version });
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Delete table schema.
|
|
||||||
*
|
|
||||||
* @param name Schema name.
|
|
||||||
*/
|
|
||||||
async deleteTableSchema(name: string): Promise<void> {
|
|
||||||
await this.schemaVersionsTable.deleteByPrimaryKey({ name });
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the application global database.
|
|
||||||
*
|
|
||||||
* @returns App's DB.
|
|
||||||
*/
|
|
||||||
getDB(): SQLiteDB {
|
|
||||||
if (!this.db) {
|
|
||||||
this.db = CoreDB.getDB(DBNAME);
|
|
||||||
}
|
|
||||||
|
|
||||||
return this.db;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get app store URL.
|
* Get app store URL.
|
||||||
*
|
*
|
||||||
|
@ -244,9 +152,11 @@ export class CoreAppProvider {
|
||||||
* Checks if the current window is wider than a mobile.
|
* Checks if the current window is wider than a mobile.
|
||||||
*
|
*
|
||||||
* @returns Whether the app the current window is wider than a mobile.
|
* @returns Whether the app the current window is wider than a mobile.
|
||||||
|
*
|
||||||
|
* @deprecated since 5.0. Use CorePlatform.isWide() instead.
|
||||||
*/
|
*/
|
||||||
isWide(): boolean {
|
isWide(): boolean {
|
||||||
return CorePlatform.width() > 768;
|
return CorePlatform.isWide();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -310,44 +220,40 @@ export class CoreAppProvider {
|
||||||
* Start an SSO authentication process.
|
* Start an SSO authentication process.
|
||||||
* Please notice that this function should be called when the app receives the new token from the browser,
|
* Please notice that this function should be called when the app receives the new token from the browser,
|
||||||
* NOT when the browser is opened.
|
* NOT when the browser is opened.
|
||||||
|
*
|
||||||
|
* @deprecated since 5.0. Use CoreSSO.startSSOAuthentication instead.
|
||||||
*/
|
*/
|
||||||
startSSOAuthentication(): void {
|
startSSOAuthentication(): void {
|
||||||
this.ssoAuthenticationDeferred = new CorePromisedValue();
|
CoreSSO.startSSOAuthentication();
|
||||||
|
|
||||||
// Resolve it automatically after 10 seconds (it should never take that long).
|
|
||||||
const cancelTimeout = setTimeout(() => this.finishSSOAuthentication(), 10000);
|
|
||||||
|
|
||||||
// If the promise is resolved because finishSSOAuthentication is called, stop the cancel promise.
|
|
||||||
// eslint-disable-next-line promise/catch-or-return
|
|
||||||
this.ssoAuthenticationDeferred.then(() => clearTimeout(cancelTimeout));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Finish an SSO authentication process.
|
* Finish an SSO authentication process.
|
||||||
|
*
|
||||||
|
* @deprecated since 5.0. Use CoreSSO.finishSSOAuthentication instead.
|
||||||
*/
|
*/
|
||||||
finishSSOAuthentication(): void {
|
finishSSOAuthentication(): void {
|
||||||
if (this.ssoAuthenticationDeferred) {
|
CoreSSO.finishSSOAuthentication();
|
||||||
this.ssoAuthenticationDeferred.resolve();
|
|
||||||
this.ssoAuthenticationDeferred = undefined;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Check if there's an ongoing SSO authentication process.
|
* Check if there's an ongoing SSO authentication process.
|
||||||
*
|
*
|
||||||
* @returns Whether there's a SSO authentication ongoing.
|
* @returns Whether there's a SSO authentication ongoing.
|
||||||
|
* @deprecated since 5.0. Use CoreSSO.isSSOAuthenticationOngoing instead.
|
||||||
*/
|
*/
|
||||||
isSSOAuthenticationOngoing(): boolean {
|
isSSOAuthenticationOngoing(): boolean {
|
||||||
return !!this.ssoAuthenticationDeferred;
|
return CoreSSO.isSSOAuthenticationOngoing();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns a promise that will be resolved once SSO authentication finishes.
|
* Returns a promise that will be resolved once SSO authentication finishes.
|
||||||
*
|
*
|
||||||
* @returns Promise resolved once SSO authentication finishes.
|
* @returns Promise resolved once SSO authentication finishes.
|
||||||
|
* @deprecated since 5.0. Use CoreSSO.waitForSSOAuthentication instead.
|
||||||
*/
|
*/
|
||||||
async waitForSSOAuthentication(): Promise<void> {
|
async waitForSSOAuthentication(): Promise<void> {
|
||||||
await this.ssoAuthenticationDeferred;
|
return CoreSSO.waitForSSOAuthentication();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -375,55 +281,25 @@ export class CoreAppProvider {
|
||||||
resumeSubscription = CorePlatform.resume.subscribe(stopWaiting);
|
resumeSubscription = CorePlatform.resume.subscribe(stopWaiting);
|
||||||
timeoutId = timeout ? window.setTimeout(stopWaiting, timeout) : null;
|
timeoutId = timeout ? window.setTimeout(stopWaiting, timeout) : null;
|
||||||
|
|
||||||
await deferred;
|
await deferred; }
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Read redirect data from local storage and clear it if it existed.
|
* Read redirect data from local storage and clear it if it existed.
|
||||||
|
*
|
||||||
|
* @deprecated since 5.0. Use CoreRedirects.consumeStorageRedirect instead.
|
||||||
*/
|
*/
|
||||||
consumeStorageRedirect(): void {
|
consumeStorageRedirect(): void {
|
||||||
if (!localStorage?.getItem) {
|
CoreRedirects.consumeStorageRedirect();
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
|
||||||
// Read data from storage.
|
|
||||||
const jsonData = localStorage.getItem('CoreRedirect');
|
|
||||||
|
|
||||||
if (!jsonData) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Clear storage.
|
|
||||||
localStorage.removeItem('CoreRedirect');
|
|
||||||
|
|
||||||
// Remember redirect data.
|
|
||||||
const data: CoreRedirectData = JSON.parse(jsonData);
|
|
||||||
|
|
||||||
if (!CoreObject.isEmpty(data)) {
|
|
||||||
this.redirect = data;
|
|
||||||
}
|
|
||||||
} catch (error) {
|
|
||||||
this.logger.error('Error loading redirect data:', error);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Retrieve and forget redirect data.
|
* Retrieve and forget redirect data.
|
||||||
*
|
*
|
||||||
* @returns Redirect data if any.
|
* @returns Redirect data if any.
|
||||||
|
* @deprecated since 5.0. Use CoreRedirects.consumeMemoryRedirect instead.
|
||||||
*/
|
*/
|
||||||
consumeMemoryRedirect(): CoreRedirectData | null {
|
consumeMemoryRedirect(): CoreRedirectData | null {
|
||||||
const redirect = this.getRedirect();
|
return CoreRedirects.consumeMemoryRedirect();
|
||||||
|
|
||||||
this.forgetRedirect();
|
|
||||||
|
|
||||||
if (redirect && (!redirect.timemodified || Date.now() - redirect.timemodified > 300000)) {
|
|
||||||
// Redirect data is only valid for 5 minutes, discard it.
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
return redirect;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -436,18 +312,21 @@ export class CoreAppProvider {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Forget redirect data.
|
* Forget redirect data.
|
||||||
|
*
|
||||||
|
* @deprecated since 5.0. Use CoreRedirects.forgetRedirect instead.
|
||||||
*/
|
*/
|
||||||
forgetRedirect(): void {
|
forgetRedirect(): void {
|
||||||
delete this.redirect;
|
CoreRedirects.forgetRedirect();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Retrieve redirect data.
|
* Retrieve redirect data.
|
||||||
*
|
*
|
||||||
* @returns Redirect data if any.
|
* @returns Redirect data if any.
|
||||||
|
* @deprecated since 5.0. Use CoreRedirects.getRedirect instead.
|
||||||
*/
|
*/
|
||||||
getRedirect(): CoreRedirectData | null {
|
getRedirect(): CoreRedirectData | null {
|
||||||
return this.redirect || null;
|
return CoreRedirects.getRedirect();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -455,23 +334,11 @@ export class CoreAppProvider {
|
||||||
*
|
*
|
||||||
* @param siteId Site ID.
|
* @param siteId Site ID.
|
||||||
* @param redirectData Redirect data.
|
* @param redirectData Redirect data.
|
||||||
|
*
|
||||||
|
* @deprecated since 5.0. Use CoreRedirects.storeRedirect instead.
|
||||||
*/
|
*/
|
||||||
storeRedirect(siteId: string, redirectData: CoreRedirectPayload = {}): void {
|
storeRedirect(siteId: string, redirectData: CoreRedirectPayload = {}): void {
|
||||||
if (!redirectData.redirectPath && !redirectData.urlToOpen) {
|
CoreRedirects.storeRedirect(siteId, redirectData);
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
|
||||||
const redirect: CoreRedirectData = {
|
|
||||||
siteId,
|
|
||||||
timemodified: Date.now(),
|
|
||||||
...redirectData,
|
|
||||||
};
|
|
||||||
|
|
||||||
localStorage.setItem('CoreRedirect', JSON.stringify(redirect));
|
|
||||||
} catch {
|
|
||||||
// Ignore errors.
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -479,8 +346,7 @@ export class CoreAppProvider {
|
||||||
*/
|
*/
|
||||||
setSystemUIColors(): void {
|
setSystemUIColors(): void {
|
||||||
this.setStatusBarColor();
|
this.setStatusBarColor();
|
||||||
this.setAndroidNavigationBarColor();
|
this.setAndroidNavigationBarColor(); }
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set StatusBar color depending on platform.
|
* Set StatusBar color depending on platform.
|
||||||
|
@ -502,24 +368,6 @@ export class CoreAppProvider {
|
||||||
StatusBar.backgroundColorByHexString(color);
|
StatusBar.backgroundColorByHexString(color);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the installed version for the given schema.
|
|
||||||
*
|
|
||||||
* @param schema App schema.
|
|
||||||
* @returns Installed version number, or 0 if the schema is not installed.
|
|
||||||
*/
|
|
||||||
protected async getInstalledSchemaVersion(schema: CoreAppSchema): Promise<number> {
|
|
||||||
try {
|
|
||||||
// Fetch installed version of the schema.
|
|
||||||
const entry = await this.schemaVersionsTable.getOneByPrimaryKey({ name: schema.name });
|
|
||||||
|
|
||||||
return entry.version;
|
|
||||||
} catch {
|
|
||||||
// No installed version yet.
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set NavigationBar color for Android
|
* Set NavigationBar color for Android
|
||||||
*
|
*
|
||||||
|
@ -541,17 +389,48 @@ export class CoreAppProvider {
|
||||||
(<any> window).StatusBar.navigationBackgroundColorByHexString(color);
|
(<any> window).StatusBar.navigationBackgroundColorByHexString(color);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Initialize database.
|
||||||
|
*
|
||||||
|
* @deprecated since 5.0. Use CoreAppDB.initialize instead.
|
||||||
|
*/
|
||||||
|
async initializeDatabase(): Promise<void> {
|
||||||
|
await CoreAppDB.initializeDatabase();
|
||||||
}
|
}
|
||||||
|
|
||||||
export const CoreApp = makeSingleton(CoreAppProvider);
|
/**
|
||||||
|
* Install and upgrade a certain schema.
|
||||||
|
*
|
||||||
|
* @param schema The schema to create.
|
||||||
|
* @deprecated since 5.0. Use CoreAppDB.createTablesFromSchema instead.
|
||||||
|
*/
|
||||||
|
async createTablesFromSchema(schema: CoreAppSchema): Promise<void> {
|
||||||
|
await CoreAppDB.createTablesFromSchema(schema);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Data stored for a redirect to another page/site.
|
* Delete table schema.
|
||||||
|
*
|
||||||
|
* @param name Schema name.
|
||||||
|
* @deprecated since 5.0. Use CoreAppDB.deleteTableSchema instead.
|
||||||
*/
|
*/
|
||||||
export type CoreRedirectData = CoreRedirectPayload & {
|
async deleteTableSchema(name: string): Promise<void> {
|
||||||
siteId?: string; // ID of the site to load.
|
await CoreAppDB.deleteTableSchema(name);
|
||||||
timemodified?: number; // Timestamp when this redirect was last modified.
|
}
|
||||||
};
|
|
||||||
|
/**
|
||||||
|
* Get the application global database.
|
||||||
|
*
|
||||||
|
* @returns App's DB.
|
||||||
|
* @deprecated since 5.0. Use CoreAppDB.getDB instead.
|
||||||
|
*/
|
||||||
|
getDB(): SQLiteDB {
|
||||||
|
return CoreAppDB.getDB();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
export const CoreApp = makeSingleton(CoreAppProvider);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Store config data.
|
* Store config data.
|
||||||
|
@ -577,44 +456,3 @@ export type CoreStoreConfig = {
|
||||||
*/
|
*/
|
||||||
default?: string;
|
default?: string;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
|
||||||
* App DB schema and migration function.
|
|
||||||
*/
|
|
||||||
export type CoreAppSchema = {
|
|
||||||
/**
|
|
||||||
* Name of the schema.
|
|
||||||
*/
|
|
||||||
name: string;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Latest version of the schema (integer greater than 0).
|
|
||||||
*/
|
|
||||||
version: number;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Tables to create when installing or upgrading the schema.
|
|
||||||
*/
|
|
||||||
tables?: SQLiteDBTableSchema[];
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Migrates the schema to the latest version.
|
|
||||||
*
|
|
||||||
* Called when upgrading the schema, after creating the defined tables.
|
|
||||||
*
|
|
||||||
* @param db The affected DB.
|
|
||||||
* @param oldVersion Old version of the schema or 0 if not installed.
|
|
||||||
* @returns Promise resolved when done.
|
|
||||||
*/
|
|
||||||
migrate?(db: SQLiteDB, oldVersion: number): Promise<void>;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Make changes to install the schema.
|
|
||||||
*
|
|
||||||
* Called when installing the schema, after creating the defined tables.
|
|
||||||
*
|
|
||||||
* @param db Site database.
|
|
||||||
* @returns Promise resolved when done.
|
|
||||||
*/
|
|
||||||
install?(db: SQLiteDB): Promise<void> | void;
|
|
||||||
};
|
|
||||||
|
|
|
@ -15,7 +15,7 @@
|
||||||
import { EnvironmentConfig } from '@/types/config';
|
import { EnvironmentConfig } from '@/types/config';
|
||||||
import { Injectable } from '@angular/core';
|
import { Injectable } from '@angular/core';
|
||||||
import { CoreDatabaseCachingStrategy, CoreDatabaseTableProxy } from '@classes/database/database-table-proxy';
|
import { CoreDatabaseCachingStrategy, CoreDatabaseTableProxy } from '@classes/database/database-table-proxy';
|
||||||
import { CoreApp } from '@services/app';
|
import { CoreAppDB } from './app-db';
|
||||||
import { APP_SCHEMA, ConfigDBEntry, CONFIG_TABLE_NAME } from '@services/database/config';
|
import { APP_SCHEMA, ConfigDBEntry, CONFIG_TABLE_NAME } from '@services/database/config';
|
||||||
import { makeSingleton } from '@singletons';
|
import { makeSingleton } from '@singletons';
|
||||||
import { CoreConstants } from '../constants';
|
import { CoreConstants } from '../constants';
|
||||||
|
@ -73,15 +73,11 @@ export class CoreConfigProvider {
|
||||||
* Initialize database.
|
* Initialize database.
|
||||||
*/
|
*/
|
||||||
async initializeDatabase(): Promise<void> {
|
async initializeDatabase(): Promise<void> {
|
||||||
try {
|
await CoreAppDB.createTablesFromSchema(APP_SCHEMA);
|
||||||
await CoreApp.createTablesFromSchema(APP_SCHEMA);
|
|
||||||
} catch {
|
|
||||||
// Ignore errors.
|
|
||||||
}
|
|
||||||
|
|
||||||
const table = new CoreDatabaseTableProxy<ConfigDBEntry, 'name'>(
|
const table = new CoreDatabaseTableProxy<ConfigDBEntry, 'name'>(
|
||||||
{ cachingStrategy: CoreDatabaseCachingStrategy.Eager },
|
{ cachingStrategy: CoreDatabaseCachingStrategy.Eager },
|
||||||
CoreApp.getDB(),
|
CoreAppDB.getDB(),
|
||||||
CONFIG_TABLE_NAME,
|
CONFIG_TABLE_NAME,
|
||||||
['name'],
|
['name'],
|
||||||
);
|
);
|
||||||
|
@ -129,7 +125,7 @@ export class CoreConfigProvider {
|
||||||
* @returns Resolves upon success along with the config data. Reject on failure.
|
* @returns Resolves upon success along with the config data. Reject on failure.
|
||||||
*/
|
*/
|
||||||
async getFromDB<T>(name: string): Promise<T> {
|
async getFromDB<T>(name: string): Promise<T> {
|
||||||
const db = CoreApp.getDB();
|
const db = CoreAppDB.getDB();
|
||||||
const record = await db.getRecord<ConfigDBEntry>(CONFIG_TABLE_NAME, { name });
|
const record = await db.getRecord<ConfigDBEntry>(CONFIG_TABLE_NAME, { name });
|
||||||
|
|
||||||
return record.value;
|
return record.value;
|
||||||
|
|
|
@ -14,7 +14,7 @@
|
||||||
|
|
||||||
import { Injectable } from '@angular/core';
|
import { Injectable } from '@angular/core';
|
||||||
|
|
||||||
import { CoreApp } from '@services/app';
|
import { CoreAppDB } from '@services/app-db';
|
||||||
import { CoreNetwork } from '@services/network';
|
import { CoreNetwork } from '@services/network';
|
||||||
import { CoreConfig } from '@services/config';
|
import { CoreConfig } from '@services/config';
|
||||||
import { CoreUtils } from '@services/utils/utils';
|
import { CoreUtils } from '@services/utils/utils';
|
||||||
|
@ -52,15 +52,11 @@ export class CoreCronDelegateService {
|
||||||
* Initialize database.
|
* Initialize database.
|
||||||
*/
|
*/
|
||||||
async initializeDatabase(): Promise<void> {
|
async initializeDatabase(): Promise<void> {
|
||||||
try {
|
await CoreAppDB.createTablesFromSchema(APP_SCHEMA);
|
||||||
await CoreApp.createTablesFromSchema(APP_SCHEMA);
|
|
||||||
} catch {
|
|
||||||
// Ignore errors.
|
|
||||||
}
|
|
||||||
|
|
||||||
const table = new CoreDatabaseTableProxy<CronDBEntry>(
|
const table = new CoreDatabaseTableProxy<CronDBEntry>(
|
||||||
{ cachingStrategy: CoreDatabaseCachingStrategy.Eager },
|
{ cachingStrategy: CoreDatabaseCachingStrategy.Eager },
|
||||||
CoreApp.getDB(),
|
CoreAppDB.getDB(),
|
||||||
CRON_TABLE_NAME,
|
CRON_TABLE_NAME,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
|
@ -12,7 +12,7 @@
|
||||||
// See the License for the specific language governing permissions and
|
// See the License for the specific language governing permissions and
|
||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
|
|
||||||
import { CoreAppSchema } from '@services/app';
|
import { CoreAppSchema } from '@services/app-db';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Database variables for for CoreConfig service.
|
* Database variables for for CoreConfig service.
|
||||||
|
|
|
@ -12,7 +12,7 @@
|
||||||
// See the License for the specific language governing permissions and
|
// See the License for the specific language governing permissions and
|
||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
|
|
||||||
import { CoreAppSchema } from '@services/app';
|
import { CoreAppSchema } from '@services/app-db';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Database variables for CoreCron service.
|
* Database variables for CoreCron service.
|
||||||
|
|
|
@ -13,7 +13,7 @@
|
||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
|
|
||||||
import { DownloadStatus } from '@/core/constants';
|
import { DownloadStatus } from '@/core/constants';
|
||||||
import { CoreAppSchema } from '@services/app';
|
import { CoreAppSchema } from '@services/app-db';
|
||||||
import { CoreSiteSchema } from '@services/sites';
|
import { CoreSiteSchema } from '@services/sites';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -13,7 +13,7 @@
|
||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
|
|
||||||
import { CorePromisedValue } from '@classes/promised-value';
|
import { CorePromisedValue } from '@classes/promised-value';
|
||||||
import { CoreAppSchema } from '@services/app';
|
import { CoreAppSchema } from '@services/app-db';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Database variables for CoreLocalNotifications service.
|
* Database variables for CoreLocalNotifications service.
|
||||||
|
|
|
@ -12,7 +12,7 @@
|
||||||
// See the License for the specific language governing permissions and
|
// See the License for the specific language governing permissions and
|
||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
|
|
||||||
import { CoreAppSchema } from '@services/app';
|
import { CoreAppSchema } from '@services/app-db';
|
||||||
import { CoreSiteSchema } from '@services/sites';
|
import { CoreSiteSchema } from '@services/sites';
|
||||||
import { SQLiteDB, SQLiteDBTableSchema } from '@classes/sqlitedb';
|
import { SQLiteDB, SQLiteDBTableSchema } from '@classes/sqlitedb';
|
||||||
|
|
||||||
|
|
|
@ -13,7 +13,7 @@
|
||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
|
|
||||||
import { SQLiteDBTableSchema } from '@classes/sqlitedb';
|
import { SQLiteDBTableSchema } from '@classes/sqlitedb';
|
||||||
import { CoreAppSchema } from '@services/app';
|
import { CoreAppSchema } from '@services/app-db';
|
||||||
import { CoreSiteSchema } from '@services/sites';
|
import { CoreSiteSchema } from '@services/sites';
|
||||||
|
|
||||||
export const TABLE_NAME = 'core_storage';
|
export const TABLE_NAME = 'core_storage';
|
||||||
|
|
|
@ -15,7 +15,7 @@
|
||||||
import { Injectable } from '@angular/core';
|
import { Injectable } from '@angular/core';
|
||||||
import { Md5 } from 'ts-md5/dist/md5';
|
import { Md5 } from 'ts-md5/dist/md5';
|
||||||
|
|
||||||
import { CoreApp } from '@services/app';
|
import { CoreAppDB } from '@services/app-db';
|
||||||
import { CoreNetwork } from '@services/network';
|
import { CoreNetwork } from '@services/network';
|
||||||
import { CoreEventPackageStatusChanged, CoreEvents } from '@singletons/events';
|
import { CoreEventPackageStatusChanged, CoreEvents } from '@singletons/events';
|
||||||
import { CoreFile } from '@services/file';
|
import { CoreFile } from '@services/file';
|
||||||
|
@ -175,15 +175,11 @@ export class CoreFilepoolProvider {
|
||||||
* Initialize database.
|
* Initialize database.
|
||||||
*/
|
*/
|
||||||
async initializeDatabase(): Promise<void> {
|
async initializeDatabase(): Promise<void> {
|
||||||
try {
|
await CoreAppDB.createTablesFromSchema(APP_SCHEMA);
|
||||||
await CoreApp.createTablesFromSchema(APP_SCHEMA);
|
|
||||||
} catch (e) {
|
|
||||||
// Ignore errors.
|
|
||||||
}
|
|
||||||
|
|
||||||
const queueTable = new CoreDatabaseTableProxy<CoreFilepoolQueueDBRecord, CoreFilepoolQueueDBPrimaryKeys>(
|
const queueTable = new CoreDatabaseTableProxy<CoreFilepoolQueueDBRecord, CoreFilepoolQueueDBPrimaryKeys>(
|
||||||
{ cachingStrategy: CoreDatabaseCachingStrategy.Lazy },
|
{ cachingStrategy: CoreDatabaseCachingStrategy.Lazy },
|
||||||
CoreApp.getDB(),
|
CoreAppDB.getDB(),
|
||||||
QUEUE_TABLE_NAME,
|
QUEUE_TABLE_NAME,
|
||||||
[...QUEUE_TABLE_PRIMARY_KEYS],
|
[...QUEUE_TABLE_PRIMARY_KEYS],
|
||||||
);
|
);
|
||||||
|
|
|
@ -16,7 +16,7 @@ import { Injectable } from '@angular/core';
|
||||||
import { Subject, Subscription } from 'rxjs';
|
import { Subject, Subscription } from 'rxjs';
|
||||||
import { ILocalNotification } from '@awesome-cordova-plugins/local-notifications';
|
import { ILocalNotification } from '@awesome-cordova-plugins/local-notifications';
|
||||||
|
|
||||||
import { CoreApp } from '@services/app';
|
import { CoreAppDB } from '@services/app-db';
|
||||||
import { CoreConfig } from '@services/config';
|
import { CoreConfig } from '@services/config';
|
||||||
import { CoreEventObserver, CoreEvents } from '@singletons/events';
|
import { CoreEventObserver, CoreEvents } from '@singletons/events';
|
||||||
import { CoreText } from '@singletons/text';
|
import { CoreText } from '@singletons/text';
|
||||||
|
@ -185,13 +185,9 @@ export class CoreLocalNotificationsProvider {
|
||||||
* Initialize database.
|
* Initialize database.
|
||||||
*/
|
*/
|
||||||
async initializeDatabase(): Promise<void> {
|
async initializeDatabase(): Promise<void> {
|
||||||
try {
|
await CoreAppDB.createTablesFromSchema(APP_SCHEMA);
|
||||||
await CoreApp.createTablesFromSchema(APP_SCHEMA);
|
|
||||||
} catch {
|
|
||||||
// Ignore errors.
|
|
||||||
}
|
|
||||||
|
|
||||||
const database = CoreApp.getDB();
|
const database = CoreAppDB.getDB();
|
||||||
const sitesTable = new CoreDatabaseTableProxy<CoreLocalNotificationsSitesDBRecord, 'id', never>(
|
const sitesTable = new CoreDatabaseTableProxy<CoreLocalNotificationsSitesDBRecord, 'id', never>(
|
||||||
{ cachingStrategy: CoreDatabaseCachingStrategy.None },
|
{ cachingStrategy: CoreDatabaseCachingStrategy.None },
|
||||||
database,
|
database,
|
||||||
|
|
|
@ -91,6 +91,15 @@ export class CorePlatformService extends Platform {
|
||||||
return this.is('cordova');
|
return this.is('cordova');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks if the current window is wider than a mobile.
|
||||||
|
*
|
||||||
|
* @returns Whether the app the current window is wider than a mobile.
|
||||||
|
*/
|
||||||
|
isWide(): boolean {
|
||||||
|
return this.width() > 768;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Check whether the device is configured to reduce motion.
|
* Check whether the device is configured to reduce motion.
|
||||||
*
|
*
|
||||||
|
|
|
@ -68,6 +68,8 @@ import { CoreHTMLClasses } from '@singletons/html-classes';
|
||||||
import { CoreSiteErrorDebug } from '@classes/errors/siteerror';
|
import { CoreSiteErrorDebug } from '@classes/errors/siteerror';
|
||||||
import { CoreErrorHelper } from './error-helper';
|
import { CoreErrorHelper } from './error-helper';
|
||||||
import { CoreQueueRunner } from '@classes/queue-runner';
|
import { CoreQueueRunner } from '@classes/queue-runner';
|
||||||
|
import { CoreAppDB } from './app-db';
|
||||||
|
import { CoreRedirects } from '@singletons/redirects';
|
||||||
|
|
||||||
export const CORE_SITE_SCHEMAS = new InjectionToken<CoreSiteSchema[]>('CORE_SITE_SCHEMAS');
|
export const CORE_SITE_SCHEMAS = new InjectionToken<CoreSiteSchema[]>('CORE_SITE_SCHEMAS');
|
||||||
export const CORE_SITE_CURRENT_SITE_ID_CONFIG = 'current_site_id';
|
export const CORE_SITE_CURRENT_SITE_ID_CONFIG = 'current_site_id';
|
||||||
|
@ -201,15 +203,11 @@ export class CoreSitesProvider {
|
||||||
* Initialize database.
|
* Initialize database.
|
||||||
*/
|
*/
|
||||||
async initializeDatabase(): Promise<void> {
|
async initializeDatabase(): Promise<void> {
|
||||||
try {
|
await CoreAppDB.createTablesFromSchema(APP_SCHEMA);
|
||||||
await CoreApp.createTablesFromSchema(APP_SCHEMA);
|
|
||||||
} catch {
|
|
||||||
// Ignore errors.
|
|
||||||
}
|
|
||||||
|
|
||||||
const sitesTable = new CoreDatabaseTableProxy<SiteDBEntry>(
|
const sitesTable = new CoreDatabaseTableProxy<SiteDBEntry>(
|
||||||
{ cachingStrategy: CoreDatabaseCachingStrategy.Eager },
|
{ cachingStrategy: CoreDatabaseCachingStrategy.Eager },
|
||||||
CoreApp.getDB(),
|
CoreAppDB.getDB(),
|
||||||
SITES_TABLE_NAME,
|
SITES_TABLE_NAME,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -1198,7 +1196,7 @@ export class CoreSitesProvider {
|
||||||
* @returns Site.
|
* @returns Site.
|
||||||
*/
|
*/
|
||||||
async getSiteFromDB(siteId: string): Promise<CoreSite> {
|
async getSiteFromDB(siteId: string): Promise<CoreSite> {
|
||||||
const db = CoreApp.getDB();
|
const db = CoreAppDB.getDB();
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const record = await db.getRecord<SiteDBEntry>(SITES_TABLE_NAME, { id: siteId });
|
const record = await db.getRecord<SiteDBEntry>(SITES_TABLE_NAME, { id: siteId });
|
||||||
|
@ -1500,7 +1498,7 @@ export class CoreSitesProvider {
|
||||||
|
|
||||||
if (CoreSitePlugins.hasSitePluginsLoaded) {
|
if (CoreSitePlugins.hasSitePluginsLoaded) {
|
||||||
// The site has site plugins so the app will be restarted. Store the data and logout.
|
// The site has site plugins so the app will be restarted. Store the data and logout.
|
||||||
CoreApp.storeRedirect(siteId, redirectData);
|
CoreRedirects.storeRedirect(siteId, redirectData);
|
||||||
}
|
}
|
||||||
|
|
||||||
await this.logout();
|
await this.logout();
|
||||||
|
@ -2052,12 +2050,12 @@ export class CoreSitesProvider {
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const db = CoreApp.getDB();
|
const db = CoreAppDB.getDB();
|
||||||
|
|
||||||
const { siteId } = await db.getRecord<{ siteId: string }>('current_site');
|
const { siteId } = await db.getRecord<{ siteId: string }>('current_site');
|
||||||
|
|
||||||
await CoreConfig.set(CORE_SITE_CURRENT_SITE_ID_CONFIG, siteId);
|
await CoreConfig.set(CORE_SITE_CURRENT_SITE_ID_CONFIG, siteId);
|
||||||
await CoreApp.deleteTableSchema('current_site');
|
await CoreAppDB.deleteTableSchema('current_site');
|
||||||
await db.dropTable('current_site');
|
await db.dropTable('current_site');
|
||||||
} catch {
|
} catch {
|
||||||
// There was no current site, silence the error.
|
// There was no current site, silence the error.
|
||||||
|
|
|
@ -15,7 +15,7 @@
|
||||||
import { Inject, Injectable, Optional } from '@angular/core';
|
import { Inject, Injectable, Optional } from '@angular/core';
|
||||||
|
|
||||||
import { AsyncInstance, asyncInstance } from '@/core/utils/async-instance';
|
import { AsyncInstance, asyncInstance } from '@/core/utils/async-instance';
|
||||||
import { CoreApp } from '@services/app';
|
import { CoreAppDB } from './app-db';
|
||||||
import { CoreDatabaseCachingStrategy, CoreDatabaseTableProxy } from '@classes/database/database-table-proxy';
|
import { CoreDatabaseCachingStrategy, CoreDatabaseTableProxy } from '@classes/database/database-table-proxy';
|
||||||
import { CoreDatabaseTable } from '@classes/database/database-table';
|
import { CoreDatabaseTable } from '@classes/database/database-table';
|
||||||
import { makeSingleton } from '@singletons';
|
import { makeSingleton } from '@singletons';
|
||||||
|
@ -32,7 +32,7 @@ import { NULL_INJECTION_TOKEN } from '@/core/constants';
|
||||||
* The data can be scoped to a single site using CoreStorage.forSite(site), and it will be automatically cleared
|
* The data can be scoped to a single site using CoreStorage.forSite(site), and it will be automatically cleared
|
||||||
* when the site is deleted.
|
* when the site is deleted.
|
||||||
*
|
*
|
||||||
* For tabular data, use CoreAppProvider.getDB() or CoreSite.getDb().
|
* For tabular data, use CoreAppDB.getDB() or CoreSite.getDb().
|
||||||
*/
|
*/
|
||||||
@Injectable({ providedIn: 'root' })
|
@Injectable({ providedIn: 'root' })
|
||||||
export class CoreStorageService {
|
export class CoreStorageService {
|
||||||
|
@ -47,13 +47,9 @@ export class CoreStorageService {
|
||||||
* Initialize database.
|
* Initialize database.
|
||||||
*/
|
*/
|
||||||
async initializeDatabase(): Promise<void> {
|
async initializeDatabase(): Promise<void> {
|
||||||
try {
|
await CoreAppDB.createTablesFromSchema(APP_SCHEMA);
|
||||||
await CoreApp.createTablesFromSchema(APP_SCHEMA);
|
|
||||||
} catch {
|
|
||||||
// Ignore errors.
|
|
||||||
}
|
|
||||||
|
|
||||||
await this.initializeTable(CoreApp.getDB());
|
await this.initializeTable(CoreAppDB.getDB());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -97,7 +93,7 @@ export class CoreStorageService {
|
||||||
async getFromDB<T>(key: string, defaultValue: T): Promise<T>;
|
async getFromDB<T>(key: string, defaultValue: T): Promise<T>;
|
||||||
async getFromDB<T=unknown>(key: string, defaultValue: T | null = null): Promise<T | null> {
|
async getFromDB<T=unknown>(key: string, defaultValue: T | null = null): Promise<T | null> {
|
||||||
try {
|
try {
|
||||||
const db = CoreApp.getDB();
|
const db = CoreAppDB.getDB();
|
||||||
const { value } = await db.getRecord<CoreStorageRecord>(TABLE_NAME, { key });
|
const { value } = await db.getRecord<CoreStorageRecord>(TABLE_NAME, { key });
|
||||||
|
|
||||||
return JSON.parse(value);
|
return JSON.parse(value);
|
||||||
|
|
|
@ -22,7 +22,7 @@ import { CoreH5P } from '@features/h5p/services/h5p';
|
||||||
import { CoreLoginHelper } from '@features/login/services/login-helper';
|
import { CoreLoginHelper } from '@features/login/services/login-helper';
|
||||||
import { CoreSites } from './sites';
|
import { CoreSites } from './sites';
|
||||||
import { CoreUtils } from './utils/utils';
|
import { CoreUtils } from './utils/utils';
|
||||||
import { CoreApp } from './app';
|
import { CoreRedirects } from '@singletons/redirects';
|
||||||
import { CoreZoomLevel } from '@features/settings/services/settings-helper';
|
import { CoreZoomLevel } from '@features/settings/services/settings-helper';
|
||||||
import { CorePromisedValue } from '@classes/promised-value';
|
import { CorePromisedValue } from '@classes/promised-value';
|
||||||
import { CoreFile } from './file';
|
import { CoreFile } from './file';
|
||||||
|
@ -138,7 +138,7 @@ export class CoreUpdateManagerProvider {
|
||||||
await CoreSites.removeStoredCurrentSite();
|
await CoreSites.removeStoredCurrentSite();
|
||||||
|
|
||||||
// Tell the app to open add site so the user can add the new site.
|
// Tell the app to open add site so the user can add the new site.
|
||||||
CoreApp.storeRedirect(CoreConstants.NO_SITE_ID, {
|
CoreRedirects.storeRedirect(CoreConstants.NO_SITE_ID, {
|
||||||
redirectPath: '/login/sites',
|
redirectPath: '/login/sites',
|
||||||
redirectOptions: {
|
redirectOptions: {
|
||||||
params: {
|
params: {
|
||||||
|
|
|
@ -23,7 +23,7 @@ import { ApplicationInit, makeSingleton, Translate } from '@singletons';
|
||||||
import { CoreLogger } from '@singletons/logger';
|
import { CoreLogger } from '@singletons/logger';
|
||||||
import { CorePath } from '@singletons/path';
|
import { CorePath } from '@singletons/path';
|
||||||
import { CoreConstants } from '../constants';
|
import { CoreConstants } from '../constants';
|
||||||
import { CoreApp } from './app';
|
import { CoreSSO } from '@singletons/sso';
|
||||||
import { CoreNavigator, CoreRedirectPayload } from './navigator';
|
import { CoreNavigator, CoreRedirectPayload } from './navigator';
|
||||||
import { CoreSiteCheckResponse, CoreSites } from './sites';
|
import { CoreSiteCheckResponse, CoreSites } from './sites';
|
||||||
import { CoreDomUtils } from './utils/dom';
|
import { CoreDomUtils } from './utils/dom';
|
||||||
|
@ -217,7 +217,7 @@ export class CoreCustomURLSchemesProvider {
|
||||||
modal.dismiss();
|
modal.dismiss();
|
||||||
|
|
||||||
if (data.isSSOToken) {
|
if (data.isSSOToken) {
|
||||||
CoreApp.finishSSOAuthentication();
|
CoreSSO.finishSSOAuthentication();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -349,13 +349,13 @@ export class CoreCustomURLSchemesProvider {
|
||||||
throw new CoreCustomURLSchemesHandleError(null);
|
throw new CoreCustomURLSchemesHandleError(null);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (CoreApp.isSSOAuthenticationOngoing()) {
|
if (CoreSSO.isSSOAuthenticationOngoing()) {
|
||||||
// Authentication ongoing, probably duplicated request.
|
// Authentication ongoing, probably duplicated request.
|
||||||
throw new CoreCustomURLSchemesHandleError('Duplicated');
|
throw new CoreCustomURLSchemesHandleError('Duplicated');
|
||||||
}
|
}
|
||||||
|
|
||||||
// App opened using custom URL scheme. Probably an SSO authentication.
|
// App opened using custom URL scheme. Probably an SSO authentication.
|
||||||
CoreApp.startSSOAuthentication();
|
CoreSSO.startSSOAuthentication();
|
||||||
this.logger.debug('App launched by URL with an SSO');
|
this.logger.debug('App launched by URL with an SSO');
|
||||||
|
|
||||||
// Delete the sso scheme from the URL.
|
// Delete the sso scheme from the URL.
|
||||||
|
|
|
@ -93,6 +93,24 @@ export class CoreMedia {
|
||||||
return sources.some(source => CoreMedia.sourceUsesJavascriptPlayer(source));
|
return sources.some(source => CoreMedia.sourceUsesJavascriptPlayer(source));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check if the browser supports mediaDevices.getUserMedia.
|
||||||
|
*
|
||||||
|
* @returns Whether the function is supported.
|
||||||
|
*/
|
||||||
|
static canGetUserMedia(): boolean {
|
||||||
|
return !!(navigator && navigator.mediaDevices && navigator.mediaDevices.getUserMedia);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check if the browser supports MediaRecorder.
|
||||||
|
*
|
||||||
|
* @returns Whether the function is supported.
|
||||||
|
*/
|
||||||
|
static canRecordMedia(): boolean {
|
||||||
|
return !!window.MediaRecorder;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -0,0 +1,130 @@
|
||||||
|
// (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 { CoreRedirectPayload } from '@services/navigator';
|
||||||
|
import { CoreLogger } from './logger';
|
||||||
|
import { CoreObject } from './object';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Singleton with helper functions to manage redirects.
|
||||||
|
*
|
||||||
|
* This singleton is not necessary to be exported for site plugins.
|
||||||
|
*/
|
||||||
|
export class CoreRedirects {
|
||||||
|
|
||||||
|
private static redirect?: CoreRedirectData;
|
||||||
|
protected static logger = CoreLogger.getInstance('CoreRedirects');
|
||||||
|
|
||||||
|
// Avoid creating singleton instances.
|
||||||
|
private constructor() {
|
||||||
|
// Nothing to do.
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Read redirect data from local storage and clear it if it existed.
|
||||||
|
*/
|
||||||
|
static consumeStorageRedirect(): void {
|
||||||
|
if (!localStorage?.getItem) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
// Read data from storage.
|
||||||
|
const jsonData = localStorage.getItem('CoreRedirect');
|
||||||
|
|
||||||
|
if (!jsonData) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Clear storage.
|
||||||
|
localStorage.removeItem('CoreRedirect');
|
||||||
|
|
||||||
|
// Remember redirect data.
|
||||||
|
const data: CoreRedirectData = JSON.parse(jsonData);
|
||||||
|
|
||||||
|
if (!CoreObject.isEmpty(data)) {
|
||||||
|
CoreRedirects.redirect = data;
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
CoreRedirects.logger.error('Error loading redirect data:', error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieve and forget redirect data.
|
||||||
|
*
|
||||||
|
* @returns Redirect data if any.
|
||||||
|
*/
|
||||||
|
static consumeMemoryRedirect(): CoreRedirectData | null {
|
||||||
|
const redirect = CoreRedirects.getRedirect();
|
||||||
|
|
||||||
|
CoreRedirects.forgetRedirect();
|
||||||
|
|
||||||
|
if (redirect && (!redirect.timemodified || Date.now() - redirect.timemodified > 300000)) {
|
||||||
|
// Redirect data is only valid for 5 minutes, discard it.
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return redirect;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Forget redirect data.
|
||||||
|
*/
|
||||||
|
static forgetRedirect(): void {
|
||||||
|
delete CoreRedirects.redirect;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieve redirect data.
|
||||||
|
*
|
||||||
|
* @returns Redirect data if any.
|
||||||
|
*/
|
||||||
|
static getRedirect(): CoreRedirectData | null {
|
||||||
|
return CoreRedirects.redirect || null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Store redirect params.
|
||||||
|
*
|
||||||
|
* @param siteId Site ID.
|
||||||
|
* @param redirectData Redirect data.
|
||||||
|
*/
|
||||||
|
static storeRedirect(siteId: string, redirectData: CoreRedirectPayload = {}): void {
|
||||||
|
if (!redirectData.redirectPath && !redirectData.urlToOpen) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
const redirect: CoreRedirectData = {
|
||||||
|
siteId,
|
||||||
|
timemodified: Date.now(),
|
||||||
|
...redirectData,
|
||||||
|
};
|
||||||
|
|
||||||
|
localStorage.setItem('CoreRedirect', JSON.stringify(redirect));
|
||||||
|
} catch {
|
||||||
|
// Ignore errors.
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Data stored for a redirect to another page/site.
|
||||||
|
*/
|
||||||
|
export type CoreRedirectData = CoreRedirectPayload & {
|
||||||
|
siteId?: string; // ID of the site to load.
|
||||||
|
timemodified?: number; // Timestamp when this redirect was last modified.
|
||||||
|
};
|
|
@ -0,0 +1,75 @@
|
||||||
|
// (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 { CorePromisedValue } from '@classes/promised-value';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Singleton with helper functions for Single Sign On.
|
||||||
|
*/
|
||||||
|
export class CoreSSO {
|
||||||
|
|
||||||
|
private static ssoAuthenticationDeferred?: CorePromisedValue<void>;
|
||||||
|
|
||||||
|
// Avoid creating singleton instances.
|
||||||
|
private constructor() {
|
||||||
|
// Nothing to do.
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Start an SSO authentication process.
|
||||||
|
* Please notice that this function should be called when the app receives the new token from the browser,
|
||||||
|
* NOT when the browser is opened.
|
||||||
|
*/
|
||||||
|
static startSSOAuthentication(): void {
|
||||||
|
CoreSSO.ssoAuthenticationDeferred = new CorePromisedValue();
|
||||||
|
|
||||||
|
// Resolve it automatically after 10 seconds (it should never take that long).
|
||||||
|
const cancelTimeout = setTimeout(() => CoreSSO.finishSSOAuthentication(), 10000);
|
||||||
|
|
||||||
|
// If the promise is resolved because finishSSOAuthentication is called, stop the cancel promise.
|
||||||
|
// eslint-disable-next-line promise/catch-or-return
|
||||||
|
CoreSSO.ssoAuthenticationDeferred.then(() => clearTimeout(cancelTimeout));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Finish an SSO authentication process.
|
||||||
|
*/
|
||||||
|
static finishSSOAuthentication(): void {
|
||||||
|
if (!CoreSSO.ssoAuthenticationDeferred) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
CoreSSO.ssoAuthenticationDeferred.resolve();
|
||||||
|
CoreSSO.ssoAuthenticationDeferred = undefined;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check if there's an ongoing SSO authentication process.
|
||||||
|
*
|
||||||
|
* @returns Whether there's a SSO authentication ongoing.
|
||||||
|
*/
|
||||||
|
static isSSOAuthenticationOngoing(): boolean {
|
||||||
|
return !!CoreSSO.ssoAuthenticationDeferred;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns a promise that will be resolved once SSO authentication finishes.
|
||||||
|
*
|
||||||
|
* @returns Promise resolved once SSO authentication finishes.
|
||||||
|
*/
|
||||||
|
static async waitForSSOAuthentication(): Promise<void> {
|
||||||
|
await CoreSSO.ssoAuthenticationDeferred;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -14,12 +14,70 @@
|
||||||
|
|
||||||
import { Translate } from '@singletons';
|
import { Translate } from '@singletons';
|
||||||
import { CoreConstants } from '../constants';
|
import { CoreConstants } from '../constants';
|
||||||
|
import { CorePlatform } from '@services/platform';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Singleton with helper functions for time operations.
|
* Singleton with helper functions for time operations.
|
||||||
*/
|
*/
|
||||||
export class CoreTime {
|
export class CoreTime {
|
||||||
|
|
||||||
|
protected static readonly LEGACY_TIMEZONES = {
|
||||||
|
'-13.0': 'Australia/Perth',
|
||||||
|
'-12.5': 'Etc/GMT+12',
|
||||||
|
'-12.0': 'Etc/GMT+12',
|
||||||
|
'-11.5': 'Etc/GMT+11',
|
||||||
|
'-11.0': 'Etc/GMT+11',
|
||||||
|
'-10.5': 'Etc/GMT+10',
|
||||||
|
'-10.0': 'Etc/GMT+10',
|
||||||
|
'-9.5': 'Etc/GMT+9',
|
||||||
|
'-9.0': 'Etc/GMT+9',
|
||||||
|
'-8.5': 'Etc/GMT+8',
|
||||||
|
'-8.0': 'Etc/GMT+8',
|
||||||
|
'-7.5': 'Etc/GMT+7',
|
||||||
|
'-7.0': 'Etc/GMT+7',
|
||||||
|
'-6.5': 'Etc/GMT+6',
|
||||||
|
'-6.0': 'Etc/GMT+6',
|
||||||
|
'-5.5': 'Etc/GMT+5',
|
||||||
|
'-5.0': 'Etc/GMT+5',
|
||||||
|
'-4.5': 'Etc/GMT+4',
|
||||||
|
'-4.0': 'Etc/GMT+4',
|
||||||
|
'-3.5': 'Etc/GMT+3',
|
||||||
|
'-3.0': 'Etc/GMT+3',
|
||||||
|
'-2.5': 'Etc/GMT+2',
|
||||||
|
'-2.0': 'Etc/GMT+2',
|
||||||
|
'-1.5': 'Etc/GMT+1',
|
||||||
|
'-1.0': 'Etc/GMT+1',
|
||||||
|
'-0.5': 'Etc/GMT',
|
||||||
|
'0': 'Etc/GMT',
|
||||||
|
'0.0': 'Etc/GMT',
|
||||||
|
'0.5': 'Etc/GMT',
|
||||||
|
'1.0': 'Etc/GMT-1',
|
||||||
|
'1.5': 'Etc/GMT-1',
|
||||||
|
'2.0': 'Etc/GMT-2',
|
||||||
|
'2.5': 'Etc/GMT-2',
|
||||||
|
'3.0': 'Etc/GMT-3',
|
||||||
|
'3.5': 'Etc/GMT-3',
|
||||||
|
'4.0': 'Etc/GMT-4',
|
||||||
|
'4.5': 'Asia/Kabul',
|
||||||
|
'5.0': 'Etc/GMT-5',
|
||||||
|
'5.5': 'Asia/Kolkata',
|
||||||
|
'6.0': 'Etc/GMT-6',
|
||||||
|
'6.5': 'Asia/Rangoon',
|
||||||
|
'7.0': 'Etc/GMT-7',
|
||||||
|
'7.5': 'Etc/GMT-7',
|
||||||
|
'8.0': 'Etc/GMT-8',
|
||||||
|
'8.5': 'Etc/GMT-8',
|
||||||
|
'9.0': 'Etc/GMT-9',
|
||||||
|
'9.5': 'Australia/Darwin',
|
||||||
|
'10.0': 'Etc/GMT-10',
|
||||||
|
'10.5': 'Etc/GMT-10',
|
||||||
|
'11.0': 'Etc/GMT-11',
|
||||||
|
'11.5': 'Etc/GMT-11',
|
||||||
|
'12.0': 'Etc/GMT-12',
|
||||||
|
'12.5': 'Etc/GMT-12',
|
||||||
|
'13.0': 'Etc/GMT-13',
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns years, months, days, hours, minutes and seconds in a human readable format.
|
* Returns years, months, days, hours, minutes and seconds in a human readable format.
|
||||||
*
|
*
|
||||||
|
@ -119,4 +177,24 @@ export class CoreTime {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the forced timezone to use. Timezone is forced for automated tests.
|
||||||
|
*
|
||||||
|
* @returns Timezone. Undefined to use the user's timezone.
|
||||||
|
*/
|
||||||
|
static getForcedTimezone(): string | undefined {
|
||||||
|
// Use the same timezone forced for LMS in tests.
|
||||||
|
return CorePlatform.isAutomated() ? 'Australia/Perth' : undefined;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Translates legacy timezone names.
|
||||||
|
*
|
||||||
|
* @param tz Timezone name.
|
||||||
|
* @returns Readable timezone name.
|
||||||
|
*/
|
||||||
|
static translateLegacyTimezone(tz: string): string {
|
||||||
|
return CoreTime.LEGACY_TIMEZONES[tz] ?? tz;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,7 +13,7 @@
|
||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
|
|
||||||
import { APP_INITIALIZER, NgModule } from '@angular/core';
|
import { APP_INITIALIZER, NgModule } from '@angular/core';
|
||||||
import { CoreAppProvider } from '@services/app';
|
import { CoreTime } from '@singletons/time';
|
||||||
import moment from 'moment-timezone';
|
import moment from 'moment-timezone';
|
||||||
import { TestingBehatRuntime, TestingBehatRuntimeService } from './services/behat-runtime';
|
import { TestingBehatRuntime, TestingBehatRuntimeService } from './services/behat-runtime';
|
||||||
import { CorePlatform } from '@services/platform';
|
import { CorePlatform } from '@services/platform';
|
||||||
|
@ -35,7 +35,7 @@ function initializeAutomatedTests(window: AutomatedTestsWindow) {
|
||||||
window.behat = TestingBehatRuntime.instance;
|
window.behat = TestingBehatRuntime.instance;
|
||||||
|
|
||||||
// Force timezone for automated tests.
|
// Force timezone for automated tests.
|
||||||
moment.tz.setDefault(CoreAppProvider.getForcedTimezone());
|
moment.tz.setDefault(CoreTime.getForcedTimezone());
|
||||||
}
|
}
|
||||||
|
|
||||||
@NgModule({
|
@NgModule({
|
||||||
|
|
Loading…
Reference in New Issue