Skip to content
GitLab
Projects
Groups
Snippets
Help
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
arsnova-click-v2-frontend
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Labels
Merge Requests
12
Merge Requests
12
Analytics
Analytics
Repository
Value Stream
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Commits
Open sidebar
ARSnova
arsnova-click-v2-frontend
Commits
0d2074a6
Commit
0d2074a6
authored
Nov 16, 2019
by
Christopher Mark Fullarton
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Adds warning if the quiz data can be lost by navigation interactions
parent
4ad94e6c
Changes
23
Hide whitespace changes
Inline
Side-by-side
Showing
23 changed files
with
308 additions
and
46 deletions
+308
-46
src/app/lib/interfaces/IHasTriggeredNavigation.ts
src/app/lib/interfaces/IHasTriggeredNavigation.ts
+3
-0
src/app/modals/server-unavailable-modal/server-unavailable-modal.component.ts
...r-unavailable-modal/server-unavailable-modal.component.ts
+1
-1
src/app/quiz/quiz-flow/confidence-rate/confidence-rate.component.ts
...iz/quiz-flow/confidence-rate/confidence-rate.component.ts
+19
-3
src/app/quiz/quiz-flow/leaderboard/leaderboard.component.ts
src/app/quiz/quiz-flow/leaderboard/leaderboard.component.ts
+13
-7
src/app/quiz/quiz-flow/quiz-flow.module.ts
src/app/quiz/quiz-flow/quiz-flow.module.ts
+5
-0
src/app/quiz/quiz-flow/quiz-lobby/quiz-lobby.component.ts
src/app/quiz/quiz-flow/quiz-lobby/quiz-lobby.component.ts
+15
-7
src/app/quiz/quiz-flow/quiz-results/question-details/question-details.component.ts
...iz-results/question-details/question-details.component.ts
+14
-1
src/app/quiz/quiz-flow/quiz-results/quiz-results.component.html
...p/quiz/quiz-flow/quiz-results/quiz-results.component.html
+2
-0
src/app/quiz/quiz-flow/quiz-results/quiz-results.component.ts
...app/quiz/quiz-flow/quiz-results/quiz-results.component.ts
+11
-1
src/app/quiz/quiz-flow/reading-confirmation/reading-confirmation.component.ts
...ow/reading-confirmation/reading-confirmation.component.ts
+15
-1
src/app/quiz/quiz-flow/voting/voting.component.ts
src/app/quiz/quiz-flow/voting/voting.component.ts
+26
-11
src/app/service/attendee/attendee.service.ts
src/app/service/attendee/attendee.service.ts
+19
-0
src/app/service/footer-bar/footer-bar.service.ts
src/app/service/footer-bar/footer-bar.service.ts
+7
-7
src/app/service/quiz/quiz.service.ts
src/app/service/quiz/quiz.service.ts
+19
-2
src/app/service/show-unload-warning-guard/show-unload-warning.guard.spec.ts
...ow-unload-warning-guard/show-unload-warning.guard.spec.ts
+15
-0
src/app/service/show-unload-warning-guard/show-unload-warning.guard.ts
...ce/show-unload-warning-guard/show-unload-warning.guard.ts
+20
-0
src/app/shared/no-data-error/no-data-error.component.html
src/app/shared/no-data-error/no-data-error.component.html
+16
-0
src/app/shared/no-data-error/no-data-error.component.scss
src/app/shared/no-data-error/no-data-error.component.scss
+0
-0
src/app/shared/no-data-error/no-data-error.component.spec.ts
src/app/shared/no-data-error/no-data-error.component.spec.ts
+25
-0
src/app/shared/no-data-error/no-data-error.component.ts
src/app/shared/no-data-error/no-data-error.component.ts
+40
-0
src/app/shared/shared.module.ts
src/app/shared/shared.module.ts
+5
-3
src/assets/i18n/de.json
src/assets/i18n/de.json
+9
-1
src/assets/i18n/en.json
src/assets/i18n/en.json
+9
-1
No files found.
src/app/lib/interfaces/IHasTriggeredNavigation.ts
0 → 100644
View file @
0d2074a6
export
interface
IHasTriggeredNavigation
{
hasTriggeredNavigation
:
boolean
;
}
src/app/modals/server-unavailable-modal/server-unavailable-modal.component.ts
View file @
0d2074a6
...
...
@@ -13,7 +13,7 @@ export class ServerUnavailableModalComponent implements OnDestroy {
}
public
reloadPage
():
void
{
location
.
reload
(
true
);
window
.
caches
.
keys
().
then
(
keys
=>
Promise
.
all
(
keys
.
map
(
key
=>
window
.
caches
.
delete
(
key
)))).
finally
(()
=>
location
.
reload
(
true
)
);
}
public
ngOnDestroy
():
void
{
...
...
src/app/quiz/quiz-flow/confidence-rate/confidence-rate.component.ts
View file @
0d2074a6
...
...
@@ -9,6 +9,7 @@ import { StorageKey } from '../../../lib/enums/enums';
import
{
MessageProtocol
}
from
'
../../../lib/enums/Message
'
;
import
{
QuizState
}
from
'
../../../lib/enums/QuizState
'
;
import
{
IMessage
}
from
'
../../../lib/interfaces/communication/IMessage
'
;
import
{
IHasTriggeredNavigation
}
from
'
../../../lib/interfaces/IHasTriggeredNavigation
'
;
import
{
ServerUnavailableModalComponent
}
from
'
../../../modals/server-unavailable-modal/server-unavailable-modal.component
'
;
import
{
MemberApiService
}
from
'
../../../service/api/member/member-api.service
'
;
import
{
AttendeeService
}
from
'
../../../service/attendee/attendee.service
'
;
...
...
@@ -22,9 +23,11 @@ import { QuizService } from '../../../service/quiz/quiz.service';
templateUrl
:
'
./confidence-rate.component.html
'
,
styleUrls
:
[
'
./confidence-rate.component.scss
'
],
})
export
class
ConfidenceRateComponent
implements
OnInit
,
OnDestroy
{
export
class
ConfidenceRateComponent
implements
OnInit
,
OnDestroy
,
IHasTriggeredNavigation
{
public
static
TYPE
=
'
ConfidenceRateComponent
'
;
public
hasTriggeredNavigation
:
boolean
;
private
_confidenceValue
=
'
100
'
;
get
confidenceValue
():
string
{
...
...
@@ -60,11 +63,18 @@ export class ConfidenceRateComponent implements OnInit, OnDestroy {
}
if
(
this
.
quizService
.
quiz
.
state
===
QuizState
.
Inactive
)
{
this
.
hasTriggeredNavigation
=
true
;
this
.
router
.
navigate
([
'
/
'
]);
return
;
}
});
if
(
this
.
attendeeService
.
hasConfidenceValue
())
{
this
.
hasTriggeredNavigation
=
true
;
this
.
router
.
navigate
([
'
/quiz
'
,
'
flow
'
,
'
results
'
]);
return
;
}
this
.
quizService
.
loadDataToPlay
(
sessionStorage
.
getItem
(
StorageKey
.
CurrentQuizName
)).
then
(()
=>
{
this
.
handleMessages
();
});
...
...
@@ -111,6 +121,7 @@ export class ConfidenceRateComponent implements OnInit, OnDestroy {
public
async
sendConfidence
():
Promise
<
Subscription
>
{
return
this
.
memberApiService
.
putConfidenceValue
(
parseInt
(
this
.
_confidenceValue
,
10
)).
subscribe
((
data
:
IMessage
)
=>
{
this
.
hasTriggeredNavigation
=
true
;
this
.
router
.
navigate
([
'
/quiz
'
,
'
flow
'
,
'
results
'
]);
});
}
...
...
@@ -122,8 +133,10 @@ export class ConfidenceRateComponent implements OnInit, OnDestroy {
sessionStorage
.
removeItem
(
StorageKey
.
CurrentQuestionIndex
);
}),
this
.
messageQueue
.
subscribe
(
MessageProtocol
.
Start
,
payload
=>
{
this
.
quizService
.
quiz
.
currentStartTimestamp
=
payload
.
currentStartTimestamp
;
this
.
hasTriggeredNavigation
=
true
;
this
.
router
.
navigate
([
'
/quiz
'
,
'
flow
'
,
'
voting
'
]);
}),
this
.
messageQueue
.
subscribe
(
MessageProtocol
.
Stop
,
payload
=>
{
}),
this
.
messageQueue
.
subscribe
(
MessageProtocol
.
Stop
,
()
=>
{
this
.
hasTriggeredNavigation
=
true
;
this
.
router
.
navigate
([
'
/quiz
'
,
'
flow
'
,
'
results
'
]);
}),
this
.
messageQueue
.
subscribe
(
MessageProtocol
.
UpdatedResponse
,
payload
=>
{
console
.
log
(
'
ConfidenceRateComponent: modify response data for nickname
'
,
payload
.
nickname
);
...
...
@@ -131,6 +144,7 @@ export class ConfidenceRateComponent implements OnInit, OnDestroy {
}),
this
.
messageQueue
.
subscribe
(
MessageProtocol
.
UpdatedSettings
,
payload
=>
{
this
.
quizService
.
quiz
.
sessionConfig
=
payload
.
sessionConfig
;
}),
this
.
messageQueue
.
subscribe
(
MessageProtocol
.
ReadingConfirmationRequested
,
payload
=>
{
this
.
hasTriggeredNavigation
=
true
;
if
(
environment
.
readingConfirmationEnabled
)
{
this
.
router
.
navigate
([
'
/quiz
'
,
'
flow
'
,
'
reading-confirmation
'
]);
}
else
{
...
...
@@ -139,12 +153,14 @@ export class ConfidenceRateComponent implements OnInit, OnDestroy {
}),
this
.
messageQueue
.
subscribe
(
MessageProtocol
.
Reset
,
payload
=>
{
this
.
attendeeService
.
clearResponses
();
this
.
quizService
.
quiz
.
currentQuestionIndex
=
-
1
;
this
.
hasTriggeredNavigation
=
true
;
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
.
messageQueue
.
subscribe
(
MessageProtocol
.
Closed
,
()
=>
{
this
.
hasTriggeredNavigation
=
true
;
this
.
router
.
navigate
([
'
/
'
]);
}),
]);
...
...
src/app/quiz/quiz-flow/leaderboard/leaderboard.component.ts
View file @
0d2074a6
import
{
isPlatformBrowser
}
from
'
@angular/common
'
;
import
{
Component
,
Inject
,
OnDestroy
,
OnInit
,
PLATFORM_ID
,
SecurityContext
}
from
'
@angular/core
'
;
import
{
DomSanitizer
}
from
'
@angular/platform-browser
'
;
import
{
ActivatedRoute
,
Router
}
from
'
@angular/router
'
;
...
...
@@ -10,6 +9,7 @@ import { environment } from '../../../../environments/environment';
import
{
StorageKey
}
from
'
../../../lib/enums/enums
'
;
import
{
MessageProtocol
}
from
'
../../../lib/enums/Message
'
;
import
{
QuizState
}
from
'
../../../lib/enums/QuizState
'
;
import
{
IHasTriggeredNavigation
}
from
'
../../../lib/interfaces/IHasTriggeredNavigation
'
;
import
{
ILeaderBoardItem
}
from
'
../../../lib/interfaces/ILeaderboard
'
;
import
{
ServerUnavailableModalComponent
}
from
'
../../../modals/server-unavailable-modal/server-unavailable-modal.component
'
;
import
{
LeaderboardApiService
}
from
'
../../../service/api/leaderboard/leaderboard-api.service
'
;
...
...
@@ -26,9 +26,10 @@ import { QuizService } from '../../../service/quiz/quiz.service';
templateUrl
:
'
./leaderboard.component.html
'
,
styleUrls
:
[
'
./leaderboard.component.scss
'
],
})
export
class
LeaderboardComponent
implements
OnInit
,
OnDestroy
{
export
class
LeaderboardComponent
implements
OnInit
,
OnDestroy
,
IHasTriggeredNavigation
{
public
static
TYPE
=
'
LeaderboardComponent
'
;
public
isLoadingData
=
true
;
public
hasTriggeredNavigation
:
boolean
;
private
_questionIndex
:
number
;
private
readonly
_destroy
=
new
Subject
();
...
...
@@ -89,6 +90,7 @@ export class LeaderboardComponent implements OnInit, OnDestroy {
}
if
(
this
.
quizService
.
quiz
.
state
===
QuizState
.
Inactive
)
{
this
.
hasTriggeredNavigation
=
true
;
this
.
router
.
navigate
([
'
/
'
]);
return
;
}
...
...
@@ -177,6 +179,7 @@ export class LeaderboardComponent implements OnInit, OnDestroy {
this
.
headerLabelService
.
headerLabel
=
'
component.leaderboard.global_header
'
;
this
.
_questionIndex
=
null
;
if
(
params
[
'
questionIndex
'
])
{
this
.
hasTriggeredNavigation
=
true
;
this
.
router
.
navigate
([
'
/quiz
'
,
'
flow
'
,
'
leaderboard
'
]);
return
;
}
...
...
@@ -205,6 +208,7 @@ export class LeaderboardComponent implements OnInit, OnDestroy {
sessionStorage
.
removeItem
(
StorageKey
.
CurrentQuestionIndex
);
}),
this
.
messageQueue
.
subscribe
(
MessageProtocol
.
Start
,
payload
=>
{
this
.
hasTriggeredNavigation
=
true
;
this
.
router
.
navigate
([
'
/quiz
'
,
'
flow
'
,
'
voting
'
]);
}),
this
.
messageQueue
.
subscribe
(
MessageProtocol
.
UpdatedResponse
,
payload
=>
{
console
.
log
(
'
LeaderboardComponent: modify response data for nickname
'
,
payload
.
nickname
);
...
...
@@ -214,15 +218,16 @@ export class LeaderboardComponent implements OnInit, OnDestroy {
}),
this
.
messageQueue
.
subscribe
(
MessageProtocol
.
Reset
,
payload
=>
{
this
.
attendeeService
.
clearResponses
();
this
.
quizService
.
quiz
.
currentQuestionIndex
=
-
1
;
this
.
hasTriggeredNavigation
=
true
;
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
([
'
/
'
]);
}
const
existingNickname
=
sessionStorage
.
getItem
(
StorageKey
.
CurrentNickName
);
if
(
existingNickname
===
payload
.
name
)
{
this
.
hasTriggeredNavigation
=
true
;
this
.
router
.
navigate
([
'
/
'
]);
}
}),
this
.
messageQueue
.
subscribe
(
MessageProtocol
.
Closed
,
payload
=>
{
this
.
hasTriggeredNavigation
=
true
;
this
.
router
.
navigate
([
'
/
'
]);
}),
]);
...
...
@@ -234,6 +239,7 @@ export class LeaderboardComponent implements OnInit, OnDestroy {
];
this
.
footerBarService
.
footerElemBack
.
onClickCallback
=
()
=>
{
this
.
hasTriggeredNavigation
=
true
;
this
.
router
.
navigate
([
'
/quiz
'
,
'
flow
'
,
'
results
'
]);
};
...
...
src/app/quiz/quiz-flow/quiz-flow.module.ts
View file @
0d2074a6
...
...
@@ -3,6 +3,7 @@ import { RouterModule, Routes } from '@angular/router';
import
{
QRCodeModule
}
from
'
angularx-qrcode
'
;
import
{
MarkdownModule
}
from
'
ngx-markdown
'
;
import
{
CasLoginService
}
from
'
../../service/login/cas-login.service
'
;
import
{
ShowUnloadWarningGuard
}
from
'
../../service/show-unload-warning-guard/show-unload-warning.guard
'
;
import
{
SharedModule
}
from
'
../../shared/shared.module
'
;
import
{
ConfidenceRateComponent
}
from
'
./confidence-rate/confidence-rate.component
'
;
import
{
LeaderboardComponent
}
from
'
./leaderboard/leaderboard.component
'
;
...
...
@@ -26,6 +27,7 @@ export const quizFlowRoutes: Routes = [
canLoad
:
[
CasLoginService
],
component
:
QuizLobbyComponent
,
data
:
{},
canDeactivate
:
[
ShowUnloadWarningGuard
],
},
{
path
:
'
results
'
,
component
:
QuizResultsComponent
,
...
...
@@ -46,14 +48,17 @@ export const quizFlowRoutes: Routes = [
path
:
'
voting
'
,
component
:
VotingComponent
,
data
:
{},
canDeactivate
:
[
ShowUnloadWarningGuard
],
},
{
path
:
'
reading-confirmation
'
,
component
:
ReadingConfirmationComponent
,
data
:
{},
canDeactivate
:
[
ShowUnloadWarningGuard
],
},
{
path
:
'
confidence-rate
'
,
component
:
ConfidenceRateComponent
,
data
:
{},
canDeactivate
:
[
ShowUnloadWarningGuard
],
},
];
...
...
src/app/quiz/quiz-flow/quiz-lobby/quiz-lobby.component.ts
View file @
0d2074a6
import
{
isPlatformBrowser
}
from
'
@angular/common
'
;
import
{
Component
,
Inject
,
OnDestroy
,
OnInit
,
PLATFORM_ID
,
SecurityContext
,
TemplateRef
}
from
'
@angular/core
'
;
import
{
DomSanitizer
}
from
'
@angular/platform-browser
'
;
import
{
Router
}
from
'
@angular/router
'
;
...
...
@@ -14,6 +13,7 @@ import { UserRole } from '../../../lib/enums/UserRole';
import
{
FooterbarElement
}
from
'
../../../lib/footerbar-element/footerbar-element
'
;
import
{
IMessage
}
from
'
../../../lib/interfaces/communication/IMessage
'
;
import
{
IMemberSerialized
}
from
'
../../../lib/interfaces/entities/Member/IMemberSerialized
'
;
import
{
IHasTriggeredNavigation
}
from
'
../../../lib/interfaces/IHasTriggeredNavigation
'
;
import
{
ServerUnavailableModalComponent
}
from
'
../../../modals/server-unavailable-modal/server-unavailable-modal.component
'
;
import
{
MemberApiService
}
from
'
../../../service/api/member/member-api.service
'
;
import
{
QuizApiService
}
from
'
../../../service/api/quiz/quiz-api.service
'
;
...
...
@@ -35,9 +35,11 @@ import { QrCodeContentComponent } from './modals/qr-code-content/qr-code-content
templateUrl
:
'
./quiz-lobby.component.html
'
,
styleUrls
:
[
'
./quiz-lobby.component.scss
'
],
})
export
class
QuizLobbyComponent
implements
OnInit
,
OnDestroy
{
export
class
QuizLobbyComponent
implements
OnInit
,
OnDestroy
,
IHasTriggeredNavigation
{
public
static
TYPE
=
'
QuizLobbyComponent
'
;
public
hasTriggeredNavigation
:
boolean
;
private
_nickToRemove
:
string
;
get
nickToRemove
():
string
{
...
...
@@ -81,6 +83,7 @@ export class QuizLobbyComponent implements OnInit, OnDestroy {
}
if
(
this
.
quizService
.
quiz
.
state
===
QuizState
.
Inactive
)
{
this
.
hasTriggeredNavigation
=
true
;
this
.
router
.
navigate
([
'
/
'
]);
return
;
}
...
...
@@ -200,6 +203,7 @@ export class QuizLobbyComponent implements OnInit, OnDestroy {
this
.
memberApiService
.
deleteMember
(
this
.
quizService
.
quiz
.
name
,
this
.
attendeeService
.
ownNick
).
subscribe
();
this
.
attendeeService
.
cleanUp
();
this
.
connectionService
.
cleanUp
();
this
.
hasTriggeredNavigation
=
true
;
this
.
router
.
navigate
([
'
/
'
]);
};
}
...
...
@@ -238,6 +242,7 @@ export class QuizLobbyComponent implements OnInit, OnDestroy {
this
.
quizService
.
readingConfirmationRequested
=
environment
.
readingConfirmationEnabled
?
data
.
step
===
MessageProtocol
.
ReadingConfirmationRequested
:
false
;
this
.
hasTriggeredNavigation
=
true
;
this
.
router
.
navigate
([
'
/quiz
'
,
'
flow
'
,
'
results
'
]);
self
.
isLoading
=
false
;
});
...
...
@@ -252,6 +257,7 @@ export class QuizLobbyComponent implements OnInit, OnDestroy {
this
.
quizService
.
close
();
this
.
attendeeService
.
cleanUp
();
this
.
connectionService
.
cleanUp
();
this
.
hasTriggeredNavigation
=
true
;
this
.
router
.
navigate
([
'
/quiz
'
,
'
manager
'
,
'
overview
'
]);
}).
catch
(()
=>
{});
};
...
...
@@ -273,6 +279,7 @@ export class QuizLobbyComponent implements OnInit, OnDestroy {
}),
this
.
messageQueue
.
subscribe
(
MessageProtocol
.
Start
,
payload
=>
{
this
.
quizService
.
quiz
.
currentStartTimestamp
=
payload
.
currentStartTimestamp
;
}),
this
.
messageQueue
.
subscribe
(
MessageProtocol
.
Closed
,
payload
=>
{
this
.
hasTriggeredNavigation
=
true
;
this
.
router
.
navigate
([
'
/
'
]);
}),
]);
...
...
@@ -295,21 +302,22 @@ export class QuizLobbyComponent implements OnInit, OnDestroy {
private
handleMessagesForAttendee
():
void
{
this
.
_messageSubscriptions
.
push
(...[
this
.
messageQueue
.
subscribe
(
MessageProtocol
.
Start
,
payload
=>
{
this
.
hasTriggeredNavigation
=
true
;
this
.
router
.
navigate
([
'
/quiz
'
,
'
flow
'
,
'
voting
'
]);
}),
this
.
messageQueue
.
subscribe
(
MessageProtocol
.
UpdatedSettings
,
payload
=>
{
this
.
quizService
.
quiz
.
sessionConfig
=
payload
.
sessionConfig
;
}),
this
.
messageQueue
.
subscribe
(
MessageProtocol
.
ReadingConfirmationRequested
,
payload
=>
{
this
.
hasTriggeredNavigation
=
true
;
if
(
environment
.
readingConfirmationEnabled
)
{
this
.
router
.
navigate
([
'
/quiz
'
,
'
flow
'
,
'
reading-confirmation
'
]);
}
else
{
this
.
router
.
navigate
([
'
/quiz
'
,
'
flow
'
,
'
voting
'
]);
}
}),
this
.
messageQueue
.
subscribe
(
MessageProtocol
.
Removed
,
payload
=>
{
if
(
isPlatformBrowser
(
this
.
platformId
))
{
const
existingNickname
=
sessionStorage
.
getItem
(
StorageKey
.
CurrentNickName
);
if
(
existingNickname
===
payload
.
name
)
{
this
.
router
.
navigate
([
'
/
'
]);
}
const
existingNickname
=
sessionStorage
.
getItem
(
StorageKey
.
CurrentNickName
);
if
(
existingNickname
===
payload
.
name
)
{
this
.
hasTriggeredNavigation
=
true
;
this
.
router
.
navigate
([
'
/
'
]);
}
}),
]);
...
...
src/app/quiz/quiz-flow/quiz-results/question-details/question-details.component.ts
View file @
0d2074a6
...
...
@@ -11,6 +11,7 @@ import { RangedQuestionEntity } from '../../../../lib/entities/question/RangedQu
import
{
StorageKey
}
from
'
../../../../lib/enums/enums
'
;
import
{
MessageProtocol
}
from
'
../../../../lib/enums/Message
'
;
import
{
IMemberSerialized
}
from
'
../../../../lib/interfaces/entities/Member/IMemberSerialized
'
;
import
{
IHasTriggeredNavigation
}
from
'
../../../../lib/interfaces/IHasTriggeredNavigation
'
;
import
{
ServerUnavailableModalComponent
}
from
'
../../../../modals/server-unavailable-modal/server-unavailable-modal.component
'
;
import
{
AttendeeService
}
from
'
../../../../service/attendee/attendee.service
'
;
import
{
ConnectionService
}
from
'
../../../../service/connection/connection.service
'
;
...
...
@@ -23,8 +24,9 @@ import { QuizService } from '../../../../service/quiz/quiz.service';
templateUrl
:
'
./question-details.component.html
'
,
styleUrls
:
[
'
./question-details.component.scss
'
],
})
export
class
QuestionDetailsComponent
implements
OnInit
,
OnDestroy
{
export
class
QuestionDetailsComponent
implements
OnInit
,
OnDestroy
,
IHasTriggeredNavigation
{
public
static
TYPE
=
'
QuestionDetailsComponent
'
;
public
hasTriggeredNavigation
:
boolean
;
private
_question
:
AbstractQuestionEntity
;
...
...
@@ -75,6 +77,11 @@ export class QuestionDetailsComponent implements OnInit, OnDestroy {
footerBarService
.
replaceFooterElements
([
this
.
footerBarService
.
footerElemBack
,
]);
this
.
footerBarService
.
footerElemBack
.
onClickCallback
=
()
=>
{
this
.
hasTriggeredNavigation
=
true
;
history
.
back
();
};
}
public
sanitizeHTML
(
value
:
string
):
string
{
...
...
@@ -121,6 +128,7 @@ export class QuestionDetailsComponent implements OnInit, OnDestroy {
this
.
_questionIndex
=
questionIndex
;
if
(
this
.
_questionIndex
<
0
||
this
.
_questionIndex
>
this
.
quizService
.
quiz
.
currentQuestionIndex
)
{
this
.
hasTriggeredNavigation
=
true
;
this
.
router
.
navigate
([
'
/quiz
'
,
'
flow
'
,
'
results
'
]);
return
;
}
...
...
@@ -136,6 +144,7 @@ export class QuestionDetailsComponent implements OnInit, OnDestroy {
}
public
ngOnDestroy
():
void
{
this
.
footerBarService
.
footerElemBack
.
restoreClickCallback
();
this
.
_messageSubscriptions
.
forEach
(
id
=>
this
.
messageQueue
.
unsubscribe
(
id
));
this
.
_destroy
.
next
();
this
.
_destroy
.
complete
();
...
...
@@ -165,8 +174,10 @@ export class QuestionDetailsComponent implements OnInit, OnDestroy {
}),
this
.
messageQueue
.
subscribe
(
MessageProtocol
.
Reset
,
payload
=>
{
this
.
attendeeService
.
clearResponses
();
this
.
quizService
.
quiz
.
currentQuestionIndex
=
-
1
;
this
.
hasTriggeredNavigation
=
true
;
this
.
router
.
navigate
([
'
/quiz
'
,
'
flow
'
,
'
lobby
'
]);
}),
this
.
messageQueue
.
subscribe
(
MessageProtocol
.
Closed
,
payload
=>
{
this
.
hasTriggeredNavigation
=
true
;
this
.
router
.
navigate
([
'
/
'
]);
}),
]);
...
...
@@ -179,10 +190,12 @@ export class QuestionDetailsComponent implements OnInit, OnDestroy {
private
handleMessagesForAttendee
():
void
{
this
.
_messageSubscriptions
.
push
(...[
this
.
messageQueue
.
subscribe
(
MessageProtocol
.
Start
,
payload
=>
{
this
.
hasTriggeredNavigation
=
true
;
this
.
router
.
navigate
([
'
/quiz
'
,
'
flow
'
,
'
voting
'
]);
}),
this
.
messageQueue
.
subscribe
(
MessageProtocol
.
UpdatedSettings
,
payload
=>
{
this
.
quizService
.
quiz
.
sessionConfig
=
payload
.
sessionConfig
;
}),
this
.
messageQueue
.
subscribe
(
MessageProtocol
.
ReadingConfirmationRequested
,
payload
=>
{
this
.
hasTriggeredNavigation
=
true
;
if
(
environment
.
readingConfirmationEnabled
)
{
this
.
router
.
navigate
([
'
/quiz
'
,
'
flow
'
,
'
reading-confirmation
'
]);
}
else
{
...
...
src/app/quiz/quiz-flow/quiz-results/quiz-results.component.html
View file @
0d2074a6
...
...
@@ -81,6 +81,7 @@
<div
*ngIf=
"showLeaderBoardButton(selectedQuestionIndex) || showQuestionButton(selectedQuestionIndex)"
class=
"btn-group w-100"
>
<button
*ngIf=
"showLeaderBoardButton(selectedQuestionIndex)"
(click)=
"hasTriggeredNavigation = true"
[routerLink]=
"['/quiz', 'flow', 'leaderboard', visibleQuestions.length > 1 ? selectedQuestionIndex : 'all']"
class=
"btn btn-light w-100 cursor-pointer"
type=
"button"
>
...
...
@@ -89,6 +90,7 @@
<span>
{{'component.liveResults.ranking' | translate}}
</span>
</button>
<button
*ngIf=
"showQuestionButton(selectedQuestionIndex)"
(click)=
"hasTriggeredNavigation = true"
[routerLink]=
"['/quiz', 'flow', 'results', selectedQuestionIndex]"
class=
"btn btn-light w-100 cursor-pointer"
type=
"button"
>
...
...
src/app/quiz/quiz-flow/quiz-results/quiz-results.component.ts
View file @
0d2074a6
...
...
@@ -11,6 +11,7 @@ import { MessageProtocol, StatusProtocol } from '../../../lib/enums/Message';
import
{
QuestionType
}
from
'
../../../lib/enums/QuestionType
'
;
import
{
QuizState
}
from
'
../../../lib/enums/QuizState
'
;
import
{
IMemberSerialized
}
from
'
../../../lib/interfaces/entities/Member/IMemberSerialized
'
;
import
{
IHasTriggeredNavigation
}
from
'
../../../lib/interfaces/IHasTriggeredNavigation
'
;
import
{
ServerUnavailableModalComponent
}
from
'
../../../modals/server-unavailable-modal/server-unavailable-modal.component
'
;
import
{
QuizApiService
}
from
'
../../../service/api/quiz/quiz-api.service
'
;
import
{
AttendeeService
}
from
'
../../../service/attendee/attendee.service
'
;
...
...
@@ -28,8 +29,9 @@ import { ToLobbyConfirmComponent } from './modals/to-lobby-confirm/to-lobby-conf
styleUrls
:
[
'
./quiz-results.component.scss
'
],
changeDetection
:
ChangeDetectionStrategy
.
OnPush
,
})
export
class
QuizResultsComponent
implements
OnInit
,
OnDestroy
{
export
class
QuizResultsComponent
implements
OnInit
,
OnDestroy
,
IHasTriggeredNavigation
{
public
static
TYPE
=
'
QuizResultsComponent
'
;
public
hasTriggeredNavigation
:
boolean
;
public
countdown
:
number
;
public
answers
:
Array
<
string
>
=
[];
public
showStartQuizButton
:
boolean
;
...
...
@@ -222,6 +224,7 @@ export class QuizResultsComponent implements OnInit, OnDestroy {
}
if
(
this
.
quizService
.
quiz
.
state
===
QuizState
.
Inactive
)
{
this
.
hasTriggeredNavigation
=
true
;
this
.
router
.
navigate
([
'
/
'
]);
return
;
}
...
...
@@ -327,6 +330,7 @@ export class QuizResultsComponent implements OnInit, OnDestroy {
return
this
.
quizApiService
.
getQuizStatus
(
this
.
quizService
.
quiz
.
name
).
toPromise
().
then
(
currentStateData
=>
{
if
(
currentStateData
.
status
!==
StatusProtocol
.
Success
)
{
this
.
hasTriggeredNavigation
=
true
;
this
.
router
.
navigate
([
'
/
'
]);
return
;
}
...
...
@@ -334,6 +338,7 @@ export class QuizResultsComponent implements OnInit, OnDestroy {
if
(
currentStateData
.
payload
.
state
===
QuizState
.
Active
)
{
this
.
attendeeService
.
clearResponses
();
this
.
quizService
.
quiz
.
currentQuestionIndex
=
-
1
;
this
.
hasTriggeredNavigation
=
true
;
this
.
router
.
navigate
([
'
/quiz
'
,
'
flow
'
,
'
lobby
'
]);
return
;
}
...
...
@@ -470,8 +475,10 @@ export class QuizResultsComponent implements OnInit, OnDestroy {
}),
this
.
messageQueue
.
subscribe
(
MessageProtocol
.
Reset
,
payload
=>
{
this
.
attendeeService
.
clearResponses
();
this
.
quizService
.
quiz
.
currentQuestionIndex
=
-
1
;
this
.
hasTriggeredNavigation
=
true
;
this
.
router
.
navigate
([
'
/quiz
'
,
'
flow
'
,
'
lobby
'
]);
}),
this
.
messageQueue
.
subscribe
(
MessageProtocol
.
Closed
,
payload
=>
{
this
.
hasTriggeredNavigation
=
true
;
this
.
router
.
navigate
([
'
/
'
]);
}),
]);
...
...
@@ -504,10 +511,12 @@ export class QuizResultsComponent implements OnInit, OnDestroy {
private
handleMessagesForAttendee
():
void
{
this
.
_messageSubscriptions
.
push
(...[
this
.
messageQueue
.
subscribe
(
MessageProtocol
.
Start
,
payload
=>
{
this
.
hasTriggeredNavigation
=
true
;
this
.
router
.
navigate
([
'
/quiz
'
,
'
flow
'
,
'
voting
'
]);
}),
this
.
messageQueue
.
subscribe
(
MessageProtocol
.
UpdatedSettings
,
payload
=>
{
this
.
quizService
.
quiz
.
sessionConfig
=
payload
.
sessionConfig
;
}),
this
.
messageQueue
.
subscribe
(
MessageProtocol
.
ReadingConfirmationRequested
,
payload
=>
{
this
.
hasTriggeredNavigation
=
true
;
if
(
environment
.
readingConfirmationEnabled
)
{
this
.
router
.
navigate
([
'
/quiz
'
,
'
flow
'
,
'
reading-confirmation
'
]);
}
else
{
...
...
@@ -516,6 +525,7 @@ export class QuizResultsComponent implements OnInit, OnDestroy {
}),
this
.
messageQueue
.
subscribe
(
MessageProtocol
.
Removed
,
payload
=>
{
const
existingNickname
=
sessionStorage
.
getItem
(
StorageKey
.
CurrentNickName
);
if
(
existingNickname
===
payload
.
name
)
{
this
.
hasTriggeredNavigation
=
true
;
this
.
router
.
navigate
([
'
/
'
]);
}
}),
...
...
src/app/quiz/quiz-flow/reading-confirmation/reading-confirmation.component.ts
View file @
0d2074a6
...
...
@@ -9,6 +9,7 @@ import { StorageKey } from '../../../lib/enums/enums';
import
{
MessageProtocol
}
from
'
../../../lib/enums/Message
'
;
import
{
QuizState
}
from
'
../../../lib/enums/QuizState
'
;
import
{
IMemberSerialized
}
from
'
../../../lib/interfaces/entities/Member/IMemberSerialized
'
;
import
{
IHasTriggeredNavigation
}
from
'
../../../lib/interfaces/IHasTriggeredNavigation
'
;
import
{
ServerUnavailableModalComponent
}
from
'
../../../modals/server-unavailable-modal/server-unavailable-modal.component
'
;
import
{
MemberApiService
}
from
'
../../../service/api/member/member-api.service
'
;
import
{
AttendeeService
}
from
'
../../../service/attendee/attendee.service
'
;
...
...
@@ -23,9 +24,11 @@ import { QuizService } from '../../../service/quiz/quiz.service';
templateUrl
:
'
./reading-confirmation.component.html
'
,
styleUrls
:
[
'
./reading-confirmation.component.scss
'
],
})
export
class
ReadingConfirmationComponent
implements
OnInit
,
OnDestroy
{
export
class
ReadingConfirmationComponent
implements
OnInit
,
OnDestroy
,
IHasTriggeredNavigation
{
public
static
TYPE
=
'
ReadingConfirmationComponent
'
;
public
hasTriggeredNavigation
:
boolean
;
public
questionIndex
:
number
;
public
questionText
:
string
;
...
...
@@ -74,12 +77,19 @@ export class ReadingConfirmationComponent implements OnInit, OnDestroy {
this
.
_serverUnavailableModal
.
result
.
finally
(()
=>
this
.
_serverUnavailableModal
=
null
);
});
if
(
this
.
attendeeService
.
hasReadingConfirmation
())
{
this
.
hasTriggeredNavigation
=
true
;
this
.
router
.
navigate
([
'
/quiz
'
,
'
flow
'
,
'
results
'
]);
return
;
}
this
.
quizService
.
quizUpdateEmitter
.
pipe
(
takeUntil
(
this
.
_destroy
)).
subscribe
(
quiz
=>
{
if
(
!
quiz
)
{
return
;
}
if
(
this
.
quizService
.
quiz
.
state
===
QuizState
.
Inactive
)
{
this
.
hasTriggeredNavigation
=
true
;
this
.
router
.
navigate
([
'
/
'
]);
return
;
}
...
...
@@ -105,6 +115,7 @@ export class ReadingConfirmationComponent implements OnInit, OnDestroy {
public
confirmReading
():
void
{
this
.
memberApiService
.
putReadingConfirmationValue
().
subscribe
(()
=>
{
this
.
hasTriggeredNavigation
=
true
;
this
.
router
.
navigate
([
'
/quiz
'
,
'
flow
'
,
'
results
'
]);
});
}
...
...
@@ -115,6 +126,7 @@ export class ReadingConfirmationComponent implements OnInit, OnDestroy {
this
.
quizService
.
quiz
.
currentQuestionIndex
=
payload
.
nextQuestionIndex
;
sessionStorage
.
removeItem
(
StorageKey
.
CurrentQuestionIndex
);
}),
this
.
messageQueue
.
subscribe
(
MessageProtocol
.
Start
,
payload
=>
{
this
.
hasTriggeredNavigation
=
true
;
this
.
router
.
navigate
([
'
/quiz
'
,
'
flow
'
,
'
voting
'
]);
}),
this
.
messageQueue
.
subscribe
(
MessageProtocol
.
UpdatedResponse
,
payload
=>
{
console
.
log
(
'
ReadingConfirmationComponent: modifying response data for nickname
'
,
payload
.
nickname
);
...
...
@@ -124,8 +136,10 @@ export class ReadingConfirmationComponent implements OnInit, OnDestroy {
}),
this
.
messageQueue
.
subscribe
(
MessageProtocol
.
Reset
,
payload
=>
{
this
.
attendeeService
.
clearResponses
();
this
.
quizService
.
quiz
.
currentQuestionIndex
=
-
1
;
this
.
hasTriggeredNavigation
=
true
;
this
.
router
.
navigate
([
'
/quiz
'
,
'
flow
'
,
'
lobby
'
]);
}),
this
.
messageQueue
.
subscribe
(
MessageProtocol
.
Closed
,
payload
=>
{
this
.
hasTriggeredNavigation
=
true
;
this
.
router
.
navigate
([
'
/
'
]);
}),
this
.
messageQueue
.
subscribe
(
MessageProtocol
.
Added
,
payload
=>
{
this
.
attendeeService
.
addMember
(
payload
.
member
);
...
...
src/app/quiz/quiz-flow/voting/voting.component.ts
View file @
0d2074a6
import
{
isPlatformBrowser
}
from
'
@angular/common
'
;
import
{
Component
,
Inject
,
OnDestroy
,
OnInit
,
PLATFORM_ID
,
SecurityContext
}
from
'
@angular/core
'
;
import
{
DomSanitizer
}
from
'
@angular/platform-browser
'
;
import
{
Router
}
from
'
@angular/router
'
;
...
...
@@ -15,6 +14,7 @@ import { MessageProtocol, StatusProtocol } from '../../../lib/enums/Message';
import
{
QuestionType
}
from
'
../../../lib/enums/QuestionType
'
;
import
{
QuizState
}
from
'
../../../lib/enums/QuizState
'
;
import
{
IMessage
}
from
'
../../../lib/interfaces/communication/IMessage
'
;
import
{
IHasTriggeredNavigation
}
from
'
../../../lib/interfaces/IHasTriggeredNavigation
'
;
import
{
ServerUnavailableModalComponent
}
from
'
../../../modals/server-unavailable-modal/server-unavailable-modal.component
'
;
import
{
MemberApiService
}
from
'
../../../service/api/member/member-api.service
'
;
import
{
QuizApiService
}
from
'
../../../service/api/quiz/quiz-api.service
'
;
...
...
@@ -30,9 +30,10 @@ import { QuizService } from '../../../service/quiz/quiz.service';
templateUrl
:
'
./voting.component.html
'
,
styleUrls
:
[
'
./voting.component.scss
'
],
})
export
class
VotingComponent
implements
OnInit
,
OnDestroy
{
export
class
VotingComponent
implements
OnInit
,
OnDestroy
,
IHasTriggeredNavigation
{
public
static
TYPE
=
'
VotingComponent
'
;
public
isSendingResponse
:
boolean
;
public
hasTriggeredNavigation
:
boolean
;
private
_answers
:
Array
<
string
>
=
[];
...
...
@@ -144,10 +145,8 @@ export class VotingComponent implements OnInit, OnDestroy {
public
sendResponses
(
route
?:
string
):
void
{
this
.
isSendingResponse
=
true
;
this
.
router
.
navigate
([
'
/quiz
'
,
'
flow
'
,
route
?
route
:
environment
.
confidenceSliderEnabled
&&
//
this
.
quizService
.
quiz
.
sessionConfig
.
confidenceSliderEnabled
?
'
confidence-rate
'
:
'
results
'
,
]);
this
.
hasTriggeredNavigation
=
true
;
this
.
router
.
navigate
(
this
.
getNextRoute
(
route
));
}
public
initData
():
void
{
...
...
@@ -171,11 +170,18 @@ export class VotingComponent implements OnInit, OnDestroy {
}
if
(
this
.
quizService
.
quiz
.
state
===
QuizState
.
Inactive
)
{
this
.
hasTriggeredNavigation
=
true
;
this
.
router
.
navigate
([
'
/
'
]);
return
;
}
this
.
_currentQuestion
=
this
.
quizService
.
currentQuestion
();
if
(
this
.
attendeeService
.
hasReponse
())
{
this
.
hasTriggeredNavigation
=
true
;
this
.
router
.
navigate
(
this
.
getNextRoute
());
return
;
}
this
.
initData
();
this
.
questionTextService
.
eventEmitter
.
pipe
(
takeUntil
(
this
.
_destroy
)).
subscribe
((
value
:
string
|
Array
<
string
>
)
=>
{
...
...
@@ -252,18 +258,20 @@ export class VotingComponent implements OnInit, OnDestroy {
}),
this
.
messageQueue
.
subscribe
(
MessageProtocol
.
Reset
,
payload
=>
{
this
.
attendeeService
.
clearResponses
();
this
.
quizService
.
quiz
.
currentQuestionIndex
=
-
1
;
this
.
hasTriggeredNavigation
=
true
;
this
.
router
.
navigate
([
'
/quiz
'
,
'
flow
'
,
'
lobby
'
]);
}),
this
.
messageQueue
.
subscribe
(
MessageProtocol
.
Closed
,
payload
=>
{
this
.
hasTriggeredNavigation
=
true
;
this
.
router
.
navigate
([
'
/
'
]);
}),
this
.
messageQueue
.
subscribe
(
MessageProtocol
.
Removed
,
payload
=>
{
if
(
isPlatformBrowser
(
this
.
platformId
))
{
const
existingNickname
=
sessionStorage
.
getItem
(
StorageKey
.
CurrentNickName
);
if
(
existingNickname
===
payload
.
name
)
{
this
.
router
.
navigate
([
'
/
'
]);
}
const
existingNickname
=
sessionStorage
.
getItem
(
StorageKey
.
CurrentNickName
);