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

Run poll item toggle #267

Merged
merged 9 commits into from
May 8, 2021
Merged
Show file tree
Hide file tree
Changes from all 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
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,10 @@
<!-- Step 1 - Select item type -->
<div *ngIf="step === 1">
<nz-radio-group [(ngModel)]="itemType">
<label *ngFor="let type of itemTypes" nz-radio [nzValue]='type.id'>
<strong>{{type.name}}</strong><br>
<label *ngFor="let type of itemTypes" nz-radio [nzValue]='type.id' [nzDisabled]="!type.available">
<strong>{{type.name}}</strong>
<nz-tag *ngIf="!type.available" class="available-soon" nzColor="processing">available soon!</nz-tag>
<br>
<span class="radio-description"><em>{{type.description}}</em></span>
</label>
</nz-radio-group>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,3 +29,6 @@ nz-content

.wrong-answer
color: #ff194f

.available-soon
margin-left: 10px
Original file line number Diff line number Diff line change
Expand Up @@ -21,27 +21,32 @@ const ITEM_TYPES = [
{
id: 1,
name: 'Open Text Question',
description: 'Enables the user to fill in a text as answer'
description: 'Enables the user to fill in a text as answer.',
available: true
},
{
id: 2,
name: 'Multiple Choice Question',
description: 'Lets the user choose between several, pre-defined answers'
description: 'Lets the user choose between several, pre-defined answers.',
available: true
},
{
id: 3,
name: 'Quiz Question',
description: 'Multiple choice question, which displays the right answer afterwards'
description: 'Multiple choice question which displays the right answer afterwards.',
available: true
},
{
id: 4,
name: 'Word Cloud Question',
description: 'Single word can be entered. The words will be arranged in form of clouds'
description: 'Single word can be entered. The words will be arranged in form of clouds.',
available: false
},
{
id: 5,
name: 'Rating Question',
description: 'Star rating.'
description: 'Star rating.',
available: false
}
];

Expand Down
2 changes: 0 additions & 2 deletions src/app/model/quiz-item-answer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,4 @@
export class QuizItemAnswer {
id: number;
selectionOption: string;
isCorrect: boolean;
answerCount: number;
}
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ <h1 class="poll-name">{{poll?.name}}</h1>
<h2>{{activeItem?.question}}</h2>

<!-- Loading -->
<nz-spin *ngIf="activeItemType === ''" nzSize="large"></nz-spin>
<nz-spin *ngIf="loading" nzSize="large"></nz-spin>

<!-- Multiple Choice Question -->
<div class="poll-item-selection-options" *ngSwitchCase="'multiple-choice'">
Expand Down Expand Up @@ -50,6 +50,14 @@ <h2>{{activeItem?.question}}</h2>
nzTitle="Answer was sent"
nzSubTitle="Waiting for the presenter to select another question ...">
</nz-result>

