mirror of
https://gitlab.com/openstapps/openstapps.git
synced 2026-01-09 19:22:51 +00:00
@@ -17,8 +17,6 @@ import {Router} from '@angular/router';
|
|||||||
import {App, URLOpenListenerEvent} from '@capacitor/app';
|
import {App, URLOpenListenerEvent} from '@capacitor/app';
|
||||||
import {SplashScreen} from '@capacitor/splash-screen';
|
import {SplashScreen} from '@capacitor/splash-screen';
|
||||||
import {Platform, ToastController} from '@ionic/angular';
|
import {Platform, ToastController} from '@ionic/angular';
|
||||||
import {NGXLogger} from 'ngx-logger';
|
|
||||||
import {ConfigProvider} from './modules/config/config.provider';
|
|
||||||
import {SettingsProvider} from './modules/settings/settings.provider';
|
import {SettingsProvider} from './modules/settings/settings.provider';
|
||||||
import {PAIAAuthService} from './modules/auth/paia/paia-auth.service';
|
import {PAIAAuthService} from './modules/auth/paia/paia-auth.service';
|
||||||
import {DefaultAuthService} from './modules/auth/default-auth.service';
|
import {DefaultAuthService} from './modules/auth/default-auth.service';
|
||||||
@@ -52,8 +50,6 @@ export class AppComponent implements AfterContentInit {
|
|||||||
*
|
*
|
||||||
* @param platform TODO
|
* @param platform TODO
|
||||||
* @param settingsProvider TODO
|
* @param settingsProvider TODO
|
||||||
* @param configProvider TODO
|
|
||||||
* @param logger An angular logger
|
|
||||||
* @param router The angular router
|
* @param router The angular router
|
||||||
* @param zone The angular zone
|
* @param zone The angular zone
|
||||||
* @param defaultAuth Auth Service
|
* @param defaultAuth Auth Service
|
||||||
@@ -65,8 +61,6 @@ export class AppComponent implements AfterContentInit {
|
|||||||
constructor(
|
constructor(
|
||||||
private readonly platform: Platform,
|
private readonly platform: Platform,
|
||||||
private readonly settingsProvider: SettingsProvider,
|
private readonly settingsProvider: SettingsProvider,
|
||||||
private readonly configProvider: ConfigProvider,
|
|
||||||
private readonly logger: NGXLogger,
|
|
||||||
private readonly router: Router,
|
private readonly router: Router,
|
||||||
private readonly zone: NgZone,
|
private readonly zone: NgZone,
|
||||||
private readonly defaultAuth: DefaultAuthService,
|
private readonly defaultAuth: DefaultAuthService,
|
||||||
@@ -102,19 +96,6 @@ export class AppComponent implements AfterContentInit {
|
|||||||
await this.paiaAuth.init();
|
await this.paiaAuth.init();
|
||||||
await SplashScreen.hide();
|
await SplashScreen.hide();
|
||||||
|
|
||||||
// initialise the configProvider
|
|
||||||
try {
|
|
||||||
await this.configProvider.init();
|
|
||||||
} catch (error) {
|
|
||||||
if (
|
|
||||||
typeof error.name !== 'undefined' &&
|
|
||||||
error.name === 'ConfigInitError'
|
|
||||||
) {
|
|
||||||
// TODO: Issue #43 handle initialisation error and inform user
|
|
||||||
}
|
|
||||||
this.logger.error(error);
|
|
||||||
}
|
|
||||||
|
|
||||||
// set order of categories in settings
|
// set order of categories in settings
|
||||||
this.settingsProvider.setCategoriesOrder([
|
this.settingsProvider.setCategoriesOrder([
|
||||||
'profile',
|
'profile',
|
||||||
|
|||||||
@@ -65,18 +65,21 @@ import {AuthModule} from './modules/auth/auth.module';
|
|||||||
import {ScheduleSyncService} from './modules/background/schedule/schedule-sync.service';
|
import {ScheduleSyncService} from './modules/background/schedule/schedule-sync.service';
|
||||||
import {BackgroundModule} from './modules/background/background.module';
|
import {BackgroundModule} from './modules/background/background.module';
|
||||||
import {LibraryModule} from './modules/library/library.module';
|
import {LibraryModule} from './modules/library/library.module';
|
||||||
|
import {StorageProvider} from './modules/storage/storage.provider';
|
||||||
|
|
||||||
registerLocaleData(localeDe);
|
registerLocaleData(localeDe);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Initializes settings from Config before other components
|
* Initializes data needed on startup
|
||||||
*
|
*
|
||||||
|
* @param storageProvider provider of the saved data (using framework's storage)
|
||||||
* @param logger TODO
|
* @param logger TODO
|
||||||
* @param settingsProvider provider of settings (e.g. language that has been set)
|
* @param settingsProvider provider of settings (e.g. language that has been set)
|
||||||
* @param configProvider TODO
|
* @param configProvider TODO
|
||||||
* @param translateService TODO
|
* @param translateService TODO
|
||||||
*/
|
*/
|
||||||
export function initSettingsFactory(
|
export function initializerFactory(
|
||||||
|
storageProvider: StorageProvider,
|
||||||
logger: NGXLogger,
|
logger: NGXLogger,
|
||||||
settingsProvider: SettingsProvider,
|
settingsProvider: SettingsProvider,
|
||||||
configProvider: ConfigProvider,
|
configProvider: ConfigProvider,
|
||||||
@@ -84,10 +87,12 @@ export function initSettingsFactory(
|
|||||||
) {
|
) {
|
||||||
return async () => {
|
return async () => {
|
||||||
initLogger(logger);
|
initLogger(logger);
|
||||||
|
await storageProvider.init();
|
||||||
|
await configProvider.init();
|
||||||
await settingsProvider.init();
|
await settingsProvider.init();
|
||||||
try {
|
try {
|
||||||
// set language from settings
|
|
||||||
if (configProvider.firstSession) {
|
if (configProvider.firstSession) {
|
||||||
|
// set language from browser
|
||||||
await settingsProvider.setSettingValue(
|
await settingsProvider.setSettingValue(
|
||||||
'profile',
|
'profile',
|
||||||
'language',
|
'language',
|
||||||
@@ -184,13 +189,14 @@ export function createTranslateLoader(http: HttpClient) {
|
|||||||
provide: APP_INITIALIZER,
|
provide: APP_INITIALIZER,
|
||||||
multi: true,
|
multi: true,
|
||||||
deps: [
|
deps: [
|
||||||
|
StorageProvider,
|
||||||
NGXLogger,
|
NGXLogger,
|
||||||
SettingsProvider,
|
SettingsProvider,
|
||||||
ConfigProvider,
|
ConfigProvider,
|
||||||
TranslateService,
|
TranslateService,
|
||||||
ScheduleSyncService,
|
ScheduleSyncService,
|
||||||
],
|
],
|
||||||
useFactory: initSettingsFactory,
|
useFactory: initializerFactory,
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -23,7 +23,7 @@ import {ConfigProvider} from '../../config/config.provider';
|
|||||||
styleUrls: ['about-page.scss'],
|
styleUrls: ['about-page.scss'],
|
||||||
})
|
})
|
||||||
export class AboutPageComponent implements OnInit {
|
export class AboutPageComponent implements OnInit {
|
||||||
content: Promise<SCAboutPage>;
|
content: SCAboutPage;
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
private readonly route: ActivatedRoute,
|
private readonly route: ActivatedRoute,
|
||||||
@@ -33,12 +33,11 @@ export class AboutPageComponent implements OnInit {
|
|||||||
async ngOnInit() {
|
async ngOnInit() {
|
||||||
const route = this.route.snapshot.url.map(it => it.path).join('/');
|
const route = this.route.snapshot.url.map(it => it.path).join('/');
|
||||||
|
|
||||||
this.content = new Promise(resolve => {
|
this.content =
|
||||||
this.configProvider
|
(
|
||||||
.getValue('aboutPages')
|
this.configProvider.getValue(
|
||||||
.then(value =>
|
'aboutPages',
|
||||||
resolve((value as SCAppConfiguration['aboutPages'])[route] ?? {}),
|
) as SCAppConfiguration['aboutPages']
|
||||||
);
|
)[route] ?? {};
|
||||||
});
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -19,7 +19,7 @@
|
|||||||
<ion-menu-button></ion-menu-button>
|
<ion-menu-button></ion-menu-button>
|
||||||
<ion-back-button></ion-back-button>
|
<ion-back-button></ion-back-button>
|
||||||
</ion-buttons>
|
</ion-buttons>
|
||||||
<ion-title *ngIf="content | async as content; else titleLoading">{{
|
<ion-title *ngIf="content; else titleLoading">{{
|
||||||
'title' | translateSimple: content
|
'title' | translateSimple: content
|
||||||
}}</ion-title>
|
}}</ion-title>
|
||||||
<ng-template #titleLoading>
|
<ng-template #titleLoading>
|
||||||
@@ -29,7 +29,7 @@
|
|||||||
</ng-template>
|
</ng-template>
|
||||||
</ion-toolbar>
|
</ion-toolbar>
|
||||||
</ion-header>
|
</ion-header>
|
||||||
<ion-content *ngIf="content | async as content">
|
<ion-content *ngIf="content">
|
||||||
<about-page-content
|
<about-page-content
|
||||||
*ngFor="let element of content.content"
|
*ngFor="let element of content.content"
|
||||||
[content]="element"
|
[content]="element"
|
||||||
|
|||||||
@@ -107,7 +107,6 @@ describe('ConfigProvider', () => {
|
|||||||
expect(storageProviderSpy.has).toHaveBeenCalled();
|
expect(storageProviderSpy.has).toHaveBeenCalled();
|
||||||
expect(storageProviderSpy.get).toHaveBeenCalledTimes(0);
|
expect(storageProviderSpy.get).toHaveBeenCalledTimes(0);
|
||||||
expect(configProvider.client.handshake).toHaveBeenCalled();
|
expect(configProvider.client.handshake).toHaveBeenCalled();
|
||||||
expect(configProvider.initialised).toBe(true);
|
|
||||||
expect(await configProvider.getValue('name')).toEqual(
|
expect(await configProvider.getValue('name')).toEqual(
|
||||||
sampleIndexResponse.app.name,
|
sampleIndexResponse.app.name,
|
||||||
);
|
);
|
||||||
@@ -129,7 +128,6 @@ describe('ConfigProvider', () => {
|
|||||||
expect(error).toEqual(new ConfigFetchError());
|
expect(error).toEqual(new ConfigFetchError());
|
||||||
expect(storageProviderSpy.has).toHaveBeenCalled();
|
expect(storageProviderSpy.has).toHaveBeenCalled();
|
||||||
expect(storageProviderSpy.get).toHaveBeenCalled();
|
expect(storageProviderSpy.get).toHaveBeenCalled();
|
||||||
expect(configProvider.initialised).toBe(true);
|
|
||||||
expect(await configProvider.getValue('name')).toEqual(
|
expect(await configProvider.getValue('name')).toEqual(
|
||||||
sampleIndexResponse.app.name,
|
sampleIndexResponse.app.name,
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -50,21 +50,16 @@ export class ConfigProvider {
|
|||||||
*/
|
*/
|
||||||
config: SCIndexResponse;
|
config: SCIndexResponse;
|
||||||
|
|
||||||
/**
|
|
||||||
* First session indicator
|
|
||||||
*/
|
|
||||||
firstSession = true;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Initialised status flag of config provider
|
|
||||||
*/
|
|
||||||
initialised = false;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Version of the @openstapps/core package that app is using
|
* Version of the @openstapps/core package that app is using
|
||||||
*/
|
*/
|
||||||
scVersion = packageJson.dependencies['@openstapps/core'];
|
scVersion = packageJson.dependencies['@openstapps/core'];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* First session indicator (config not found in storage)
|
||||||
|
*/
|
||||||
|
firstSession = true;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructor, initialise api client
|
* Constructor, initialise api client
|
||||||
*
|
*
|
||||||
@@ -100,17 +95,7 @@ export class ConfigProvider {
|
|||||||
*
|
*
|
||||||
* @param attribute requested attribute from app configuration
|
* @param attribute requested attribute from app configuration
|
||||||
*/
|
*/
|
||||||
public async getValue(attribute: keyof SCAppConfiguration) {
|
public getValue(attribute: keyof SCAppConfiguration) {
|
||||||
if (!this.initialised) {
|
|
||||||
try {
|
|
||||||
await this.init();
|
|
||||||
} catch (error) {
|
|
||||||
// don't throw ConfigFetchError if saved config is available
|
|
||||||
if (error.name === 'ConfigFetchError' && !this.initialised) {
|
|
||||||
throw error;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (typeof this.config.app[attribute] !== 'undefined') {
|
if (typeof this.config.app[attribute] !== 'undefined') {
|
||||||
return this.config.app[attribute];
|
return this.config.app[attribute];
|
||||||
}
|
}
|
||||||
@@ -138,12 +123,10 @@ export class ConfigProvider {
|
|||||||
async init(): Promise<void> {
|
async init(): Promise<void> {
|
||||||
let loadError;
|
let loadError;
|
||||||
let fetchError;
|
let fetchError;
|
||||||
this.initialised = false;
|
|
||||||
// load saved configuration
|
// load saved configuration
|
||||||
try {
|
try {
|
||||||
this.config = await this.loadLocal();
|
this.config = await this.loadLocal();
|
||||||
this.firstSession = false;
|
this.firstSession = false;
|
||||||
this.initialised = true;
|
|
||||||
this.logger.log(`initialised configuration from storage`);
|
this.logger.log(`initialised configuration from storage`);
|
||||||
if (this.config.backend.SCVersion !== this.scVersion) {
|
if (this.config.backend.SCVersion !== this.scVersion) {
|
||||||
loadError = new WrongConfigVersionInStorage(
|
loadError = new WrongConfigVersionInStorage(
|
||||||
@@ -159,7 +142,6 @@ export class ConfigProvider {
|
|||||||
try {
|
try {
|
||||||
const fetchedConfig: SCIndexResponse = await this.fetch();
|
const fetchedConfig: SCIndexResponse = await this.fetch();
|
||||||
await this.set(fetchedConfig);
|
await this.set(fetchedConfig);
|
||||||
this.initialised = true;
|
|
||||||
this.logger.log(`initialised configuration from remote`);
|
this.logger.log(`initialised configuration from remote`);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
fetchError = error;
|
fetchError = error;
|
||||||
@@ -169,7 +151,7 @@ export class ConfigProvider {
|
|||||||
throw new ConfigInitError();
|
throw new ConfigInitError();
|
||||||
}
|
}
|
||||||
if (typeof loadError !== 'undefined') {
|
if (typeof loadError !== 'undefined') {
|
||||||
throw loadError;
|
this.logger.warn(loadError);
|
||||||
}
|
}
|
||||||
if (typeof fetchError !== 'undefined') {
|
if (typeof fetchError !== 'undefined') {
|
||||||
throw fetchError;
|
throw fetchError;
|
||||||
@@ -182,7 +164,6 @@ export class ConfigProvider {
|
|||||||
* @throws SavedConfigNotAvailable if no configuration could be loaded
|
* @throws SavedConfigNotAvailable if no configuration could be loaded
|
||||||
*/
|
*/
|
||||||
async loadLocal(): Promise<SCIndexResponse> {
|
async loadLocal(): Promise<SCIndexResponse> {
|
||||||
await this.storageProvider.init();
|
|
||||||
// get local configuration
|
// get local configuration
|
||||||
if (await this.storageProvider.has(STORAGE_KEY_CONFIG)) {
|
if (await this.storageProvider.has(STORAGE_KEY_CONFIG)) {
|
||||||
return this.storageProvider.get<SCIndexResponse>(STORAGE_KEY_CONFIG);
|
return this.storageProvider.get<SCIndexResponse>(STORAGE_KEY_CONFIG);
|
||||||
|
|||||||
@@ -13,7 +13,6 @@
|
|||||||
* this program. If not, see <https://www.gnu.org/licenses/>.
|
* this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
import {CommonModule} from '@angular/common';
|
import {CommonModule} from '@angular/common';
|
||||||
import {APP_INITIALIZER, NgModule} from '@angular/core';
|
|
||||||
import {FormsModule} from '@angular/forms';
|
import {FormsModule} from '@angular/forms';
|
||||||
import {RouterModule, Routes} from '@angular/router';
|
import {RouterModule, Routes} from '@angular/router';
|
||||||
import {LeafletModule} from '@asymmetrik/ngx-leaflet';
|
import {LeafletModule} from '@asymmetrik/ngx-leaflet';
|
||||||
@@ -34,6 +33,7 @@ import {MapPageComponent} from './page/map-page.component';
|
|||||||
import {MapListModalComponent} from './page/modals/map-list-modal.component';
|
import {MapListModalComponent} from './page/modals/map-list-modal.component';
|
||||||
import {MapSingleModalComponent} from './page/modals/map-single-modal.component';
|
import {MapSingleModalComponent} from './page/modals/map-single-modal.component';
|
||||||
import {MapItemComponent} from './item/map-item.component';
|
import {MapItemComponent} from './item/map-item.component';
|
||||||
|
import {NgModule} from '@angular/core';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Initializes the default area to show in advance (before components are initialized)
|
* Initializes the default area to show in advance (before components are initialized)
|
||||||
@@ -86,12 +86,6 @@ const mapRoutes: Routes = [
|
|||||||
DataProvider,
|
DataProvider,
|
||||||
DataFacetsProvider,
|
DataFacetsProvider,
|
||||||
StAppsWebHttpClient,
|
StAppsWebHttpClient,
|
||||||
{
|
|
||||||
provide: APP_INITIALIZER,
|
|
||||||
multi: true,
|
|
||||||
deps: [ConfigProvider, MapProvider],
|
|
||||||
useFactory: initMapConfigFactory,
|
|
||||||
},
|
|
||||||
],
|
],
|
||||||
})
|
})
|
||||||
export class MapModule {}
|
export class MapModule {}
|
||||||
|
|||||||
@@ -26,6 +26,7 @@ import {divIcon, geoJSON, icon, LatLng, Map, marker, Marker} from 'leaflet';
|
|||||||
import {DataProvider} from '../data/data.provider';
|
import {DataProvider} from '../data/data.provider';
|
||||||
import {MapPosition, PositionService} from './position.service';
|
import {MapPosition, PositionService} from './position.service';
|
||||||
import {hasValidLocation} from '../data/types/place/place-types';
|
import {hasValidLocation} from '../data/types/place/place-types';
|
||||||
|
import {ConfigProvider} from '../config/config.provider';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Provides methods for presenting the map
|
* Provides methods for presenting the map
|
||||||
@@ -107,7 +108,12 @@ export class MapProvider {
|
|||||||
constructor(
|
constructor(
|
||||||
private dataProvider: DataProvider,
|
private dataProvider: DataProvider,
|
||||||
private positionService: PositionService,
|
private positionService: PositionService,
|
||||||
) {}
|
private configProvider: ConfigProvider,
|
||||||
|
) {
|
||||||
|
this.defaultPolygon = this.configProvider.getValue(
|
||||||
|
'campusPolygon',
|
||||||
|
) as Polygon;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Provide the specific place by its UID
|
* Provide the specific place by its UID
|
||||||
@@ -128,7 +134,7 @@ export class MapProvider {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Provide places (buildings and canteens) const result = await this.dataProvider.search(query);
|
* Provide places (buildings and canteens) const result = await this.dataProvider.search(query);
|
||||||
|
|
||||||
*
|
*
|
||||||
* @param contextFilter Additional contextual filter (e.g. from the context menu)
|
* @param contextFilter Additional contextual filter (e.g. from the context menu)
|
||||||
* @param queryText Query (text) of the search query
|
* @param queryText Query (text) of the search query
|
||||||
|
|||||||
@@ -333,9 +333,9 @@ export class SettingsProvider {
|
|||||||
*/
|
*/
|
||||||
public async init(): Promise<void> {
|
public async init(): Promise<void> {
|
||||||
try {
|
try {
|
||||||
const settings: SCSetting[] = (await this.configProvider.getValue(
|
const settings: SCSetting[] = this.configProvider.getValue(
|
||||||
'settings',
|
'settings',
|
||||||
)) as SCSetting[];
|
) as SCSetting[];
|
||||||
for (const setting of settings) this.addSetting(setting);
|
for (const setting of settings) this.addSetting(setting);
|
||||||
|
|
||||||
for (const category of Object.keys(this.settingsCache)) {
|
for (const category of Object.keys(this.settingsCache)) {
|
||||||
|
|||||||
Reference in New Issue
Block a user