Adds rabbitmq as message broker for frontend and backend

parent fcd2b9da
......@@ -51,10 +51,9 @@ build:
- nodejs
- angular
script:
- echo $STAGING_SERVER_ENDPOINTS > src/assets/serverEndpoint.json
- npm install
- npm install typescript@3.4.5
- npm run build:PROD
- npm run build:STAGING_THM
artifacts:
paths:
- dist
......
......@@ -130,6 +130,30 @@
}
]
},
"thmStaging": {
"optimization": true,
"outputHashing": "all",
"sourceMap": false,
"extractCss": true,
"namedChunks": false,
"aot": true,
"extractLicenses": true,
"vendorChunk": true,
"commonChunk": true,
"buildOptimizer": true,
"serviceWorker": true,
"ngswConfigPath": "src/ngsw-config.json",
"fileReplacements": [
{
"replace": "src/environments/environment.ts",
"with": "src/environments/environment.thm.staging.ts"
},
{
"replace": "src/assets/piwik/piwik.js",
"with": "src/assets/piwik/piwik.prod.js"
}
]
},
"westermann": {
"optimization": true,
"outputHashing": "all",
......@@ -165,6 +189,9 @@
"production": {
"browserTarget": "frontend:build:production"
},
"thmStaging": {
"browserTarget": "frontend:build:thmStaging"
},
"westermann": {
"browserTarget": "frontend:build:westermann"
}
......@@ -243,4 +270,4 @@
"styleext": "scss"
}
}
}
\ No newline at end of file
}
......@@ -12,7 +12,6 @@
"prefixed",
"prefixes",
"prefixedCSS",
"setClasses",
"testAllProps",
"testProp",
"testStyles"
......
......@@ -10,7 +10,7 @@
"scripts": {
"dependency-check": "npx --ignore-existing madge --circular --extensions ts src",
"ng": "ng",
"clean": "rm -rf dist/",
"clean": "rimraf dist",
"ngsw-config": "node_modules/.bin/ngsw-config dist/browser src/ngsw-config.json",
"start:SSR": "cd dist && node server",
"start:DEV": "ng serve --host 192.168.2.101 --port 4210 --aot",
......@@ -20,6 +20,7 @@
"build:SERVER": "ng run frontend:server",
"prebuild:PROD": "npm run clean",
"build:PROD": "ng build --prod",
"build:STAGING_THM": "ng build --configuration=thmStaging",
"build:WESTERMANN": "ng build --configuration=westermann",
"build:PROD:DEPLOY": "npm run build:PROD && npm run purify",
"build:PROD-STATS": "ng build --prod --stats-json",
......@@ -66,10 +67,12 @@
"@nguniversal/module-map-ngfactory-loader": "^7.1.1",
"@ngx-translate/core": "^11.0.1",
"@ngx-translate/http-loader": "~4.0.0",
"@stomp/ng2-stompjs": "^7.2.0",
"@techiediaries/ngx-qrcode": "0.0.5",
"@webcomponents/custom-elements": "^1.2.4",
"angular-svg-icon": "^7.2.1",
"angulartics2": "^7.5.2",
"angularx-qrcode": "^1.6.4",
"bootstrap": "^4.3.1",
"classlist.js": "^1.1.20150312",
"cors": "^2.8.5",
......@@ -77,10 +80,11 @@
"intro.js": "^2.9.3",
"marked": "git+https://github.com/trayhem/marked.git",
"messageformat": "^2.1.0",
"ng2-simple-mq": "^8.2.1",
"ngx-infinite-scroll": "^7.2.0",
"ngx-qrcode2": "0.0.9",
"ngx-toastr": "^10.0.4",
"ngx-translate-messageformat-compiler": "^4.5.0",
"rimraf": "^3.0.0",
"rxjs": "^6.5.2",
"ts-loader": "^6.0.4",
"zone.js": "~0.9.1"
......
......@@ -20,8 +20,6 @@ import { StorageServiceMock } from '../../service/storage/storage.service.mock';
import { ThemesService } from '../../service/themes/themes.service';
import { TrackingMockService } from '../../service/tracking/tracking.mock.service';
import { TrackingService } from '../../service/tracking/tracking.service';
import { WebsocketMockService } from '../../service/websocket/websocket.mock.service';
import { WebsocketService } from '../../service/websocket/websocket.service';
import { SharedModule } from '../../shared/shared.module';
import { AdminOverviewComponent } from './admin-overview.component';
......@@ -58,9 +56,6 @@ describe('AdminOverviewComponent', () => {
}, FooterBarService, SettingsService, {
provide: ConnectionService,
useClass: ConnectionMockService,
}, {
provide: WebsocketService,
useClass: WebsocketMockService,
}, SharedService,
],
declarations: [
......
......@@ -24,8 +24,6 @@ import { ThemesService } from '../../service/themes/themes.service';
import { TrackingMockService } from '../../service/tracking/tracking.mock.service';
import { TrackingService } from '../../service/tracking/tracking.service';
import { UserService } from '../../service/user/user.service';
import { WebsocketMockService } from '../../service/websocket/websocket.mock.service';
import { WebsocketService } from '../../service/websocket/websocket.service';
import { SharedModule } from '../../shared/shared.module';
import { QuizAdminComponent } from './quiz-admin.component';
......@@ -68,9 +66,6 @@ describe('QuizAdminComponent', () => {
}, FooterBarService, SettingsService, {
provide: ConnectionService,
useClass: ConnectionMockService,
}, {
provide: WebsocketService,
useClass: WebsocketMockService,
}, SharedService, UserService, JwtHelperService,
],
declarations: [
......
......@@ -24,8 +24,6 @@ import { ThemesService } from '../../service/themes/themes.service';
import { TrackingMockService } from '../../service/tracking/tracking.mock.service';
import { TrackingService } from '../../service/tracking/tracking.service';
import { UserService } from '../../service/user/user.service';
import { WebsocketMockService } from '../../service/websocket/websocket.mock.service';
import { WebsocketService } from '../../service/websocket/websocket.service';
import { SharedModule } from '../../shared/shared.module';
import { UserAdminComponent } from './user-admin.component';
......@@ -68,9 +66,6 @@ describe('UserAdminComponent', () => {
}, FooterBarService, SettingsService, {
provide: ConnectionService,
useClass: ConnectionMockService,
}, {
provide: WebsocketService,
useClass: WebsocketMockService,
}, SharedService, UserService, JwtHelperService,
],
declarations: [
......
......@@ -19,8 +19,6 @@ import { StorageService } from '../../service/storage/storage.service';
import { StorageServiceMock } from '../../service/storage/storage.service.mock';
import { TrackingMockService } from '../../service/tracking/tracking.mock.service';
import { TrackingService } from '../../service/tracking/tracking.service';
import { WebsocketMockService } from '../../service/websocket/websocket.mock.service';
import { WebsocketService } from '../../service/websocket/websocket.service';
import { SharedModule } from '../../shared/shared.module';
import { FooterBarComponent } from './footer-bar.component';
......@@ -54,9 +52,6 @@ describe('FooterBarComponent', () => {
}, SettingsService, {
provide: ConnectionService,
useClass: ConnectionMockService,
}, {
provide: WebsocketService,
useClass: WebsocketMockService,
}, {
provide: TrackingService,
useClass: TrackingMockService,
......
......@@ -13,8 +13,6 @@ import { HeaderLabelService } from '../../service/header-label/header-label.serv
import { SharedService } from '../../service/shared/shared.service';
import { TrackingMockService } from '../../service/tracking/tracking.mock.service';
import { TrackingService } from '../../service/tracking/tracking.service';
import { WebsocketMockService } from '../../service/websocket/websocket.mock.service';
import { WebsocketService } from '../../service/websocket/websocket.service';
import { SharedModule } from '../../shared/shared.module';
import { HeaderComponent } from './header.component';
......@@ -44,10 +42,7 @@ describe('HeaderComponent', () => {
}, {
provide: TrackingService,
useClass: TrackingMockService,
}, SharedService, {
provide: WebsocketService,
useClass: WebsocketMockService,
},
}, SharedService,
],
declarations: [
HeaderComponent,
......
......@@ -20,8 +20,6 @@ import { SettingsService } from '../../service/settings/settings.service';
import { SharedService } from '../../service/shared/shared.service';
import { TrackingMockService } from '../../service/tracking/tracking.mock.service';
import { TrackingService } from '../../service/tracking/tracking.service';
import { WebsocketMockService } from '../../service/websocket/websocket.mock.service';
import { WebsocketService } from '../../service/websocket/websocket.service';
import { LivePreviewComponent } from './live-preview.component';
......@@ -51,9 +49,6 @@ describe('LivePreviewComponent', () => {
}, {
provide: QuizService,
useClass: QuizMockService,
}, {
provide: WebsocketService,
useClass: WebsocketMockService,
}, FooterBarService, SharedService, SettingsService, HeaderLabelService, {
provide: TrackingService,
useClass: TrackingMockService,
......
......@@ -23,8 +23,6 @@ import { StorageService } from '../../service/storage/storage.service';
import { StorageServiceMock } from '../../service/storage/storage.service.mock';
import { TrackingMockService } from '../../service/tracking/tracking.mock.service';
import { TrackingService } from '../../service/tracking/tracking.service';
import { WebsocketMockService } from '../../service/websocket/websocket.mock.service';
import { WebsocketService } from '../../service/websocket/websocket.service';
import { SharedModule } from '../../shared/shared.module';
import { AvailableQuizzesComponent } from './available-quizzes.component';
......@@ -61,9 +59,6 @@ describe('AvailableQuizzesComponent', () => {
}, FooterBarService, SettingsService, {
provide: ConnectionService,
useClass: ConnectionMockService,
}, {
provide: WebsocketService,
useClass: WebsocketMockService,
}, SharedService, {
provide: FileUploadService,
useClass: FileUploadMockService,
......
......@@ -20,8 +20,6 @@ import { SharedService } from '../../../service/shared/shared.service';
import { IndexedDbService } from '../../../service/storage/indexed.db.service';
import { StorageService } from '../../../service/storage/storage.service';
import { StorageServiceMock } from '../../../service/storage/storage.service.mock';
import { WebsocketMockService } from '../../../service/websocket/websocket.mock.service';
import { WebsocketService } from '../../../service/websocket/websocket.service';
import { SharedModule } from '../../../shared/shared.module';
import { ConfidenceRateComponent } from './confidence-rate.component';
......@@ -57,10 +55,7 @@ describe('QuizFlow: ConfidenceRateComponent', () => {
}, {
provide: QuizService,
useClass: QuizMockService,
}, HeaderLabelService, FooterBarService, {
provide: WebsocketService,
useClass: WebsocketMockService,
}, SharedService, SettingsService, MemberApiService,
}, HeaderLabelService, FooterBarService, SharedService, SettingsService, MemberApiService,
],
declarations: [ConfidenceRateComponent],
}).compileComponents();
......
import { Component, Inject, OnDestroy, PLATFORM_ID } from '@angular/core';
import { Component, Inject, OnDestroy, OnInit, PLATFORM_ID } from '@angular/core';
import { Router } from '@angular/router';
import { NgbModal, NgbModalRef } from '@ng-bootstrap/ng-bootstrap';
import { SimpleMQ } from 'ng2-simple-mq';
import { Subscription } from 'rxjs';
import { environment } from '../../../../environments/environment';
import { AutoUnsubscribe } from '../../../../lib/AutoUnsubscribe';
......@@ -21,7 +22,7 @@ import { QuizService } from '../../../service/quiz/quiz.service';
styleUrls: ['./confidence-rate.component.scss'],
}) //
@AutoUnsubscribe('_subscriptions')
export class ConfidenceRateComponent implements OnDestroy {
export class ConfidenceRateComponent implements OnInit, OnDestroy {
public static TYPE = 'ConfidenceRateComponent';
private _confidenceValue = 100;
......@@ -32,7 +33,8 @@ export class ConfidenceRateComponent implements OnDestroy {
private _serverUnavailableModal: NgbModalRef;
// noinspection JSMismatchedCollectionQueryUpdate
private _subscriptions: Array<Subscription> = [];
private readonly _subscriptions: Array<Subscription> = [];
private readonly _messageSubscriptions: Array<string> = [];
constructor(
public quizService: QuizService,
......@@ -43,21 +45,22 @@ export class ConfidenceRateComponent implements OnDestroy {
private headerLabelService: HeaderLabelService,
private footerBarService: FooterBarService,
private memberApiService: MemberApiService,
private ngbModal: NgbModal,
private ngbModal: NgbModal, private messageQueue: SimpleMQ,
) {
headerLabelService.headerLabel = 'component.liveResults.confidence_grade';
this.footerBarService.replaceFooterElements([]);
}
public ngOnInit(): void {
this._subscriptions.push(this.quizService.quizUpdateEmitter.subscribe(quiz => {
if (!quiz) {
return;
}
this.initData();
}));
this.quizService.loadDataToPlay(sessionStorage.getItem(StorageKey.CurrentQuizName));
this.quizService.loadDataToPlay(sessionStorage.getItem(StorageKey.CurrentQuizName)).then(() => {
this.handleMessages();
});
this._subscriptions.push(this.connectionService.serverStatusEmitter.subscribe(isConnected => {
if (isConnected) {
......@@ -78,15 +81,9 @@ export class ConfidenceRateComponent implements OnDestroy {
}));
}
public initData(): void {
this.connectionService.initConnection().then(() => {
this.connectionService.connectToChannel(this.quizService.quiz.name);
this.handleMessages();
});
}
public ngOnDestroy(): void {
this._subscriptions.forEach(sub => sub.unsubscribe());
this._messageSubscriptions.forEach(id => this.messageQueue.unsubscribe(id));
}
public getConfidenceLevelTranslation(): string {
......@@ -114,48 +111,37 @@ export class ConfidenceRateComponent implements OnDestroy {
}
private handleMessages(): void {
this._subscriptions.push(this.connectionService.dataEmitter.subscribe((data: IMessage) => {
switch (data.step) {
case MessageProtocol.NextQuestion:
this.quizService.quiz.currentQuestionIndex = data.payload.nextQuestionIndex;
break;
case MessageProtocol.Start:
this.quizService.quiz.currentStartTimestamp = data.payload.currentStartTimestamp;
this._messageSubscriptions.push(...[
this.messageQueue.subscribe(MessageProtocol.NextQuestion, payload => {
this.quizService.quiz.currentQuestionIndex = payload.nextQuestionIndex;
}), this.messageQueue.subscribe(MessageProtocol.Start, payload => {
this.quizService.quiz.currentStartTimestamp = payload.currentStartTimestamp;
this.router.navigate(['/quiz', 'flow', 'voting']);
}), this.messageQueue.subscribe(MessageProtocol.Stop, payload => {
this.router.navigate(['/quiz', 'flow', 'results']);
}), this.messageQueue.subscribe(MessageProtocol.UpdatedResponse, payload => {
console.log('ConfidenceRateComponent: modify response data for nickname', payload.nickname);
this.attendeeService.modifyResponse(payload);
}), this.messageQueue.subscribe(MessageProtocol.UpdatedSettings, payload => {
this.quizService.quiz.sessionConfig = payload.sessionConfig;
}), this.messageQueue.subscribe(MessageProtocol.ReadingConfirmationRequested, payload => {
if (environment.readingConfirmationEnabled) {
this.router.navigate(['/quiz', 'flow', 'reading-confirmation']);
} else {
this.router.navigate(['/quiz', 'flow', 'voting']);
break;
case MessageProtocol.Stop:
this.router.navigate(['/quiz', 'flow', 'results']);
break;
case MessageProtocol.UpdatedResponse:
console.log('ConfidenceRateComponent: modify response data for nickname', data.payload.nickname);
this.attendeeService.modifyResponse(data.payload);
break;
case MessageProtocol.UpdatedSettings:
this.quizService.quiz.sessionConfig = data.payload.sessionConfig;
break;
case MessageProtocol.ReadingConfirmationRequested:
if (environment.readingConfirmationEnabled) {
this.router.navigate(['/quiz', 'flow', 'reading-confirmation']);
} else {
this.router.navigate(['/quiz', 'flow', 'voting']);
}
break;
case MessageProtocol.Reset:
this.attendeeService.clearResponses();
this.quizService.quiz.currentQuestionIndex = -1;
this.router.navigate(['/quiz', 'flow', 'lobby']);
break;
case MessageProtocol.Added:
this.attendeeService.addMember(data.payload.member);
break;
case MessageProtocol.Removed:
this.attendeeService.removeMember(data.payload.name);
break;
case MessageProtocol.Closed:
this.router.navigate(['/']);
break;
}
}));
}
}), this.messageQueue.subscribe(MessageProtocol.Reset, payload => {
this.attendeeService.clearResponses();
this.quizService.quiz.currentQuestionIndex = -1;
this.router.navigate(['/quiz', 'flow', 'lobby']);
}), this.messageQueue.subscribe(MessageProtocol.Added, payload => {
this.attendeeService.addMember(payload.member);
}), this.messageQueue.subscribe(MessageProtocol.Removed, payload => {
this.attendeeService.removeMember(payload.name);
}), this.messageQueue.subscribe(MessageProtocol.Closed, payload => {
this.router.navigate(['/']);
}),
]);
}
}
<h4>
<span *ngIf="isGlobalRanking">
{{'component.leaderboard.title.all_questions' | translate }}
</span>
<span *ngIf="!isGlobalRanking">
{{'component.leaderboard.title.single_question' | translate:{QUESTION_ID: (questionIndex + 1)} }}
</span>
<h4 *ngIf="!isGlobalRanking">
{{'component.leaderboard.title.single_question' | translate:{QUESTION_ID: (questionIndex + 1)} }}
</h4>
<h4 *ngIf="!leaderBoardCorrect.length"
......@@ -52,8 +47,8 @@
<div class="col-12">
<h5 *ngIf="hasOwnResponse()"
class="mb-0 mt-5 text-center">
<span>{{'component.leaderboard.own-rank.own-data' | translate:{INDEX: ownResponse.index + 1, SCORE: ownResponse.element.score} }}</span>
<span *ngIf="ownResponse.closestOpponent">{{'component.leaderboard.own-rank.closest-opponent' | translate:{NAME: ownResponse.closestOpponent.name, SCORE: ownResponse.closestOpponent.score} }}</span>
<span>{{'component.leaderboard.own-rank.own-data' | translate:{INDEX: ownResponse.index + 1, SCORE: ownResponse.element?.score} }}</span>
<span *ngIf="ownResponse.closestOpponent">{{'component.leaderboard.own-rank.closest-opponent' | translate:{NAME: ownResponse.closestOpponent?.name, SCORE: ownResponse.closestOpponent?.score} }}</span>
</h5>
</div>
</ng-template>
\ No newline at end of file
</ng-template>
......@@ -24,8 +24,6 @@ import { StorageService } from '../../../service/storage/storage.service';
import { StorageServiceMock } from '../../../service/storage/storage.service.mock';
import { TrackingMockService } from '../../../service/tracking/tracking.mock.service';
import { TrackingService } from '../../../service/tracking/tracking.service';
import { WebsocketMockService } from '../../../service/websocket/websocket.mock.service';
import { WebsocketService } from '../../../service/websocket/websocket.service';
import { SharedModule } from '../../../shared/shared.module';
import { LeaderboardComponent } from './leaderboard.component';
......@@ -59,9 +57,6 @@ describe('LeaderboardComponent', () => {
}, FooterBarService, SettingsService, {
provide: ConnectionService,
useClass: ConnectionMockService,
}, {
provide: WebsocketService,
useClass: WebsocketMockService,
}, SharedService, {
provide: QuizService,
useClass: QuizMockService,
......
import { isPlatformBrowser } from '@angular/common';
import { Component, Inject, OnDestroy, PLATFORM_ID, SecurityContext } from '@angular/core';
import { Component, Inject, OnDestroy, OnInit, PLATFORM_ID, SecurityContext } from '@angular/core';
import { DomSanitizer, SafeHtml } from '@angular/platform-browser';
import { ActivatedRoute, Router } from '@angular/router';
import { NgbModal, NgbModalRef } from '@ng-bootstrap/ng-bootstrap';
import { ILeaderBoardItem } from 'arsnova-click-v2-types/dist/common';
import { SimpleMQ } from 'ng2-simple-mq';
import { Subscription } from 'rxjs';
import { environment } from '../../../../environments/environment';
import { AutoUnsubscribe } from '../../../../lib/AutoUnsubscribe';
import { StorageKey } from '../../../../lib/enums/enums';
import { MessageProtocol } from '../../../../lib/enums/Message';
import { QuestionType } from '../../../../lib/enums/QuestionType';
import { IMessage } from '../../../../lib/interfaces/communication/IMessage';
import { parseGithubFlavoredMarkdown } from '../../../../lib/markdown/markdown';
import { ServerUnavailableModalComponent } from '../../../modals/server-unavailable-modal/server-unavailable-modal.component';
import { LeaderboardApiService } from '../../../service/api/leaderboard/leaderboard-api.service';
......@@ -27,7 +27,7 @@ import { QuizService } from '../../../service/quiz/quiz.service';
styleUrls: ['./leaderboard.component.scss'],
}) //
@AutoUnsubscribe('_subscriptions')
export class LeaderboardComponent implements OnDestroy {
export class LeaderboardComponent implements OnInit, OnDestroy {
public static TYPE = 'LeaderboardComponent';
public isLoadingData = true;
......@@ -71,6 +71,7 @@ export class LeaderboardComponent implements OnDestroy {
private _name: string;
// noinspection JSMismatchedCollectionQueryUpdate
private readonly _subscriptions: Array<Subscription> = [];
private readonly _messageSubscriptions: Array<string> = [];
constructor(
@Inject(PLATFORM_ID) private platformId: Object,
......@@ -84,11 +85,12 @@ export class LeaderboardComponent implements OnDestroy {
private connectionService: ConnectionService,
private i18nService: I18nService,
private leaderboardApiService: LeaderboardApiService,
private ngbModal: NgbModal,
private ngbModal: NgbModal, private messageQueue: SimpleMQ,
) {
this.footerBarService.TYPE_REFERENCE = LeaderboardComponent.TYPE;
}
public ngOnInit(): void {
this._subscriptions.push(this.quizService.quizUpdateEmitter.subscribe(quiz => {
if (!quiz) {
return;
......@@ -100,7 +102,9 @@ export class LeaderboardComponent implements OnDestroy {
this.addFooterElements();
}));
this.quizService.loadDataToPlay(sessionStorage.getItem(StorageKey.CurrentQuizName));
this.quizService.loadDataToPlay(sessionStorage.getItem(StorageKey.CurrentQuizName)).then(() => {
this.handleMessages();
});
this._subscriptions.push(this.connectionService.serverStatusEmitter.subscribe(isConnected => {
if (isConnected) {
......@@ -123,6 +127,7 @@ export class LeaderboardComponent implements OnDestroy {
public ngOnDestroy(): void {
this._subscriptions.forEach(sub => sub.unsubscribe());
this._messageSubscriptions.forEach(id => this.messageQueue.unsubscribe(id));
}
public sanitizeHTML(value: string): SafeHtml {
......@@ -161,17 +166,12 @@ export class LeaderboardComponent implements OnDestroy {
}
public hasOwnResponse(): boolean {
return Object.keys(this._ownResponse || {}).length > 0;
return Object.keys(this._ownResponse || {}).length > 1;
}
private initData(): void {
this.route.params.subscribe(params => {
this.connectionService.initConnection().then(() => {
this.connectionService.connectToChannel(this.quizService.quiz.name);
this.handleMessages();
});
this._questionIndex = +params['questionIndex'];
this._isGlobalRanking = isNaN(this._questionIndex);
if (this._isGlobalRanking) {
......@@ -203,36 +203,29 @@ export class LeaderboardComponent implements OnDestroy {
}
private handleMessages(): void {
this._subscriptions.push(this.connectionService.dataEmitter.subscribe((data: IMessage) => {
switch (data.step) {
case MessageProtocol.Start:
this.router.navigate(['/quiz', 'flow', 'voting']);
break;
case MessageProtocol.UpdatedResponse:
console.log('LeaderboardComponent: modify response data for nickname', data.payload.nickname);
this.attendeeService.modifyResponse(data.payload);
break;
case MessageProtocol.UpdatedSettings:
this.quizService.quiz.sessionConfig = data.payload.sessionConfig;
break;
case MessageProtocol.Reset:
this.attendeeService.clearResponses();
this.quizService.quiz.currentQuestionIndex = -1;
this.router.navigate(['/quiz', 'flow', 'lobby']);
break;
case MessageProtocol.Removed:
if (isPlatformBrowser(this.platformId)) {
const existingNickname = sessionStorage.getItem(StorageKey.CurrentNickName);
if (existingNickname === data.payload.name) {
this.router.navigate(['/']);
}
this._messageSubscriptions.push(...[
this.messageQueue.subscribe(MessageProtocol.Start, payload => {
this.router.navigate(['/quiz', 'flow', 'voting']);
}), this.messageQueue.subscribe(MessageProtocol.UpdatedResponse, payload => {
console.log('LeaderboardComponent: modify response data for nickname', payload.nickname);
this.attendeeService.modifyResponse(payload);
}), this.messageQueue.subscribe(MessageProtocol.UpdatedSettings, payload => {
this.quizService.quiz.sessionConfig = payload.sessionConfig;
}), this.messageQueue.subscribe(MessageProtocol.Reset, payload => {
this.attendeeService.clearResponses();
this.quizService.quiz.currentQuestionIndex = -1;
this.router.navigate(['/quiz', 'flow', 'lobby']);
}), this.messageQueue.subscribe(MessageProtocol.Removed, payload => {
if (isPlatformBrowser(this.platformId)) {
const existingNickname = sessionStorage.getItem(StorageKey.CurrentNickName);
if (existingNickname === payload.name) {
this.router.navigate(['/']);
}
break;
case MessageProtocol.Closed:
this.router.navigate(['/']);
break;
}
}));
}
}), this.messageQueue.subscribe(MessageProtocol.Closed, payload => {
this.router.navigate(['/']);
}),
]);
}
private addFooterElements(): void {
......
import { NgModule } from '@angular/core';
import { RouterModule, Routes } from '@angular/router';
import { NgxQRCodeModule } from '@techiediaries/ngx-qrcode';
import { QRCodeModule } from 'angularx-qrcode';
import { MarkdownModule } from '../../markdown/markdown.module';
import { CasLoginService } from '../../service/login/cas-login.service';
import { SharedModule } from '../../shared/shared.module';
......@@ -65,7 +65,7 @@ export const quizFlowRoutes: Routes = [
@NgModule({
imports: [
MarkdownModule, SharedModule, ThemesModule, RouterModule.forChild(quizFlowRoutes), QuizResultsModule, NgxQRCodeModule, QuizFlowSharedModule,
MarkdownModule, SharedModule, ThemesModule, RouterModule.forChild(quizFlowRoutes), QuizResultsModule, QRCodeModule, QuizFlowSharedModule,
],
bootstrap: [EditModeConfirmComponent, QrCodeContentComponent],
declarations: [
......
......@@ -9,10 +9,10 @@
</div>
<div class="modal-body pt-0">
<div class="d-flex flex-column align-items-center qrCodeContent">
<ngx-qrcode [qrc-value]="qrCodeContent"
qrc-element-type="img"
qrc-errorCorrectionLevel="L">
</ngx-qrcode>
<qrcode [level]="'M'"
[qrdata]="qrCodeContent"
[size]="512"
class="px-3 pb-4"></qrcode>
<h6 class="mb-0 text-break text-center">{{qrCodeContent}}</h6>
</div>
</div>
......@@ -29,8 +29,6 @@ import { ThemesMockService } from '../../../service/themes/themes.mock.service';
import { ThemesService } from '../../../service/themes/themes.service';
import { TrackingMockService } from '../../../service/tracking/tracking.mock.service';
import { TrackingService } from '../../../service/tracking/tracking.service';
import { WebsocketMockService } from '../../../service/websocket/websocket.mock.service';
import { WebsocketService } from '../../../service/websocket/websocket.service';
import { SharedModule } from '../../../shared/shared.module';