<!-- Waiting for presenter -->
<nz-result
*ngIf="!poll.currentItem"
nzStatus="info"
nzTitle="Waiting for presenter"
nzSubTitle="Waiting for the presenter to start the poll ...">
</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>
35 changes: 28 additions & 7 deletions src/app/pages/poll-participants/poll-participants.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,12 +21,12 @@ export class PollParticipantsComponent implements OnInit, OnDestroy {

// Variables
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;
loading = true;

/**
* Initialize component
Expand All @@ -52,13 +52,33 @@ export class PollParticipantsComponent implements OnInit, OnDestroy {
// 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;
if (Object.keys(pollItem).length > 1) {
// Load poll
if (!this.poll) {
this.pollService.get(pollItem.pollId).subscribe(poll => this.poll = poll);
} else {
this.poll.currentItem = pollItem.itemId;
}
// Randomize selection options if it is a quiz item
if (pollItem.type === 'quiz') {
marcauberer marked this conversation as resolved.
Show resolved Hide resolved
pollItem.answers = this.toolsService.shuffleList(pollItem.answers);
}
// Update UI
this.activeItemType = pollItem.type;
delete pollItem.type;
this.activeItem = pollItem;
} else {
// Load poll
if (!this.poll) {
this.pollService.get(pollItem.id).subscribe(poll => this.poll = poll);
} else {
this.poll.currentItem = null;
}
this.activeItem = null;
this.activeItemType = '';
}
this.sent = false;
this.loading = false;
});
});
}
Expand Down Expand Up @@ -88,6 +108,7 @@ export class PollParticipantsComponent implements OnInit, OnDestroy {
}
if (this.websocketService.sendAnswer(this.activeItem.itemId, answerItem)) {
this.sent = true;
this.answer = null;
} else {
this.toolsService.showErrorMessage('Could not send answer. Please try again. If the problem occurs again, please try to reload the page.');
}
Expand Down
11 changes: 7 additions & 4 deletions src/app/pages/poll/poll.component.html
Original file line number Diff line number Diff line change
Expand Up @@ -99,18 +99,21 @@
</ngx-charts-bar-horizontal>
</div>
</div>
<button nz-button nzType="default" class="preview-button"
[routerLink]="'/p/' + poll.slug + '/' + pollItem.position">
Preview Question<i nz-icon nzType="right"></i>
</button>

<!-- Header -->
<ng-template #header>
<span class="poll-item-title">{{pollItem.question}}</span>
</ng-template>
<!-- Header options -->
<ng-template #options>
<nz-tag *ngIf="poll.currentItem === pollItem.itemId" nzColor="green">
<i nz-icon nzType="loading"></i>
<span>Running</span>
</nz-tag>
<nz-tag nzColor="default">{{pollItem.type}}</nz-tag>
<nz-switch class="run-item-switch" nzSize="small" [ngModel]="poll.currentItem === pollItem.itemId"
(click)="onRunPollItem($event, pollItem.itemId)" [nzLoading]="loadingRunPollItemId === pollItem.itemId">
</nz-switch>
<button nz-button nzType="primary" [nzSize]="p.nzActive ? 'default' : 'small'"
(click)="openEditPollItemDialog($event)">
<i nz-icon nzType="edit"></i>Edit
Expand Down
6 changes: 2 additions & 4 deletions src/app/pages/poll/poll.component.sass
Original file line number Diff line number Diff line change
Expand Up @@ -26,10 +26,8 @@
.slug
margin-left: -2px

.preview-button
float: right
margin-top: 5px
margin-bottom: 10px
.run-item-switch
margin-right: 10px

// -------------- Drag & Drop CSS --------------

Expand Down
26 changes: 24 additions & 2 deletions src/app/pages/poll/poll.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ export class PollComponent {
poll: Poll;
pollId: number;
changingState = false;
loadingRunPollItemId = 0;
showNewPollItemDialog = false;
error = false;
results = [];
Expand Down Expand Up @@ -100,6 +101,25 @@ export class PollComponent {
});
}

/**
* Update the current poll item for this poll on the server
*
* @param event Click event
* @param pollItemId Id of the poll item
*/
onRunPollItem(event: MouseEvent, pollItemId: number): void {
event.stopPropagation();
const oldPollItem = this.poll.currentItem;
this.poll.currentItem = this.loadingRunPollItemId = pollItemId === this.poll.currentItem ? null : pollItemId;
marcauberer marked this conversation as resolved.
Show resolved Hide resolved
this.pollService.update(this.poll).subscribe((_) => {
this.loadingRunPollItemId = -1;
marcauberer marked this conversation as resolved.
Show resolved Hide resolved
}, (_) => {
this.poll.currentItem = oldPollItem;
this.loadingRunPollItemId = -1;
this.tools.showErrorMessage('Something went wrong. Please try again');
});
}

/**
* Change the poll state on the server
*
Expand Down Expand Up @@ -166,7 +186,7 @@ export class PollComponent {
*/
updatePoll(callback: () => void, error?: () => void): void {
error = error ?? function(): void {
this.tools.showErrorMessage('The change could not be committed on the server. Please try again later.');
this.tools.showErrorMessage('The change could not be committed onto the server. Please try again later.');
};

this.pollService.update(this.poll).subscribe(callback, error);
Expand Down Expand Up @@ -201,6 +221,8 @@ export class PollComponent {
*/
drop(event: CdkDragDrop<string[]>): void {
moveItemInArray(this.poll.pollItems, event.previousIndex, event.currentIndex);
// Update position on server
// TODO: Ask team what to do when dropping item, because I would have to do a API request for every position update
}

/**
Expand Down Expand Up @@ -260,7 +282,7 @@ export class PollComponent {
/**
* Shows the dialog a specific poll item
*/
openEditPollItemDialog(event: any): void {
openEditPollItemDialog(event: MouseEvent): void {
event.stopPropagation();
// Open edit dialog
this.showEditPollItemDialog = true;
Expand Down
4 changes: 3 additions & 1 deletion src/app/pages/poll/poll.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ import {NzCollapseModule} from 'ng-zorro-antd/collapse';
import {DragDropModule} from '@angular/cdk/drag-drop';
import {NgxChartsModule} from '@swimlane/ngx-charts';
import {NzStatisticModule} from 'ng-zorro-antd/statistic';
import {NzSwitchModule} from 'ng-zorro-antd/switch';

@NgModule({
declarations: [PollComponent],
Expand Down Expand Up @@ -65,7 +66,8 @@ import {NzStatisticModule} from 'ng-zorro-antd/statistic';
NzCollapseModule,
DragDropModule,
NgxChartsModule,
NzStatisticModule
NzStatisticModule,
NzSwitchModule
]
})
export class PollModule { }
22 changes: 22 additions & 0 deletions src/app/service/common-tools.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -78,4 +78,26 @@ export class CommonToolsService {
.replace(/([A-Z])([A-Z])(?=[a-z])/g, '$1-$2')
.toLowerCase();
}

// Fisher-Yates Shuffle
// https://bost.ocks.org/mike/shuffle/
shuffleList(array: any[]): any[] {
marcauberer marked this conversation as resolved.
Show resolved Hide resolved
let currentIndex = array.length;
let temp: number;
let randomIndex: number;

// While there remain elements to shuffle
while (currentIndex !== 0) {
// Pick a remaining element
randomIndex = Math.floor(Math.random() * currentIndex);
currentIndex--;

// And swap it with the current element
temp = array[currentIndex];
array[currentIndex] = array[randomIndex];
array[randomIndex] = temp;
}

return array;
}
}
1 change: 0 additions & 1 deletion src/app/service/websocket.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,6 @@ export class WebsocketService {
* @param answer Answer object, which will be serialized
*/
sendAnswer(pollItemId: number, answer: MultipleChoiceItemAnswerParticipant): boolean {
console.log(answer);
if (this.stompClient.connected) {
this.stompClient.publish({
destination: ENDPOINT_MESSAGING_WRITE_URL + '/' + pollItemId,
Expand Down