Skip to content
Snippets Groups Projects
Commit 0f512533 authored by jojohoch's avatar jojohoch
Browse files

[player] Verify data versions of `unitDefinition` and `unitState`

* Define data version types data versions for `unitDefinition` and
`unitState` in meta tag of index.html
* Separate `MetaDataService` from `VeronaPostService`
* Extend `MetaDataService` to verify data versions of `unitDefinition` and
`unitState`
parent 1644bfaf
No related branches found
No related tags found
No related merge requests found
......@@ -7,7 +7,8 @@ import {
import { VeronaSubscriptionService } from './services/verona-subscription.service';
import { VeronaPostService } from './services/verona-post.service';
import { NativeEventService } from './services/native-event.service';
import { PlayerConfig, VopStartCommand } from './models/verona';
import { MetaDataService } from './services/meta-data.service';
import { PlayerConfig, UnitState, VopStartCommand } from './models/verona';
import { FormPage } from '../../../common/form';
@Component({
......@@ -24,12 +25,13 @@ export class AppComponent implements OnInit {
constructor(private translateService: TranslateService,
private veronaSubscriptionService: VeronaSubscriptionService,
private veronaPostService: VeronaPostService,
private metaDataService: MetaDataService,
private nativeEventService: NativeEventService) {
}
ngOnInit(): void {
this.initSubscriptions();
this.veronaPostService.sendVopReadyNotification();
this.veronaPostService.sendVopReadyNotification(this.metaDataService.playerMetadata);
this.translateService.addLangs(['de']);
this.translateService.setDefaultLang('de');
}
......@@ -43,17 +45,36 @@ export class AppComponent implements OnInit {
.subscribe((focused: boolean): void => this.onFocus(focused));
}
private initUnit(pages: UnitPage[], unitState: UnitState | undefined): void {
const storedPages: FormPage[] = unitState?.dataParts?.pages ?
JSON.parse(unitState.dataParts.pages) : [];
if (storedPages.length > 0) {
if (unitState?.unitStateDataType &&
this.metaDataService.verifyUnitStateDataType(unitState.unitStateDataType)) {
this.pages = this.addStoredValues(pages, storedPages);
} else {
// eslint-disable-next-line no-console
console.warn('player: wrong unitStateDataType');
this.pages = pages;
}
} else {
this.pages = pages;
}
}
private onStart(message: VopStartCommand): void {
// eslint-disable-next-line no-console
console.log('player: onStart', message);
const unitDefinition: Unit = message.unitDefinition ? JSON.parse(message.unitDefinition) : [];
const storedPages: FormPage[] = message.unitState?.dataParts?.pages ?
JSON.parse(message.unitState.dataParts.pages) : [];
this.pages = storedPages.length > 0 ?
this.addStoredValues(unitDefinition.pages, storedPages) :
unitDefinition.pages;
this.playerConfig = message.playerConfig || {};
this.veronaPostService.sessionId = message.sessionId;
const unitDefinition: Unit = message.unitDefinition ? JSON.parse(message.unitDefinition) : {};
if (unitDefinition.veronaModuleVersion &&
this.metaDataService.verifyUnitDefinitionVersion(unitDefinition.veronaModuleVersion)) {
this.veronaPostService.sessionId = message.sessionId;
this.playerConfig = message.playerConfig || {};
this.initUnit(unitDefinition.pages, message.unitState);
} else {
// eslint-disable-next-line no-console
console.warn('player: wrong unitDefinitionType');
}
}
private addStoredValues = (unitPages: UnitPage[], storedPages: FormPage[]): UnitPage[] => unitPages
......
......@@ -10,6 +10,8 @@ import { TranslateService } from '@ngx-translate/core';
import { FormService } from '../../../../common/form.service';
import { VeronaSubscriptionService } from '../services/verona-subscription.service';
import { VeronaPostService } from '../services/verona-post.service';
import { MessageService } from '../../../../common/message.service';
import { MetaDataService } from '../services/meta-data.service';
import {
FormControlElement, FormControlValidators, ChildFormGroup, ValueChangeElement, FormModel
} from '../../../../common/form';
......@@ -17,7 +19,6 @@ import {
PlayerConfig, UnitState, VopNavigationDeniedNotification
} from '../models/verona';
import { UnitPage } from '../../../../common/unit';
import { MessageService } from '../../../../common/message.service';
@Component({
selector: 'app-form',
......@@ -41,6 +42,7 @@ export class FormComponent implements OnInit, OnDestroy {
private veronaSubscriptionService: VeronaSubscriptionService,
private veronaPostService: VeronaPostService,
private messageService: MessageService,
private metaDataService: MetaDataService,
private translateService: TranslateService,
protected changeDetectorRef: ChangeDetectorRef) {
}
......@@ -111,7 +113,8 @@ export class FormComponent implements OnInit, OnDestroy {
const unitState: UnitState = {
dataParts: {
pages: JSON.stringify(formModel.pages)
}
},
unitStateDataType: this.metaDataService.playerMetadata.supportedUnitStateDataTypes
};
this.veronaPostService.sendVopStateChangedNotification({ unitState });
}
......@@ -120,10 +123,4 @@ export class FormComponent implements OnInit, OnDestroy {
this.ngUnsubscribe.next();
this.ngUnsubscribe.complete();
}
/// ////////////////////// only for dev
submit(): void {
// eslint-disable-next-line no-console
console.log('player: form.value', this.form.value);
}
}
......@@ -69,8 +69,11 @@ export interface VopContinueCommand {
sessionId: string;
}
export interface VopReadyNotification {
export interface VopReadyNotification extends VopMetaData{
type: 'vopReadyNotification';
}
export interface VopMetaData {
apiVersion: string;
notSupportedApiFeatures?: string;
supportedUnitDefinitionTypes?: string;
......
import { Inject, Injectable } from '@angular/core';
import { DOCUMENT } from '@angular/common';
import { VopMetaData } from '../models/verona';
@Injectable({
providedIn: 'root'
})
export class MetaDataService {
playerMetadata!: VopMetaData;
constructor(@Inject(DOCUMENT) private document: Document) {
const playerMetadata: NamedNodeMap = document.querySelectorAll('meta')[1].attributes;
this.playerMetadata = {
apiVersion:
playerMetadata.getNamedItem('data-api-version')?.value || '',
notSupportedApiFeatures:
playerMetadata.getNamedItem('data-not-supported-api-features')?.value,
supportedUnitDefinitionTypes:
playerMetadata.getNamedItem('data-supported-unit-definition-types')?.value,
supportedUnitStateDataTypes:
playerMetadata.getNamedItem('data-supported-unit-state-data-types')?.value
};
}
verifyUnitDefinitionVersion(unitDefinition: string): boolean {
return (this.playerMetadata.supportedUnitDefinitionTypes === unitDefinition);
}
verifyUnitStateDataType(unitStateDataType: string): boolean {
return (this.playerMetadata.supportedUnitStateDataTypes === unitStateDataType);
}
}
import { Inject, Injectable } from '@angular/core';
import { DOCUMENT } from '@angular/common';
import { Injectable } from '@angular/core';
import {
LogData, NavigationTarget, PlayerState, UnitState, VopMessage
LogData, NavigationTarget, PlayerState, UnitState, VopMessage, VopMetaData
} from '../models/verona';
@Injectable({
providedIn: 'root'
})
export class VeronaPostService {
private readonly playerMetadata!: NamedNodeMap;
private _sessionId!: string;
constructor(@Inject(DOCUMENT) private document: Document) {
this.playerMetadata = document.querySelectorAll('meta')[1].attributes;
}
set sessionId(sessionId:string) {
set sessionId(sessionId: string) {
this._sessionId = sessionId;
}
......@@ -44,18 +38,11 @@ export class VeronaPostService {
});
}
sendVopReadyNotification(): void {
if (this.playerMetadata) {
sendVopReadyNotification(playerMetadata: VopMetaData): void {
if (playerMetadata) {
this.send({
type: 'vopReadyNotification',
apiVersion:
this.playerMetadata.getNamedItem('data-api-version')?.value || '',
notSupportedApiFeatures:
this.playerMetadata.getNamedItem('data-not-supported-api-features')?.value,
supportedUnitDefinitionTypes:
this.playerMetadata.getNamedItem('data-supported-unit-definition-types')?.value,
supportedUnitStateDataTypes:
this.playerMetadata.getNamedItem('data-supported-unit-state-data-types')?.value
...playerMetadata
});
} else {
// eslint-disable-next-line no-console
......
......@@ -5,12 +5,12 @@
<title>Verona Player Aspect</title>
<meta name="application-name" content="iqb-player-aspect"
data-version="3.3.3"
data-version="3.0.0"
data-repository-url="https://github.com/iqb-berlin/verona-modules-apect"
data-api-version="2.1.0"
data-api-version="3.0.0"
data-not-supported-api-features=""
data-supported-unit-definition-types="iqb-scripted@1.0"
data-supported-unit-state-data-types="iqb-key-value@1.0.0"
data-supported-unit-definition-types="iqb-aspect-module@0.0.1"
data-supported-unit-state-data-types="iqb-aspect-player@0.0.1"
data-supported-browsers='{"Firefox": 69, "Chrome": 72, "Edge": 79}'
/>
<script type="application/ld+json">
......
......@@ -4,12 +4,12 @@
<meta charset="utf-8">
<title>Player</title>
<meta name="application-name" content="iqb-player-aspect"
data-version="3.3.3"
data-version="3.0.0"
data-repository-url="https://github.com/iqb-berlin/verona-modules-apect"
data-api-version="2.1.0"
data-api-version="3.0.0"
data-not-supported-api-features=""
data-supported-unit-definition-types="iqb-scripted@1.0"
data-supported-unit-state-data-types="iqb-key-value@1.0.0"
data-supported-unit-definition-types="iqb-aspect-module@0.0.1"
data-supported-unit-state-data-types="iqb-aspect-player@0.0.1"
data-supported-browsers='{"Firefox": 69, "Chrome": 72, "Edge": 79}'
/>
<base href="/">
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment