Skip to content
This repository was archived by the owner on Sep 11, 2024. It is now read-only.

Commit 17ba914

Browse files
committed
Implement button to return to user onboarding screen
1 parent 1e4c336 commit 17ba914

File tree

10 files changed

+183
-2
lines changed

10 files changed

+183
-2
lines changed

cypress/e2e/user-onboarding/user-onboarding-new.ts

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,8 +47,11 @@ describe("User Onboarding (new user)", () => {
4747
cy.stopSynapse(synapse);
4848
});
4949

50-
it("page is shown", () => {
50+
it("page is shown and preference exists", () => {
5151
cy.get('.mx_UserOnboardingPage').should('exist');
52+
cy.get('.mx_UserOnboardingButton').should('exist');
53+
cy.openUserSettings("Preferences");
54+
cy.contains("Show shortcut to welcome page above the room list").should("exist");
5255
cy.percySnapshot("User onboarding page");
5356
});
5457

cypress/e2e/user-onboarding/user-onboarding-old.ts

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,10 @@ describe("User Onboarding (old user)", () => {
4040
cy.stopSynapse(synapse);
4141
});
4242

43-
it("page is hidden", () => {
43+
it("page and preference are hidden", () => {
4444
cy.get('.mx_UserOnboardingPage').should('not.exist');
45+
cy.get('.mx_UserOnboardingButton').should('not.exist');
46+
cy.openUserSettings("Preferences");
47+
cy.contains("Show shortcut to welcome page above the room list").should("not.exist");
4548
});
4649
});

res/css/_components.pcss

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -328,6 +328,7 @@
328328
@import "./views/user-onboarding/_UserOnboardingList.pcss";
329329
@import "./views/user-onboarding/_UserOnboardingPage.pcss";
330330
@import "./views/user-onboarding/_UserOnboardingTask.pcss";
331+
@import "./views/user-onboarding/_UserOnboardingButton.pcss";
331332
@import "./views/verification/_VerificationShowSas.pcss";
332333
@import "./views/voip/CallView/_CallViewButtons.pcss";
333334
@import "./views/voip/_CallPreview.pcss";
Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
.mx_UserOnboardingButton {
2+
display: flex;
3+
flex-direction: column;
4+
align-content: stretch;
5+
align-items: stretch;
6+
border-radius: 8px;
7+
margin: $spacing-8 $spacing-8 0;
8+
padding: $spacing-12;
9+
10+
&.mx_UserOnboardingButton_selected,
11+
&:hover,
12+
&:focus-within {
13+
background-color: $panel-actions;
14+
}
15+
16+
.mx_UserOnboardingButton_content {
17+
display: flex;
18+
flex-direction: row;
19+
gap: 5px;
20+
align-items: center;
21+
22+
.mx_Heading_h4 {
23+
margin-right: auto;
24+
font-size: $font-14px;
25+
color: $primary-content;
26+
}
27+
28+
.mx_UserOnboardingButton_percentage {
29+
font-size: $font-12px;
30+
color: $secondary-content;
31+
}
32+
33+
.mx_UserOnboardingButton_close {
34+
position: relative;
35+
box-sizing: border-box;
36+
width: 14px;
37+
height: 14px;
38+
border-radius: 7px;
39+
border: 1px solid $secondary-content;
40+
flex-shrink: 0;
41+
42+
&::before {
43+
background-color: $secondary-content;
44+
content: "";
45+
mask-repeat: no-repeat;
46+
mask-position: center;
47+
mask-size: contain;
48+
width: 7px;
49+
height: 7px;
50+
position: absolute;
51+
left: 50%;
52+
top: 50%;
53+
transform: translate(-50%, -50%);
54+
mask-image: url("$(res)/img/element-icons/cancel-rounded.svg");
55+
}
56+
}
57+
}
58+
59+
.mx_ProgressBar {
60+
width: auto;
61+
margin-top: $spacing-8;
62+
background: $background;
63+
}
64+
65+
&.mx_UserOnboardingButton_completed .mx_ProgressBar {
66+
display: none;
67+
}
68+
}

src/components/structures/LeftPanel.tsx

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,9 +45,12 @@ import { shouldShowComponent } from "../../customisations/helpers/UIComponents";
4545
import { UIComponent } from "../../settings/UIFeature";
4646
import { ButtonEvent } from "../views/elements/AccessibleButton";
4747
import PosthogTrackers from "../../PosthogTrackers";
48+
import PageType from "../../PageTypes";
49+
import { UserOnboardingButton } from "../views/user-onboarding/UserOnboardingButton";
4850

4951
interface IProps {
5052
isMinimized: boolean;
53+
pageType: PageType;
5154
resizeNotifier: ResizeNotifier;
5255
}
5356

@@ -390,6 +393,10 @@ export default class LeftPanel extends React.Component<IProps, IState> {
390393
onVisibilityChange={this.refreshStickyHeaders}
391394
/>
392395
) }
396+
<UserOnboardingButton
397+
selected={this.props.pageType === PageType.HomePage}
398+
minimized={this.props.isMinimized}
399+
/>
393400
<div className="mx_LeftPanel_roomListWrapper">
394401
<div
395402
className={roomListClasses}

src/components/structures/LoggedInView.tsx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -689,6 +689,7 @@ class LoggedInView extends React.Component<IProps, IState> {
689689
data-collapsed={this.props.collapseLhs ? true : undefined}
690690
>
691691
<LeftPanel
692+
pageType={this.props.page_type as PageTypes}
692693
isMinimized={this.props.collapseLhs || false}
693694
resizeNotifier={this.props.resizeNotifier}
694695
/>

src/components/views/settings/tabs/user/PreferencesUserSettingsTab.tsx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@ interface IState {
4444
export default class PreferencesUserSettingsTab extends React.Component<IProps, IState> {
4545
static ROOM_LIST_SETTINGS = [
4646
'breadcrumbs',
47+
"FTUE.userOnboardingButton",
4748
];
4849

4950
static SPACES_SETTINGS = [
Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,90 @@
1+
/*
2+
Copyright 2022 The Matrix.org Foundation C.I.C.
3+
4+
Licensed under the Apache License, Version 2.0 (the "License");
5+
you may not use this file except in compliance with the License.
6+
You may obtain a copy of the License at
7+
8+
http://www.apache.org/licenses/LICENSE-2.0
9+
10+
Unless required by applicable law or agreed to in writing, software
11+
distributed under the License is distributed on an "AS IS" BASIS,
12+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
See the License for the specific language governing permissions and
14+
limitations under the License.
15+
*/
16+
17+
import classNames from "classnames";
18+
import React, { useCallback } from "react";
19+
20+
import { Action } from "../../../dispatcher/actions";
21+
import defaultDispatcher from "../../../dispatcher/dispatcher";
22+
import { useSettingValue } from "../../../hooks/useSettings";
23+
import { useUserOnboardingTasks } from "../../../hooks/useUserOnboardingTasks";
24+
import { _t } from "../../../languageHandler";
25+
import { UseCase } from "../../../settings/enums/UseCase";
26+
import { SettingLevel } from "../../../settings/SettingLevel";
27+
import SettingsStore from "../../../settings/SettingsStore";
28+
import AccessibleButton from "../../views/elements/AccessibleButton";
29+
import ProgressBar from "../../views/elements/ProgressBar";
30+
import Heading from "../../views/typography/Heading";
31+
import { showUserOnboardingPage } from "./UserOnboardingPage";
32+
33+
function toPercentage(progress: number): string {
34+
return (progress * 100).toFixed(0);
35+
}
36+
37+
interface Props {
38+
selected: boolean;
39+
minimized: boolean;
40+
}
41+
42+
export function UserOnboardingButton({ selected, minimized }: Props) {
43+
const [completedTasks, waitingTasks] = useUserOnboardingTasks();
44+
45+
const completed = completedTasks.length;
46+
const waiting = waitingTasks.length;
47+
const total = completed + waiting;
48+
49+
const progress = waiting ? completed / total : 1;
50+
51+
const onDismiss = useCallback(() => {
52+
SettingsStore.setValue("FTUE.userOnboardingButton", null, SettingLevel.ACCOUNT, false);
53+
}, []);
54+
55+
const useCase = useSettingValue<UseCase | null>("FTUE.useCaseSelection");
56+
const visible = useSettingValue<boolean>("FTUE.userOnboardingButton");
57+
if (!visible || minimized || !showUserOnboardingPage(useCase)) {
58+
return null;
59+
}
60+
61+
return (
62+
<AccessibleButton
63+
className={classNames("mx_UserOnboardingButton", {
64+
"mx_UserOnboardingButton_selected": selected,
65+
"mx_UserOnboardingButton_minimized": minimized,
66+
"mx_UserOnboardingButton_completed": !waiting,
67+
})}
68+
onClick={() => defaultDispatcher.fire(Action.ViewHomePage)}>
69+
{ !minimized && (
70+
<>
71+
<div className="mx_UserOnboardingButton_content">
72+
<Heading size="h4" className="mx_Heading_h4">
73+
{ _t("Welcome") }
74+
</Heading>
75+
{ !completed && (
76+
<div className="mx_UserOnboardingButton_percentage">
77+
{ toPercentage(progress) }%
78+
</div>
79+
) }
80+
<AccessibleButton
81+
className="mx_UserOnboardingButton_close"
82+
onClick={onDismiss}
83+
/>
84+
</div>
85+
<ProgressBar value={completed} max={total} animated />
86+
</>
87+
) }
88+
</AccessibleButton>
89+
);
90+
}

src/i18n/strings/en_EN.json

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -951,6 +951,7 @@
951951
"Order rooms by name": "Order rooms by name",
952952
"Show rooms with unread notifications first": "Show rooms with unread notifications first",
953953
"Show shortcuts to recently viewed rooms above the room list": "Show shortcuts to recently viewed rooms above the room list",
954+
"Show shortcut to welcome page above the room list": "Show shortcut to welcome page above the room list",
954955
"Show hidden events in timeline": "Show hidden events in timeline",
955956
"Low bandwidth mode (requires compatible homeserver)": "Low bandwidth mode (requires compatible homeserver)",
956957
"Allow fallback call assist server turn.matrix.org when your homeserver does not offer one (your IP address would be shared during a call)": "Allow fallback call assist server turn.matrix.org when your homeserver does not offer one (your IP address would be shared during a call)",
@@ -1147,6 +1148,7 @@
11471148
"Anchor": "Anchor",
11481149
"Headphones": "Headphones",
11491150
"Folder": "Folder",
1151+
"Welcome": "Welcome",
11501152
"Secure messaging for friends and family": "Secure messaging for friends and family",
11511153
"With free end-to-end encrypted messaging, and unlimited voice and video calls, %(brand)s is a great way to stay in touch.": "With free end-to-end encrypted messaging, and unlimited voice and video calls, %(brand)s is a great way to stay in touch.",
11521154
"Start your first chat": "Start your first chat",

src/settings/Settings.tsx

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -804,6 +804,11 @@ export const SETTINGS: {[setting: string]: ISetting} = {
804804
default: true,
805805
controller: new IncompatibleController("feature_breadcrumbs_v2", true),
806806
},
807+
"FTUE.userOnboardingButton": {
808+
supportedLevels: LEVELS_ACCOUNT_SETTINGS,
809+
displayName: _td("Show shortcut to welcome page above the room list"),
810+
default: true,
811+
},
807812
"showHiddenEventsInTimeline": {
808813
displayName: _td("Show hidden events in timeline"),
809814
supportedLevels: LEVELS_DEVICE_ONLY_SETTINGS,

0 commit comments

Comments
 (0)