1
1
<template >
2
- <div >
2
+ <div class = " tour " >
3
3
<v-tour
4
- class =" tour"
5
4
name =" nimiq-tour"
6
5
:steps =" Object.values(steps).map((s) => s.tooltip)"
7
6
>
20
19
:is-last =" tour.isLast"
21
20
:labels =" tour.labels"
22
21
>
23
- <div class =" content" slot =" content" >
22
+ <div slot =" content" class =" content" >
24
23
<p
25
24
v-for =" (content, i) in tour.steps[tour.currentStep].content"
26
25
:key =" i"
27
- v-html =" content"
26
+ v-html =" $t( content) "
28
27
></p >
29
28
<!-- TODO REMOVE ME -->
30
29
<div class =" remove_me" v-if =" currentStep === 1" @click =" simulate()" >
31
30
Simulate Receive NIM
32
31
</div >
33
32
</div >
34
- <div slot =" actions" >
35
- <template v-if =" ! isMobile " >
36
- <button @click =" tour.previousStep" >
37
- {{ $t("Previous step") }}
38
- </button >
39
- <button @click =" tour.goToNextStep" >
40
- {{ $t("Next step") }}
41
- </button >
42
- </template >
33
+ <div slot =" actions" class =" actions" >
34
+ <button @click =" tour.previousStep" v-if =" !isMobile" >
35
+ {{ $t("Previous step") }}
36
+ </button >
37
+ <button class =" right" @click =" alert"
38
+ v-if =" tour.steps[tour.currentStep].button" >
39
+ {{ $t(tour.steps[tour.currentStep].button.text) }}
40
+ </button >
41
+ <button class =" right" @click =" tour.goToNextStep"
42
+ v-else-if =" !isMobile" >
43
+ {{ $t("Next step") }}
44
+ </button >
43
45
</div >
44
46
</v-step >
45
47
</transition >
46
48
</template >
47
49
</v-tour >
48
50
<transition name =" fade" >
49
51
<div class =" tour-control-bar" >
50
- <button disabled >
52
+ <button @click = " endTour() " >
51
53
{{ $t("End Tour") }}
52
54
</button >
53
55
<span class =" progress" >
82
84
</template >
83
85
84
86
<script lang="ts">
87
+ import { useAccountStore } from ' @/stores/Account' ;
85
88
import { useNetworkStore } from ' @/stores/Network' ;
86
89
import { useTransactionsStore } from ' @/stores/Transactions' ;
87
90
import { CircleSpinner } from ' @nimiq/vue-components' ;
@@ -91,10 +94,11 @@ import {
91
94
onMounted ,
92
95
Ref ,
93
96
ref ,
97
+ watch ,
94
98
} from ' @vue/composition-api' ;
95
99
import Vue from ' vue' ;
96
100
import VueTour from ' vue-tour' ;
97
- import { TourName , TourStep , TourStepIndex , TourSteps , useFakeTx , useTour } from ' ../composables/useTour' ;
101
+ import { TourStep , TourStepIndex , TourSteps , useFakeTx , useTour } from ' ../composables/useTour' ;
98
102
import { useWindowSize } from ' ../composables/useWindowSize' ;
99
103
import CaretRightIcon from ' ./icons/CaretRightIcon.vue' ;
100
104
@@ -104,13 +108,6 @@ require('vue-tour/dist/vue-tour.css');
104
108
105
109
export default defineComponent ({
106
110
name: ' tour' ,
107
- props: {
108
- tourName: {
109
- type: String ,
110
- required: true ,
111
- validator : (tour : TourName ) => ([' onboarding' , ' network' ] as TourName []).indexOf (tour ) !== - 1 ,
112
- },
113
- },
114
111
setup(props , context ) {
115
112
// TODO Use isMobile
116
113
const { width } = useWindowSize ();
@@ -120,12 +117,14 @@ export default defineComponent({
120
117
() => $network .consensus !== ' established' ,
121
118
);
122
119
120
+ const { state : tourStore, removeTour } = useAccountStore ();
121
+
123
122
let tour: VueTour .Tour | null = null ;
124
- const steps: TourSteps <any > = useTour (props . tourName as TourName , context ) || {};
123
+ const steps: TourSteps <any > = useTour (tourStore . tour , context ) || {};
125
124
126
125
// Initial state
127
126
const loading = ref (true );
128
- const currentStep: Ref <TourStepIndex > = ref (0 );
127
+ const currentStep: Ref <TourStepIndex > = ref (8 );
129
128
const nSteps: Ref <number > = ref (0 );
130
129
const disableNextStep = ref (true );
131
130
@@ -142,17 +141,36 @@ export default defineComponent({
142
141
nSteps .value = Object .keys (steps ).length ;
143
142
disableNextStep .value = currentStep .value >= nSteps .value - 1
144
143
|| !! steps [currentStep .value ].ui .disabledNextStep ;
144
+
145
145
_addAttributes (steps [currentStep .value ].ui , currentStep .value );
146
146
// eslint-disable-next-line no-unused-expressions
147
147
steps [currentStep .value ].lifecycle ?.onMountedStep ?.(goToNextStep );
148
148
149
+ if (context .root .$route .path !== steps [currentStep .value ].path ) {
150
+ context .root .$router .push (steps [currentStep .value ].path );
151
+ }
152
+
149
153
await sleep (500 );
150
154
151
155
tour = context .root .$tours [' nimiq-tour' ];
152
156
tour ! .start (` ${currentStep .value } ` );
153
157
loading .value = false ;
154
158
}
155
159
160
+ // Dont allow user to interact with the page while it is loading
161
+ // But allow to end it
162
+ watch ([loading , disconnected ], () => {
163
+ const app = document .querySelector (' #app main' ) as HTMLDivElement ;
164
+
165
+ if (loading .value || disconnected .value ) {
166
+ // eslint-disable-next-line no-unused-expressions
167
+ app ?.setAttribute (' data-non-interactable' , ' ' );
168
+ } else {
169
+ // eslint-disable-next-line no-unused-expressions
170
+ app ?.removeAttribute (' data-non-interactable' );
171
+ }
172
+ });
173
+
156
174
function goToPrevStep() {
157
175
if (currentStep .value <= 0 ) return ;
158
176
_moveToFutureStep (currentStep .value , currentStep .value - 1 );
@@ -171,8 +189,8 @@ export default defineComponent({
171
189
) {
172
190
const goingForward = futureStepIndex > currentStepIndex ;
173
191
174
- const { page : currentPage, lifecycle : currentLifecycle } = steps [currentStepIndex ];
175
- const { page : futurePage, ui : futureUI, lifecycle : futureLifecycle } = steps [futureStepIndex ];
192
+ const { path : currentPage, lifecycle : currentLifecycle } = steps [currentStepIndex ];
193
+ const { path : futurePage, ui : futureUI, lifecycle : futureLifecycle } = steps [futureStepIndex ];
176
194
177
195
loading .value = true ;
178
196
tour ! .stop ();
@@ -183,10 +201,14 @@ export default defineComponent({
183
201
await currentLifecycle .prepareDOMPrevPage ();
184
202
} else if (goingForward && currentLifecycle && currentLifecycle .prepareDOMNextPage ) {
185
203
await currentLifecycle .prepareDOMNextPage ();
186
- } else if (futurePage !== currentPage && currentPage .startsWith (context .root .$route .path )) {
187
- // Default prepare DOM
188
- context .root .$router .push (futurePage );
189
- await context .root .$nextTick ();
204
+ } else if (futurePage !== currentPage ) {
205
+ try {
206
+ // Default prepare DOM
207
+ context .root .$router .push (futurePage );
208
+ await context .root .$nextTick ();
209
+ } catch {
210
+ // Ignore error
211
+ }
190
212
}
191
213
192
214
_addAttributes (futureUI , futureStepIndex );
@@ -243,6 +265,16 @@ export default defineComponent({
243
265
});
244
266
}
245
267
268
+ function endTour() {
269
+ _removeAttributes (currentStep .value );
270
+
271
+ // If user finalizes tour while it is loading, allow then interaction
272
+ const app = document .querySelector (' #app main' ) as HTMLDivElement ;
273
+ app .removeAttribute (' data-non-interactable' );
274
+
275
+ removeTour ();
276
+ }
277
+
246
278
// TODO REMOVE ME - Simulate tx
247
279
function simulate() {
248
280
const { addTransactions } = useTransactionsStore ();
@@ -263,6 +295,7 @@ export default defineComponent({
263
295
// actions
264
296
goToPrevStep ,
265
297
goToNextStep ,
298
+ endTour ,
266
299
267
300
// TODO REMOVE ME
268
301
simulate ,
@@ -294,6 +327,20 @@ export default defineComponent({
294
327
.tour {
295
328
position : relative ;
296
329
330
+ button {
331
+ width : min-content ;
332
+ white-space : nowrap ;
333
+ font-size : 16px ;
334
+ padding : 0.8rem 1.6rem ;
335
+
336
+ text-align : center ;
337
+ background : #ffffff33 ; // TODO Maybe move this to a CSS variable (?)
338
+ color : var (--nimiq-white );
339
+ border : none ;
340
+ outline : var (--nimiq - );
341
+ border-radius : 9999px ;
342
+ }
343
+
297
344
.tooltip-step {
298
345
background : radial-gradient (
299
346
100% 100% at 100% 100% ,
@@ -323,6 +370,21 @@ export default defineComponent({
323
370
}
324
371
}
325
372
}
373
+
374
+ .actions {
375
+ margin-top : 2rem ;
376
+ display : flex ;
377
+
378
+ button {
379
+ font-weight : 700 ;
380
+ font-size : 14px ;
381
+
382
+ & .right {
383
+ margin-left : auto ;
384
+ }
385
+ }
386
+
387
+ }
326
388
}
327
389
}
328
390
@@ -348,17 +410,8 @@ export default defineComponent({
348
410
);
349
411
350
412
button {
351
- width : min-content ;
352
- white-space : nowrap ;
353
413
padding : 1.4rem 1.6rem 1rem 1.6rem ;
354
- font-size : 16px ;
355
-
356
- text-align : center ;
357
- background : #ffffff33 ; // TODO Maybe move this to a CSS variable (?)
358
- color : var (--nimiq-white );
359
- border : none ;
360
- outline : var (--nimiq - );
361
- border-radius : 9999px ;
414
+ font-weight : 700 ;
362
415
363
416
& :disabled {
364
417
opacity : 0.5 ;
0 commit comments