Skip to content
This repository has been archived by the owner on Dec 9, 2022. It is now read-only.

Participant view web socket connection #250

Merged
merged 9 commits into from
May 3, 2021
Merged
Show file tree
Hide file tree
Changes from 6 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
39 changes: 39 additions & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@
"@angular/platform-browser-dynamic": "~11.2.11",
"@angular/router": "~11.2.11",
"@angular/service-worker": "~11.2.11",
"@stomp/rx-stomp": "^1.1.2",
"@swimlane/ngx-charts": "^17.0.1",
"@types/crypto-js": "^4.0.1",
"component": "^1.1.0",
Expand Down
13 changes: 13 additions & 0 deletions src/app/model/multiple-choice-item-answer-participant.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
/*
* Copyright © Live-Poll 2020-2021. All rights reserved
*/

/**
* MultipleChoiceItemAnswerParticipant class.
* Represents one possible answer for a multiple choice question.
*/
export class MultipleChoiceItemAnswerParticipant {
id: number;
type = 'multiple-choice';
selectionOption: string;
}
1 change: 1 addition & 0 deletions src/app/model/multiple-choice-item-answer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
* Represents one possible answer for a multiple choice question.
*/
export class MultipleChoiceItemAnswer {
id: number;
selectionOption: string;
answerCount: number;
}
1 change: 1 addition & 0 deletions src/app/model/open-text-item-answer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,5 +7,6 @@
* Represents one possible answer for an open text question.
*/
export class OpenTextItemAnswer {
id: number;
answer: string;
}
1 change: 1 addition & 0 deletions src/app/model/quiz-item-answer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
* Represents one possible answer for a quiz question.
*/
export class QuizItemAnswer {
id: number;
selectionOption: string;
isCorrect: boolean;
answerCount: number;
Expand Down
56 changes: 34 additions & 22 deletions src/app/pages/poll-participants/poll-participants.component.html
Original file line number Diff line number Diff line change
Expand Up @@ -9,35 +9,47 @@
<img src="assets/images/logo.svg" alt="logo">
</a>
</div>
<h1 class="poll-name">{{poll.name}}</h1>
<h1 class="poll-name">{{poll?.name}}</h1>
</nz-header>
<nz-content>
<div class="poll-container" [ngSwitch]="activeItemType">
<h2>{{activeItem.question}}</h2>
<div *ngIf="!sent" class="poll-container" [ngSwitch]="activeItemType">
<h2>{{activeItem?.question}}</h2>

<!-- Multiple Choice Question -->
<div class="poll-item-selection-options" *ngSwitchCase="'multiple-choice'">
<nz-radio-group [(ngModel)]="answer">
<label *ngFor="let answer of activeItem.answers; let i = index" nz-radio nzValue="{{i}}">{{answer.selectionOption}}</label>
<!--<label *ngIf="activeItem.options" nz-radio nzValue="M">Custom answer... <input type="text" nz-input *ngIf="answer === 'M'" /></label>-->
</nz-radio-group>
</div>
<!-- Loading -->
<nz-spin *ngIf="activeItemType === ''" nzSize="large"></nz-spin>

<!-- Open Text Question -->
<div class="poll-item-selection-options" *ngSwitchCase="'open-text'">
<h1>{{activeItem.question}}</h1>
</div>
<!-- Multiple Choice Question -->
<div class="poll-item-selection-options" *ngSwitchCase="'multiple-choice'">
<nz-radio-group [(ngModel)]="answer">
<label *ngFor="let answer of activeItem.answers; let i = index" nz-radio nzValue="{{i}}">{{answer.selectionOption}}</label>
<input *ngIf="activeItem.options?.canSelectMultiple" type="text" nz-input [(ngModel)]="answer"/>
</nz-radio-group>
</div>

<!-- Quiz Question -->
<div class="poll-item-selection-options" *ngSwitchCase="'quiz'">
<h1>{{activeItem.question}}</h1>
</div>
<!-- Open Text Question -->
<div class="poll-item-selection-options" *ngSwitchCase="'open-text'">
<input type="text" nz-input [(ngModel)]="answer" nzSize="large" />
</div>

<button nz-button nzType="primary" nzSize="large" [disabled]="answer == -1" nzBlock>
Submit Answer
<i nz-icon nzType="right"></i>
</button>
<!-- Quiz Question -->
<div class="poll-item-selection-options" *ngSwitchCase="'quiz'">
<nz-radio-group [(ngModel)]="answer">
<label *ngFor="let answer of activeItem.answers; let i = index" nz-radio nzValue="{{i}}">{{answer.selectionOption}}</label>
</nz-radio-group>
</div>

<button *ngIf="activeItemType !== ''" nz-button nzType="primary" nzSize="large" (click)="sendAnswer()" [disabled]="!(answer?.length > 0)" nzBlock>
Submit Answer
<i nz-icon nzType="right"></i>
</button>
</div>
<!-- Already sent -->
<nz-result
*ngIf="sent"
nzStatus="success"
nzTitle="Answer was sent"
nzSubTitle="Waiting for the presenter to select another question ...">
</nz-result>
</nz-content>
<nz-footer class="participants-footer">Provided with ❤ by <a href="https://www.live-poll.de" target="_blank">Live-Poll</a></nz-footer>
</nz-layout>
97 changes: 70 additions & 27 deletions src/app/pages/poll-participants/poll-participants.component.ts
Original file line number Diff line number Diff line change
@@ -1,59 +1,102 @@
/*
* Copyright © Live-Poll 2020-2021. All rights reserved
*/
import {Component, OnInit} from '@angular/core';
import {Component, OnDestroy, OnInit} from '@angular/core';
import {ActivatedRoute} from '@angular/router';
import {Poll} from '../../model/poll';
import {MultipleChoiceItem} from '../../model/multiple-choice-item';
import {ItemType} from '../../model/poll-item';
import {WebsocketService} from '../../service/websocket.service';
import {QuizItem} from '../../model/quiz-item';
import {OpenTextItem} from '../../model/open-text-item';
import {CommonToolsService} from '../../service/common-tools.service';
import {PollService} from '../../service/poll.service';
import {MultipleChoiceItemAnswerParticipant} from '../../model/multiple-choice-item-answer-participant';

@Component({
selector: 'app-poll-participants',
templateUrl: './poll-participants.component.html',
styleUrls: ['./poll-participants.component.sass']
})
export class PollParticipantsComponent implements OnInit {
export class PollParticipantsComponent implements OnInit, OnDestroy {

// Variables
poll: Poll = {id: 1, name: 'Test Poll', pollItems: [], currentItem: 1, slug: 'test', startDate: 0, endDate: 0};
activeItem: MultipleChoiceItem = {
itemId: 1,
pollId: 1,
question: 'How did you like the presentation?',
position: 1,
type: ItemType.MultipleChoice,
answers: [
{selectionOption: 'Option 1', answerCount: 1},
{selectionOption: 'Option 2', answerCount: 10},
{selectionOption: 'Option 3', answerCount: 4}
]
};
activeItemType = 'multiple-choice';
answer = -1;
slug = '';
// poll: Poll = {id: 1, name: 'Test Poll', pollItems: [], currentItem: 1, slug: 'test', startDate: 0, endDate: 0};
poll: Poll;
activeItem: MultipleChoiceItem|QuizItem|OpenTextItem;
activeItemType = '';
answer = null;
sent = false;

/**
* Initialize component
*
* @param route Active route
* @param pollService Injected PollService
* @param websocketService Injected WebSocketService
* @param toolsService Injected CommonToolsService
*/
constructor(
private route: ActivatedRoute
) {
this.route.params.subscribe(params => console.log(params));
}
private route: ActivatedRoute,
private pollService: PollService,
private websocketService: WebsocketService,
private toolsService: CommonToolsService
) {}

/**
* Initialize the participants page
*/
ngOnInit(): void {
// Connect to WebSocket
this.initializeWebSocketConnection();
this.route.params.subscribe(params => {
this.slug = params.slug;
// Connect to WebSocket
const subscription = this.websocketService.establishConnection(this.slug);
subscription.subscribe(pollItem => {
// Load poll
this.pollService.get(pollItem.pollId).subscribe(poll => this.poll = poll);
// Update UI
this.activeItemType = pollItem.type;
delete pollItem.type;
this.activeItem = pollItem;
this.sent = false;
});
});
}

sendAnswer(): void {
let answerItem;
switch (this.activeItemType) {
case 'multiple-choice': {
const activeItem = this.activeItem as MultipleChoiceItem;
answerItem = new MultipleChoiceItemAnswerParticipant();
answerItem.id = activeItem.answers[this.answer].id;
answerItem.selectionOption = activeItem.answers[this.answer].selectionOption;
break;
}
case 'quiz': {
const activeItem = this.activeItem as QuizItem;
/*answerItem = new QuizItemAnswer();
answerItem = activeItem.itemId;
answerItem.selectionOption = activeItem.answers[this.answer].selectionOption;*/
break;
}
case 'open-text': {
/*answerItem = new OpenTextItemAnswer();
answerItem.answer = this.answer;*/
break;
}
}
if (this.websocketService.sendAnswer(this.activeItem.itemId, answerItem)) {
this.sent = true;
} else {
this.toolsService.showErrorMessage('Could not send answer. Please try again. If the problem occurs again, please try to reload the page.');
}
}

/**
* Setup the real-time web socket connection
* Closes the websocket connection before leaving the site
*/
initializeWebSocketConnection(): void {

ngOnDestroy(): void {
this.websocketService.closeConnection();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,9 @@ import {NzRadioModule} from 'ng-zorro-antd/radio';
import {FormsModule} from '@angular/forms';
import {NzButtonModule} from 'ng-zorro-antd/button';
import {NzIconModule} from 'ng-zorro-antd/icon';
import {NzInputModule} from 'ng-zorro-antd/input';
import {NzSpinModule} from 'ng-zorro-antd/spin';
import {NzResultModule} from 'ng-zorro-antd/result';

@NgModule({
declarations: [PollParticipantsComponent],
Expand All @@ -23,7 +26,10 @@ import {NzIconModule} from 'ng-zorro-antd/icon';
NzRadioModule,
FormsModule,
NzButtonModule,
NzIconModule
NzIconModule,
NzInputModule,
NzSpinModule,
NzResultModule
]
})
export class PollParticipantsModule {}
43 changes: 0 additions & 43 deletions src/app/pages/poll/poll.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -159,39 +159,6 @@ export class PollComponent {
this.error = true;
this.tools.showErrorMessage('Something went wrong, loading the poll.');
});

/*// Build header, body and options
const header = new HttpHeaders().set('Content-Type', 'application/json');
const options: any = { header, responseType: 'application/json', observe: 'response', withCredentials: true };
// Send request
this.http.get<string>(env.apiBaseUrl + '/users/' + this.userData.id + '/polls/' + this.pollId, options)
.subscribe((response: HttpResponse<string>) => {
if (response.ok) {
// Parse data
const json = JSON.parse(response.body);
const poll = new Poll();
poll.id = json.id;
poll.name = json.name;
poll.startDate = json.startDate;
poll.endDate = json.endDate;
poll.slug = json.slug;
poll.pollItems = [];
json.pollItems.forEach(item => {
const pollItem = new PollItem();
pollItem.id = item.itemId;
pollItem.question = item.question;
pollItem.pos = item.position;
pollItem.type = item.type;
poll.pollItems.push(pollItem);
});
this.poll = poll;
// Setup result observer
this.setupResultObserver();
}
}, (_) => {
this.error = true;
this.tools.showErrorMessage('Something went wrong, loading the poll.');
});*/
}

/**
Expand All @@ -203,16 +170,6 @@ export class PollComponent {
};

this.pollService.update(this.poll).subscribe(callback, error);

/*// Build header, body and options
const header = new HttpHeaders().set('Content-Type', 'application/json');
const options: any = { header, observe: 'response', withCredentials: true };
const body = { };
// Send request
this.http.put<string>(env.apiBaseUrl + '/users/' + this.userData.id + '/polls/' + this.pollId, body, options)
.subscribe((response: HttpResponse<string>) => {
if (response.ok) callback();
}, (_) => error());*/
}

/**
Expand Down
Loading