Commit 401dba8d authored by Christopher Mark Fullarton's avatar Christopher Mark Fullarton
Browse files

Adds ui improvements. Remembers the selected question index in the results and...

Adds ui improvements. Remembers the selected question index in the results and reuses it when navigating back to it
parent 9e07cd8c
......@@ -11,7 +11,7 @@
"dependency-check": "npx --ignore-existing madge --circular --extensions ts src",
"ng": "ng",
"start:SSR": "cd dist && node server",
"start:DEV": "ng serve --host 0.0.0.0 --port 4210 --disable-host-check --aot",
"start:DEV": "ng serve --host 192.168.2.101 --port 4210 --aot",
"build:SSR": "npm run build:PROD:DEPLOY && npm run build:SERVER && npm run webpack:SERVER",
"build:SERVER": "ng run frontend:server",
"build:PROD": "ng build --prod",
......
......@@ -63,6 +63,7 @@ export class QuizLobbyComponent implements OnDestroy {
private ngbModal: NgbModal,
) {
sessionStorage.removeItem(StorageKey.CurrentQuestionIndex);
this.quizService.loadDataToPlay(sessionStorage.getItem(StorageKey.CurrentQuizName));
this._subscriptions.push(this.quizService.quizUpdateEmitter.subscribe(quiz => {
if (!quiz) {
......
......@@ -107,7 +107,8 @@ export class QuizResultsComponent implements OnInit, OnDestroy {
public hideProgressbarCssStyle(): boolean {
this.cd.markForCheck();
return this._selectedQuestionIndex === this.quizService.quiz.currentQuestionIndex && !!this.countdown;
return typeof this.countdown === 'undefined' || (this.countdown > 0 && this._selectedQuestionIndex
=== this.quizService.quiz.currentQuestionIndex);
}
public showConfidenceRate(questionIndex: number): boolean {
......@@ -207,7 +208,13 @@ export class QuizResultsComponent implements OnInit, OnDestroy {
return;
}
this._selectedQuestionIndex = this.quizService.quiz.currentQuestionIndex;
const storedSelectedQuestionIndex = parseInt(sessionStorage.getItem(StorageKey.CurrentQuestionIndex), 10);
if (!isNaN(storedSelectedQuestionIndex)) {
this.modifyVisibleQuestion(storedSelectedQuestionIndex);
sessionStorage.removeItem(StorageKey.CurrentQuestionIndex);
} else {
this.modifyVisibleQuestion(this.quizService.quiz.currentQuestionIndex);
}
this.attendeeService.restoreMembers().then(() => {
this.initData();
});
......@@ -236,6 +243,7 @@ export class QuizResultsComponent implements OnInit, OnDestroy {
}
public ngOnDestroy(): void {
sessionStorage.setItem(StorageKey.CurrentQuestionIndex, String(this._selectedQuestionIndex));
this.footerBarService.footerElemBack.restoreClickCallback();
this._subscriptions.forEach(sub => sub.unsubscribe());
}
......@@ -299,9 +307,8 @@ export class QuizResultsComponent implements OnInit, OnDestroy {
const question = this.quizService.currentQuestion();
this.generateAnswers(question);
if (!this.countdown) {
this.countdown = 0;
if (question.timer === 0 && !currentStateData.payload.readingConfirmationRequested && this.attendeeService.attendees.some(
nick => nick.responses[this.quizService.quiz.currentQuestionIndex].responseTime === -1)) {
this.showStartQuizButton = false;
......
......@@ -61,6 +61,10 @@
<button (click)="sendResponses()"
class="btn btn-info btn-lg mx-3 px-sm-5 mx-sm-auto flex-grow-1 flex-sm-grow-0">
<span class="mr-2">{{'component.voting.send' | translate}}</span>
<fa-icon [icon]="'paper-plane'"></fa-icon>
<fa-icon *ngIf="isSendingResponse"
[icon]="'spinner'"
[spin]="true"></fa-icon>
<fa-icon *ngIf="!isSendingResponse"
[icon]="'paper-plane'"></fa-icon>
</button>
</div>
......@@ -31,6 +31,7 @@ import { QuizService } from '../../../service/quiz/quiz.service';
@AutoUnsubscribe('_subscriptions')
export class VotingComponent implements OnDestroy {
public static TYPE = 'VotingComponent';
public isSendingResponse: boolean;
private _answers: Array<string> = [];
......@@ -171,6 +172,8 @@ export class VotingComponent implements OnDestroy {
}
public sendResponses(route?: string): void {
this.isSendingResponse = true;
if (this.countdown) {
this.countdown.onChange.unsubscribe();
this.countdown.stop();
......
......@@ -111,6 +111,7 @@ export class HomeComponent implements OnInit, OnDestroy {
public sharedService: SharedService,
) {
sessionStorage.removeItem(StorageKey.CurrentQuestionIndex);
this.footerBarService.TYPE_REFERENCE = HomeComponent.TYPE;
headerLabelService.headerLabel = 'default';
......
{
"ssrEndpoint": "http://localhost:4000",
"serverEndpoint": "http://localhost:3010",
"httpApiEndpoint": "http://localhost:3010/api/v1",
"httpLibEndpoint": "http://localhost:3010/lib",
"wsApiEndpoint": "ws://localhost:3010"
"ssrEndpoint": "http://192.168.2.101:4000",
"serverEndpoint": "http://192.168.2.101:3010",
"httpApiEndpoint": "http://192.168.2.101:3010/api/v1",
"httpLibEndpoint": "http://192.168.2.101:3010/lib",
"wsApiEndpoint": "ws://192.168.2.101:3010"
}
\ No newline at end of file
<!doctype html>
<html>
<head>
<title>arsnova.click</title>
</head>
<body>
Your browser is unsupported!
It is missing the following features:
<ul id="list"></ul>
<p lang="en"
style="display: none;">Your browser is unsupported!<br/>Please check which browser supports the required features (click on Details of every item) to use arsnova.click</p>
<p lang="de"
style="display: none;">Dein Browser wird nicht unterstützt!<br/>Bitte prüfe, welcher Browser die erforderlichen Features unterstützt (klicke auf Details in jedem Element der Liste) um arsnova.click nutzen zu können</p>
<p lang="en"
style="display: none;">Your browser is missing the following mandatory features:</p>
<p lang="de"
style="display: none;">Dein Browser unterstützt nicht die folgenden erforderlichen Features:</p>
<ul id="list-required"></ul>
<p>We are only supporting the following browsers:</p>
<ul>
<li>Google Chrome (Desktop): v45</li>
<li>Mozilla Firefox (Desktop): v44</li>
<li>Edge (Desktop): v17</li>
<li>Safari (Desktop): v11.1</li>
<li>Opera (Desktop): v32</li>
<li>Google Chrome (Mobile): v71</li>
<li>Mozilla Firefox (Mobile): v64</li>
<li>Safari (Mobile): v11.4</li>
</ul>
<p lang="en"
style="display: none;">Additional it is missing the following optional features:</p>
<p lang="de"
style="display: none;">Zusätzlich unterstützt er nicht die folgenden optionalen Features:</p>
<ul id="list-optional"></ul>
<script>
var lang = navigator.language.split('-')[0];
var textNodes = document.getElementsByTagName('p');
for (var i = 0; i < textNodes.length; i++) {
if (textNodes.item(i).getAttribute('lang') === lang) {
textNodes.item(i).setAttribute('style', '');
}
}
var fn = function () {
var listNode = document.getElementById('list');
while (listNode.firstChild) {
listNode.removeChild(listNode.firstChild);
var requiredListNode = document.getElementById('list-required');
while (requiredListNode.firstChild) {
requiredListNode.removeChild(requiredListNode.firstChild);
}
var optionalListNode = document.getElementById('list-optional');
while (optionalListNode.firstChild) {
optionalListNode.removeChild(optionalListNode.firstChild);
}
var list = [{label: 'Audio', value: Modernizr.audio},
{label: 'BlobConstructor', value: Modernizr.blobconstructor},
{label: 'IndexedDB', value: Modernizr.indexeddb}, // TODO: Value resolves to a promise
{label: 'ClassList', value: Modernizr.classlist},
{label: 'CORS', value: Modernizr.cors},
{label: 'CSS-Calc', value: Modernizr.csscalc},
{label: 'es5', value: Modernizr.es5},
{label: 'FileInput', value: Modernizr.fileinput},
{label: 'Flexbox', value: Modernizr.flexbox},
{label: 'Flex-wrap', value: Modernizr.flexwrap},
{label: 'Fullscreen', value: Modernizr.fullscreen},
{label: 'JSON', value: Modernizr.json},
{label: 'LocalStorage', value: Modernizr.localstorage},
{label: 'Promises', value: Modernizr.promises},
{label: 'ServiceWorker', value: Modernizr.serviceworker},
{label: 'SessionStorage', value: Modernizr.sessionstorage},
{label: 'SVG', value: Modernizr.svg},
{label: 'Video', value: Modernizr.video},
{label: 'WebSockets', value: Modernizr.websockets},
{label: 'XHR-Response JSON', value: Modernizr.xhrresponsetypejson},
var list = [{label: 'Audio', value: Modernizr.audio, required: false, linkRef: '#feat=audio'},
{label: 'BlobConstructor', value: Modernizr.blobconstructor, required: false, linkRef: '#feat=blobbuilder'},
{label: 'IndexedDB', value: Modernizr.indexeddb, required: true, linkRef: '#feat=indexeddb'}, // TODO: Value resolves to a promise
{label: 'ClassList', value: Modernizr.classlist, required: true, linkRef: '#feat=classlist'},
{label: 'CORS', value: Modernizr.cors, required: true, linkRef: '#feat=cors'},
{label: 'CSS-Calc', value: Modernizr.csscalc, required: true, linkRef: '#feat=calc'},
{label: 'es5', value: Modernizr.es5, required: true, linkRef: '#feat=es5'},
{label: 'FileInput', value: Modernizr.fileinput, required: false, linkRef: '#search=File%20Input'},
{label: 'Flexbox', value: Modernizr.flexbox, required: true, linkRef: '#feat=flexbox'},
{label: 'Flex-wrap', value: Modernizr.flexwrap, required: true, linkRef: '#feat=flexbox'},
{label: 'Fullscreen', value: Modernizr.fullscreen, required: false, linkRef: '#feat=fullscreen'},
{label: 'JSON', value: Modernizr.json, required: true, linkRef: '#feat=json'},
{label: 'LocalStorage', value: Modernizr.localstorage, required: true, linkRef: '#feat=namevalue-storage'},
{label: 'Promises', value: Modernizr.promises, required: true, linkRef: '#feat=promises'},
{label: 'ServiceWorker', value: Modernizr.serviceworker, required: false, linkRef: '#feat=serviceworkers'},
{label: 'SessionStorage', value: Modernizr.sessionstorage, required: true, linkRef: '#feat=namevalue-storage'},
{label: 'SVG', value: Modernizr.svg, required: true, linkRef: '#feat=svg'},
{label: 'Video', value: Modernizr.video, required: false, linkRef: '#feat=video'},
{label: 'WebSockets', value: Modernizr.websockets, required: true, linkRef: '#feat=websockets'},
{label: 'XHR-Response JSON', value: Modernizr.xhrresponsetypejson, required: true, linkRef: '#feat=xhr2'},
]
;
......@@ -54,10 +67,9 @@ It is missing the following features:
}
var node = document.createElement('li');
node.innerText = elem.label;
node.innerHTML = elem.label + ' (<a target="_blank" href="https://caniuse.com/' + elem.linkRef + '">Details</a>)';
node.className = 'failed';
console.log(elem);
document.getElementById('list').appendChild(node);
document.getElementById('list-' + (elem.required ? 'required' : 'optional')).appendChild(node);
});
};
......
......@@ -45,6 +45,7 @@ export enum Project {
}
export enum StorageKey {
CurrentQuestionIndex = 'CurrentQuestionIndex', //
PrivateKey = 'PrivateKey', //
LoginToken = 'LoginToken', //
QuizToken = 'QuizToken', //
......
......@@ -87,7 +87,7 @@ function postMarkdownRenderer(value: string): string {
anchorNode.href = imgNode.src;
anchorNode.target = null;
anchorNode.classList.add(...['highslide', 'd-flex', 'd-sm-block', 'justify-content-center']);
anchorNode.setAttribute('onclick', 'hs.expand(this);return false;');
anchorNode.setAttribute('onclick', 'return hs.expand(this);');
anchorNode.appendChild(imgNode);
value = value.replace(token, anchorNode.outerHTML);
......
......@@ -26,8 +26,10 @@ body {
}
.thumbnail {
height: 200px;
width: auto;
height: auto;
max-width: 100%;
max-height: 200px;
}
#theme-wrapper {
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment