Skip to content

Commit 6d47073

Browse files
authored
Merge pull request #2072 from numbersprotocol/feature-rebranded-onboarding
Feature rebranded onboarding
2 parents c83ade2 + 50849e9 commit 6d47073

File tree

11 files changed

+219
-189
lines changed

11 files changed

+219
-189
lines changed

src/app/features/home/home.page.ts

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -107,12 +107,7 @@ export class HomePage {
107107
}
108108

109109
private async onboardingRedirect() {
110-
if (
111-
// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
112-
!this.userGuideIsTemporarelyDisabled &&
113-
this.platform.is('ios') &&
114-
(await this.onboardingService.hasShownTutorialVersion()) === ''
115-
) {
110+
if (await this.onboardingService.shouldShowOnboardingTutotrial()) {
116111
return this.router.navigate(['tutorial'], {
117112
relativeTo: this.route,
118113
});
Lines changed: 47 additions & 154 deletions
Original file line numberDiff line numberDiff line change
@@ -1,166 +1,59 @@
11
<ion-content *transloco="let t">
2-
<ion-slides #slides pager>
2+
<div class="top-section">
3+
<ion-img src="/assets/images/icons/capture-rebrand-wordmark.svg"> </ion-img>
4+
<button *ngIf="!isLastSlide" (click)="skipSlides()" mat-stroked-button>
5+
{{ t('onboarding.skip') }}
6+
</button>
7+
</div>
8+
<ion-slides
9+
#slides
10+
[pager]="isLastSlide === false"
11+
(ionSlideDidChange)="ionSlideDidChange($event)"
12+
>
313
<ion-slide>
4-
<ng-container>
5-
<svg
6-
version="1.1"
7-
id="圖層_1"
8-
xmlns="http://www.w3.org/2000/svg"
9-
xmlns:xlink="http://www.w3.org/1999/xlink"
10-
x="0px"
11-
y="0px"
12-
viewBox="0 0 360 639"
13-
enable-background="new 0 0 360 639"
14-
xml:space="preserve"
15-
>
16-
<image
17-
overflow="visible"
18-
width="360"
19-
height="639"
20-
xlink:href="/assets/images/tutorial-1.png"
21-
></image>
22-
<text transform="matrix(1 0 0 1 88.6169 279.2624)">
23-
<tspan x="0" y="0" fill="#FFFFFF" font-size="24px">
24-
{{ t('tutorial.switchBetween0') }}
25-
</tspan>
26-
<tspan x="-12.6" y="28.8" fill="#FFFFFF" font-size="24px">
27-
{{ t('tutorial.switchBetween1') }}
28-
</tspan>
29-
<tspan x="4.8" y="57.6" fill="#FFFFFF" font-size="24px">
30-
{{ t('tutorial.switchBetween2') }}
31-
</tspan>
32-
</text>
33-
<text
34-
transform="matrix(1 0 0 1 100 519.6104)"
35-
fill="#FFFFFF"
36-
font-size="24px"
37-
>
38-
{{ t('tutorial.viewYourCollections') }}
39-
</text>
40-
</svg>
41-
</ng-container>
42-
<button (click)="slides.slideNext()" mat-stroked-button>
43-
{{ t('next') }}
44-
</button>
14+
<img src="/assets/images/onboarding/image-1.jpeg" class="slide-image" />
15+
<div class="slide-text">
16+
<div class="title">{{ t('onboarding.slide1.title') }}</div>
17+
<div class="spacer"></div>
18+
<div class="subtitle">{{ t('onboarding.slide1.subtitle') }}</div>
19+
</div>
20+
<div class="mat-button-height-placeholder"></div>
4521
</ion-slide>
4622
<ion-slide>
47-
<ng-container>
48-
<svg
49-
version="1.1"
50-
id="圖層_1"
51-
xmlns="http://www.w3.org/2000/svg"
52-
xmlns:xlink="http://www.w3.org/1999/xlink"
53-
x="0px"
54-
y="0px"
55-
viewBox="0 0 360 639"
56-
enable-background="new 0 0 360 639"
57-
xml:space="preserve"
58-
>
59-
<image
60-
overflow="visible"
61-
width="359"
62-
height="639"
63-
xlink:href="/assets/images/tutorial-2.png"
64-
></image>
65-
<text
66-
transform="matrix(1 0 0 1 90 460.2997)"
67-
fill="#FFFFFF"
68-
font-size="24px"
69-
>
70-
{{ t('tutorial.createCaptures') }}
71-
</text>
72-
<text
73-
transform="matrix(1 0 0 1 20 397.8444)"
74-
fill="#FFFFFF"
75-
font-size="24px"
76-
>
77-
{{ t('tutorial.viewCreatedCaptures') }}
78-
</text>
79-
</svg>
80-
</ng-container>
81-
<button (click)="slides.slideNext()" mat-stroked-button>
82-
{{ t('next') }}
83-
</button>
23+
<img src="/assets/images/onboarding/image-2.jpeg" class="slide-image" />
24+
<div class="slide-text">
25+
<div class="title">{{ t('onboarding.slide2.title') }}</div>
26+
<div class="spacer"></div>
27+
<div class="subtitle">{{ t('onboarding.slide2.subtitle') }}</div>
28+
</div>
29+
<div class="mat-button-height-placeholder"></div>
8430
</ion-slide>
8531
<ion-slide>
86-
<ng-container>
87-
<svg
88-
version="1.1"
89-
id="圖層_1"
90-
xmlns="http://www.w3.org/2000/svg"
91-
xmlns:xlink="http://www.w3.org/1999/xlink"
92-
x="0px"
93-
y="0px"
94-
viewBox="0 0 360 639"
95-
enable-background="new 0 0 360 639"
96-
xml:space="preserve"
97-
>
98-
<image
99-
overflow="visible"
100-
width="360"
101-
height="639"
102-
xlink:href="/assets/images/tutorial-3.png"
103-
></image>
104-
<text
105-
transform="matrix(1 0 0 1 158.3539 116.3548)"
106-
fill="#FFFFFF"
107-
font-size="24px"
108-
>
109-
{{ t('tutorial.viewMore') }}
110-
</text>
111-
<text
112-
transform="matrix(1 0 0 1 40 480)"
113-
fill="#FFFFFF"
114-
font-size="24px"
115-
>
116-
{{ t('tutorial.openCertificate') }}
117-
</text>
118-
</svg>
119-
</ng-container>
120-
<button (click)="slides.slideNext()" mat-stroked-button>
121-
{{ t('next') }}
122-
</button>
32+
<img src="/assets/images/onboarding/image-3.jpeg" class="slide-image" />
33+
<div class="slide-text">
34+
<div class="title">{{ t('onboarding.slide3.title') }}</div>
35+
<div class="spacer"></div>
36+
<div class="subtitle">{{ t('onboarding.slide3.subtitle') }}</div>
37+
</div>
38+
<div class="mat-button-height-placeholder"></div>
12339
</ion-slide>
12440
<ion-slide>
125-
<ng-container>
126-
<svg
127-
version="1.1"
128-
id="圖層_1"
129-
xmlns="http://www.w3.org/2000/svg"
130-
xmlns:xlink="http://www.w3.org/1999/xlink"
131-
x="0px"
132-
y="0px"
133-
viewBox="0 0 360 639"
134-
enable-background="new 0 0 360 639"
135-
xml:space="preserve"
136-
>
137-
<image
138-
overflow="visible"
139-
width="360"
140-
height="639"
141-
xlink:href="/assets/images/tutorial-4.png"
142-
></image>
143-
<text
144-
transform="matrix(1 0 0 1 127.9265 65)"
145-
fill="#000"
146-
font-size="24px"
147-
>
148-
{{ t('tutorial.histories') }}
149-
</text>
150-
<g>
151-
<text
152-
transform="matrix(1 0 0 1 159.2167 200)"
153-
fill="#FFFFFF"
154-
font-size="24px"
155-
>
156-
{{ t('tutorial.messageInbox') }}
157-
</text>
158-
</g>
159-
</svg>
160-
</ng-container>
161-
<button routerLink="/home" mat-stroked-button>
162-
{{ t('start') }}
41+
<img src="/assets/images/onboarding/image-4.jpeg" class="slide-image" />
42+
<div class="slide-text">
43+
<div class="title">{{ t('onboarding.slide4.title') }}</div>
44+
<div class="spacer"></div>
45+
<div class="subtitle">{{ t('onboarding.slide4.subtitle') }}</div>
46+
</div>
47+
<button
48+
routerLink="/home"
49+
color="primary"
50+
mat-raised-button
51+
class="explore-catpure"
52+
>
53+
{{ t('onboarding.exploreCapture') | uppercase }}
16354
</button>
16455
</ion-slide>
16556
</ion-slides>
57+
58+
<div class="bottom-section"></div>
16659
</ion-content>
Lines changed: 76 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -1,43 +1,92 @@
1+
$top-section-height: calc(64px + env(safe-area-inset-top));
2+
$bottom-section-height: calc(56px + env(safe-area-inset-bottom));
3+
$ion-slides-height: calc(
4+
100vh - #{$top-section-height} - #{$bottom-section-height}
5+
);
6+
$ion-slide-img-height: 50vh;
7+
18
ion-content {
9+
.top-section {
10+
display: flex;
11+
flex-direction: row;
12+
align-items: center;
13+
justify-content: space-between;
14+
padding-right: 8px;
15+
padding-left: 24px;
16+
padding-top: 4vh;
17+
height: $top-section-height;
18+
width: 100vw;
19+
20+
ion-img {
21+
height: 32px;
22+
width: 135px;
23+
}
24+
25+
button {
26+
font-style: normal;
27+
font-weight: 500;
28+
font-size: 16px;
29+
line-height: 21px;
30+
text-align: right;
31+
color: white;
32+
border: none;
33+
}
34+
}
35+
236
ion-slides {
3-
--bullet-background-active: white;
37+
height: $ion-slides-height;
38+
39+
--bullet-background: white;
40+
--bullet-background-active: #486cd9;
441

542
ion-slide {
643
flex-direction: column;
44+
justify-content: space-around;
745
background-color: var(--noir-primary);
8-
height: 100vh;
946

10-
svg {
11-
padding-top: 8vh;
12-
padding-bottom: calc(12vh + env(safe-area-inset-bottom));
47+
.slide-image {
48+
height: $ion-slide-img-height;
49+
width: 100vw;
50+
object-fit: cover;
51+
}
52+
53+
.slide-text {
54+
padding-left: 4vw;
55+
padding-right: 4vw;
56+
57+
.title {
58+
font-weight: 700;
59+
text-align: center;
60+
color: white;
61+
font-size: 32px;
62+
}
63+
64+
.spacer {
65+
height: 2vh;
66+
}
67+
68+
.subtitle {
69+
font-weight: 500;
70+
text-align: center;
71+
color: white;
72+
opacity: 0.75;
73+
font-size: 16px;
74+
}
75+
}
76+
77+
.mat-button-height-placeholder {
78+
height: 36px;
1379
}
1480

15-
button {
16-
position: absolute;
17-
bottom: 10px;
18-
right: 20px;
81+
.mat-raised-button.mat-primary {
1982
color: white;
20-
font-size: 20px;
21-
padding-bottom: calc(5vh + env(safe-area-inset-bottom));
22-
border: none;
83+
width: calc(100vw - 32px);
84+
border-radius: 37px;
2385
}
2486
}
2587
}
26-
}
27-
28-
.pagination-bullets {
29-
bottom: 16px;
30-
}
31-
32-
.ios text {
33-
font-family: Helvetica, Arial, Verdana, Tahoma, sans-serif;
34-
}
3588

36-
@media (min-height: 750px) {
37-
.ios div {
38-
position: relative;
39-
width: 100%;
40-
padding: 30px;
41-
height: 90%;
89+
.bottom-section {
90+
height: $bottom-section-height;
4291
}
4392
}

src/app/features/home/onboarding/tutorial/tutorial.page.ts

Lines changed: 26 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
1-
import { Component } from '@angular/core';
1+
import { ChangeDetectorRef, Component, ViewChild } from '@angular/core';
2+
import { IonSlides } from '@ionic/angular';
23
import { UntilDestroy, untilDestroyed } from '@ngneat/until-destroy';
34
import { OnboardingService } from '../../../../shared/onboarding/onboarding.service';
45

@@ -9,7 +10,30 @@ import { OnboardingService } from '../../../../shared/onboarding/onboarding.serv
910
styleUrls: ['./tutorial.page.scss'],
1011
})
1112
export class TutorialPage {
12-
constructor(private readonly onboardingService: OnboardingService) {
13+
isLastSlide = false;
14+
15+
@ViewChild('slides') slides?: IonSlides;
16+
17+
constructor(
18+
private readonly onboardingService: OnboardingService,
19+
private readonly ref: ChangeDetectorRef
20+
) {
1321
this.onboardingService.onboard$().pipe(untilDestroyed(this)).subscribe();
1422
}
23+
24+
async ionSlideDidChange(_: any) {
25+
if (!this.slides) return;
26+
27+
const curSlideIndex = await this.slides.getActiveIndex();
28+
const totalSlides = await this.slides.length();
29+
30+
this.isLastSlide = curSlideIndex === totalSlides - 1;
31+
}
32+
33+
async skipSlides() {
34+
if (!this.slides) return;
35+
36+
const totalSlides = await this.slides.length();
37+
await this.slides.slideTo(totalSlides - 1);
38+
}
1539
}

0 commit comments

Comments
 (0)