diff --git a/cypress/e2e/1-register/register.spec.ts b/cypress/e2e/1-register/register.spec.ts index 3d710cd965b..2bbc23e0c55 100644 --- a/cypress/e2e/1-register/register.spec.ts +++ b/cypress/e2e/1-register/register.spec.ts @@ -65,6 +65,8 @@ describe("Registration", () => { cy.startMeasuring("from-submit-to-home"); cy.get(".mx_InteractiveAuthEntryComponents_termsSubmit").click(); + cy.get(".mx_UseCaseSelection_skip .mx_AccessibleButton").click(); + cy.url().should('contain', '/#/home'); cy.stopMeasuring("from-submit-to-home"); diff --git a/cypress/e2e/12-spotlight/spotlight.spec.ts b/cypress/e2e/12-spotlight/spotlight.spec.ts index 9b2f290cfa2..7b5ca76fe15 100644 --- a/cypress/e2e/12-spotlight/spotlight.spec.ts +++ b/cypress/e2e/12-spotlight/spotlight.spec.ts @@ -357,7 +357,7 @@ describe("Spotlight", () => { cy.spotlightSearch().clear().type("b"); // our debouncing logic only starts the search after a short timeout, // so we wait a few milliseconds. - cy.wait(300); + cy.wait(1000); cy.get(".mx_Spinner").should("not.exist").then(() => { cy.spotlightResults().should("have.length", 2).then(() => { cy.spotlightResults().eq(0) diff --git a/package.json b/package.json index 71051a1538a..541ea9145cc 100644 --- a/package.json +++ b/package.json @@ -56,7 +56,7 @@ }, "dependencies": { "@babel/runtime": "^7.12.5", - "@matrix-org/analytics-events": "^0.1.1", + "@matrix-org/analytics-events": "^0.1.2", "@matrix-org/react-sdk-module-api": "^0.0.3", "@sentry/browser": "^6.11.0", "@sentry/tracing": "^6.11.0", diff --git a/res/css/_components.scss b/res/css/_components.scss index 4a712d33b44..0e7187e6460 100644 --- a/res/css/_components.scss +++ b/res/css/_components.scss @@ -54,6 +54,7 @@ @import "./structures/_SpaceHierarchy.scss"; @import "./structures/_SpacePanel.scss"; @import "./structures/_SpaceRoomView.scss"; +@import "./structures/_SplashPage.scss"; @import "./structures/_TabbedView.scss"; @import "./structures/_ToastContainer.scss"; @import "./structures/_UploadBar.scss"; @@ -189,6 +190,8 @@ @import "./views/elements/_ToggleSwitch.scss"; @import "./views/elements/_Tooltip.scss"; @import "./views/elements/_TooltipButton.scss"; +@import "./views/elements/_UseCaseSelection.scss"; +@import "./views/elements/_UseCaseSelectionButton.scss"; @import "./views/elements/_Validation.scss"; @import "./views/emojipicker/_EmojiPicker.scss"; @import "./views/location/_LocationPicker.scss"; diff --git a/res/css/structures/_SplashPage.scss b/res/css/structures/_SplashPage.scss new file mode 100644 index 00000000000..5a0c2324d91 --- /dev/null +++ b/res/css/structures/_SplashPage.scss @@ -0,0 +1,63 @@ +/* +Copyright 2022 The Matrix.org Foundation C.I.C. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +.mx_SplashPage { + position: relative; + height: 100%; + + &::before { + content: ""; + display: block; + position: absolute; + z-index: -1; + opacity: 0.6; + background-image: + radial-gradient( + 53.85% 66.75% at 87.55% 0%, + hsla(250, 76%, 71%, 0.261) 0%, + hsla(250, 100%, 88%, 0) 100% + ), + radial-gradient( + 41.93% 41.93% at 0% 0%, + hsla(222, 29%, 20%, 0.28) 0%, + hsla(250, 100%, 88%, 0) 100% + ), + radial-gradient( + 100% 100% at 0% 0%, + hsla(250, 100%, 88%, 0.174) 0%, + hsla(0, 100%, 86%, 0) 100% + ), + radial-gradient( + 106.35% 96.26% at 100% 0%, + hsla(250, 100%, 88%, 0.4) 0%, + hsla(167, 76%, 82%, 0) 100% + ); + /* blur to reduce color banding issues due to alpha-blending multiple gradients */ + filter: blur(8px); + inset: -9px; + mask: + /* mask to dither resulting combined gradient */ + url("$(res)/img/noise.png"), + /* gradient to apply different amounts of dithering to different parts of the gradient */ + linear-gradient( + to bottom, + /* 10% dithering at the top */ + rgba(0, 0, 0, 0.9) 20%, + /* 80% dithering at the bottom */ + rgba(0, 0, 0, 0.2) 100% + ); + } +} diff --git a/res/css/views/elements/_UseCaseSelection.scss b/res/css/views/elements/_UseCaseSelection.scss new file mode 100644 index 00000000000..bcf1d4c1aa5 --- /dev/null +++ b/res/css/views/elements/_UseCaseSelection.scss @@ -0,0 +1,129 @@ +/* +Copyright 2022 The Matrix.org Foundation C.I.C. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +.mx_UseCaseSelection { + display: grid; + grid-template-rows: 1fr 1fr max-content 2fr; + height: 100%; + grid-gap: $spacing-40; + + .mx_UseCaseSelection_title { + display: flex; + flex-direction: column; + justify-content: end; + + h1 { + font-weight: 600; + font-size: $font-32px; + text-align: center; + } + } + + .mx_UseCaseSelection_info { + display: flex; + flex-direction: column; + gap: $spacing-8; + align-self: end; + + h2 { + margin: 0; + font-weight: 500; + font-size: $font-24px; + text-align: center; + } + + h4 { + margin: 0; + font-weight: 400; + font-size: $font-16px; + color: $secondary-content; + text-align: center; + } + } + + .mx_UseCaseSelection_options { + display: grid; + grid-template-columns: repeat(auto-fit, 232px); + gap: $spacing-32; + align-self: stretch; + justify-content: center; + } + + .mx_UseCaseSelection_skip { + display: flex; + flex-direction: column; + align-self: start; + } +} + +.mx_UseCaseSelection_slideIn { + animation-delay: 800ms; + animation-duration: 300ms; + animation-timing-function: cubic-bezier(0, 0, 0.58, 1); + animation-name: mx_UseCaseSelection_slideInLong; + animation-fill-mode: backwards; + will-change: opacity; +} + +.mx_UseCaseSelection_slideInDelayed { + animation-delay: 1500ms; + animation-duration: 300ms; + animation-timing-function: cubic-bezier(0, 0, 0.58, 1); + animation-name: mx_UseCaseSelection_slideInShort; + animation-fill-mode: backwards; + will-change: transform, opacity; +} + +.mx_UseCaseSelection_selected { + .mx_UseCaseSelection_slideIn, .mx_UseCaseSelection_slideInDelayed { + animation-delay: 800ms; + animation-duration: 300ms; + animation-fill-mode: forwards; + animation-name: mx_UseCaseSelection_fadeOut; + will-change: opacity; + } +} + +@keyframes mx_UseCaseSelection_slideInLong { + 0% { + transform: translate(0, 20px); + opacity: 0; + } + 100% { + transform: translate(0, 0); + opacity: 1; + } +} + +@keyframes mx_UseCaseSelection_slideInShort { + 0% { + transform: translate(0, 8px); + opacity: 0; + } + 100% { + transform: translate(0, 0); + opacity: 1; + } +} + +@keyframes mx_UseCaseSelection_fadeOut { + 0% { + opacity: 1; + } + 100% { + opacity: 0; + } +} diff --git a/res/css/views/elements/_UseCaseSelectionButton.scss b/res/css/views/elements/_UseCaseSelectionButton.scss new file mode 100644 index 00000000000..7a44e793473 --- /dev/null +++ b/res/css/views/elements/_UseCaseSelectionButton.scss @@ -0,0 +1,104 @@ +/* +Copyright 2022 The Matrix.org Foundation C.I.C. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +.mx_UseCaseSelectionButton { + display: flex; + flex-direction: column; + align-items: center; + padding: $spacing-24 $spacing-16; + background: $background; + border: 1px solid $quinary-content; + border-radius: 8px; + text-align: center; + position: relative; + transition-property: box-shadow, transform; + transition-duration: 300ms; + + .mx_UseCaseSelectionButton_icon { + /* workaround: design expects a layering of two colors */ + background: linear-gradient(0deg, rgba(172, 59, 168, 0.15), rgba(172, 59, 168, 0.15)), #FFFFFF; + border-radius: 14px; + padding: $spacing-8; + margin-bottom: $spacing-16; + + &::before { + content: ""; + display: block; + /* this has to remain the same color across all themes, + as its background has a fixed color as well */ + background: #1E1E1E; + mask-position: center; + mask-repeat: no-repeat; + mask-size: contain; + width: 22px; + height: 22px; + } + + &.mx_UseCaseSelectionButton_messaging::before { + mask-image: url('$(res)/img/element-icons/chat-bubble.svg'); + } + + &.mx_UseCaseSelectionButton_work::before { + mask-image: url('$(res)/img/element-icons/view-community.svg'); + } + + &.mx_UseCaseSelectionButton_community::before { + mask-image: url('$(res)/img/globe.svg'); + } + } + + &:hover, &:focus { + box-shadow: 0 $spacing-4 $spacing-8 rgba(0, 0, 0, 0.08); + transform: translate(0, -$spacing-8); + } + + .mx_UseCaseSelectionButton_selectedIcon { + right: -12px; + top: -12px; + position: absolute; + border-radius: 24px; + background: $accent; + padding: 6px; + transition-property: opacity, transform; + transition-duration: 150ms; + opacity: 0; + transform: scale(0.6); + + &::before { + content: ""; + display: block; + background: $background; + mask-position: center; + mask-repeat: no-repeat; + mask-size: contain; + width: 12px; + height: 12px; + + mask-image: url('$(res)/img/element-icons/check-white.svg'); + } + } + + &.mx_UseCaseSelectionButton_selected { + border: 2px solid $accent; + padding: calc($spacing-24 - 1px) calc($spacing-16 - 1px); + box-shadow: 0 $spacing-4 $spacing-8 rgba(0, 0, 0, 0.08); + + .mx_UseCaseSelectionButton_selectedIcon { + opacity: 1; + transform: scale(1); + } + } +} diff --git a/res/img/element-icons/chat-bubble.svg b/res/img/element-icons/chat-bubble.svg new file mode 100644 index 00000000000..3b0e765843f --- /dev/null +++ b/res/img/element-icons/chat-bubble.svg @@ -0,0 +1,3 @@ + + + diff --git a/res/img/element-icons/group-members.svg b/res/img/element-icons/group-members.svg index 553ba3b1af1..7fa9c392320 100644 --- a/res/img/element-icons/group-members.svg +++ b/res/img/element-icons/group-members.svg @@ -1,8 +1,3 @@ - - - - - - - + + diff --git a/res/img/element-icons/view-community.svg b/res/img/element-icons/view-community.svg index ee33aa525e4..9bd7115a47f 100644 --- a/res/img/element-icons/view-community.svg +++ b/res/img/element-icons/view-community.svg @@ -1,8 +1,3 @@ - - - - - - - + + diff --git a/res/img/globe.svg b/res/img/globe.svg index 635fa91cceb..954a16d478d 100644 --- a/res/img/globe.svg +++ b/res/img/globe.svg @@ -1,3 +1,3 @@ - - + + diff --git a/res/img/noise.png b/res/img/noise.png new file mode 100644 index 00000000000..05351f89b6a Binary files /dev/null and b/res/img/noise.png differ diff --git a/res/themes/dark/css/_dark.scss b/res/themes/dark/css/_dark.scss index 4f36d5979c9..b64194010e1 100644 --- a/res/themes/dark/css/_dark.scss +++ b/res/themes/dark/css/_dark.scss @@ -310,3 +310,28 @@ body { background: #53232a; } // ******************** + +// Splash Page Gradient +.mx_SplashPage::before { + background-image: + radial-gradient( + 53.85% 66.75% at 87.55% 0%, + hsla(0, 0%, 11%, 0.15) 0%, + hsla(250, 100%, 88%, 0) 100% + ), + radial-gradient( + 41.93% 41.93% at 0% 0%, + hsla(0, 0%, 38%, 0.28) 0%, + hsla(250, 100%, 88%, 0) 100% + ), + radial-gradient( + 100% 100% at 0% 0%, + hsla(250, 100%, 88%, 0.3) 0%, + hsla(0, 100%, 86%, 0) 100% + ), + radial-gradient( + 106.35% 96.26% at 100% 0%, + hsla(25, 100%, 88%, 0.4) 0%, + hsla(167, 76%, 82%, 0) 100% + ) !important; +} diff --git a/src/PosthogTrackers.ts b/src/PosthogTrackers.ts index f0cb75f3686..0422f0bf9b6 100644 --- a/src/PosthogTrackers.ts +++ b/src/PosthogTrackers.ts @@ -30,6 +30,7 @@ const notLoggedInMap: Record, ScreenName> = { [Views.WELCOME]: "Welcome", [Views.LOGIN]: "Login", [Views.REGISTER]: "Register", + [Views.USE_CASE_SELECTION]: "UseCaseSelection", [Views.FORGOT_PASSWORD]: "ForgotPassword", [Views.COMPLETE_SECURITY]: "CompleteSecurity", [Views.E2E_SETUP]: "E2ESetup", diff --git a/src/Views.ts b/src/Views.ts index 4c734f7bba1..447dbeab84d 100644 --- a/src/Views.ts +++ b/src/Views.ts @@ -38,6 +38,9 @@ enum Views { // flow to setup SSSS / cross-signing on this account E2E_SETUP, + // screen that allows users to select which use case they’ll use matrix for + USE_CASE_SELECTION, + // we are logged in with an active matrix client. The logged_in state also // includes guests users as they too are logged in at the client level. LOGGED_IN, diff --git a/src/components/structures/MatrixChat.tsx b/src/components/structures/MatrixChat.tsx index 3f6ffd11546..ea2852df3d5 100644 --- a/src/components/structures/MatrixChat.tsx +++ b/src/components/structures/MatrixChat.tsx @@ -68,6 +68,7 @@ import { FontWatcher } from '../../settings/watchers/FontWatcher'; import { storeRoomAliasInCache } from '../../RoomAliasCache'; import ToastStore from "../../stores/ToastStore"; import * as StorageManager from "../../utils/StorageManager"; +import { UseCase } from "../../settings/enums/UseCase"; import type LoggedInViewType from "./LoggedInView"; import LoggedInView from './LoggedInView'; import { Action } from "../../dispatcher/actions"; @@ -129,6 +130,7 @@ import { SnakedObject } from "../../utils/SnakedObject"; import { leaveRoomBehaviour } from "../../utils/leave-behaviour"; import VideoChannelStore from "../../stores/VideoChannelStore"; import { IRoomStateEventsActionPayload } from "../../actions/MatrixActionCreators"; +import { UseCaseSelection } from '../views/elements/UseCaseSelection'; // legacy export export { default as Views } from "../../Views"; @@ -755,7 +757,8 @@ export default class MatrixChat extends React.PureComponent { this.state.view !== Views.LOGIN && this.state.view !== Views.REGISTER && this.state.view !== Views.COMPLETE_SECURITY && - this.state.view !== Views.E2E_SETUP + this.state.view !== Views.E2E_SETUP && + this.state.view !== Views.USE_CASE_SELECTION ) { this.onLoggedIn(); } @@ -1206,6 +1209,40 @@ export default class MatrixChat extends React.PureComponent { private async onLoggedIn() { ThemeController.isLogin = false; this.themeWatcher.recheck(); + StorageManager.tryPersistStorage(); + + if ( + MatrixClientPeg.currentUserIsJustRegistered() && + SettingsStore.getValue("FTUE.useCaseSelection") === null + ) { + this.setStateForNewView({ view: Views.USE_CASE_SELECTION }); + + // Listen to changes in settings and hide the use case screen if appropriate - this is necessary because + // account settings can still be changing at this point in app init (due to the initial sync being cached, + // then subsequent syncs being received from the server) + // + // This seems unlikely for something that should happen directly after registration, but if a user does + // their initial login on another device/browser than they registered on, we want to avoid asking this + // question twice + // + // initPosthogAnalyticsToast pioneered this technique, we’re just reusing it here. + SettingsStore.watchSetting("FTUE.useCaseSelection", null, + (originalSettingName, changedInRoomId, atLevel, newValueAtLevel, newValue) => { + if (newValue !== null && this.state.view === Views.USE_CASE_SELECTION) { + this.onShowPostLoginScreen(); + } + }); + } else { + return this.onShowPostLoginScreen(); + } + } + + private async onShowPostLoginScreen(useCase?: UseCase) { + if (useCase) { + PosthogAnalytics.instance.setProperty("ftueUseCaseSelection", useCase); + SettingsStore.setValue("FTUE.useCaseSelection", null, SettingLevel.ACCOUNT, useCase); + } + this.setStateForNewView({ view: Views.LOGGED_IN }); // If a specific screen is set to be shown after login, show that above // all else, as it probably means the user clicked on something already. @@ -1243,8 +1280,7 @@ export default class MatrixChat extends React.PureComponent { this.showScreenAfterLogin(); } - StorageManager.tryPersistStorage(); - + // Will be moved to a pre-login flow as well if (PosthogAnalytics.instance.isEnabled() && SettingsStore.isLevelSupported(SettingLevel.ACCOUNT)) { this.initPosthogAnalyticsToast(); } @@ -2005,6 +2041,10 @@ export default class MatrixChat extends React.PureComponent { fragmentAfterLogin={fragmentAfterLogin} /> ); + } else if (this.state.view === Views.USE_CASE_SELECTION) { + view = ( + this.onShowPostLoginScreen(useCase)} /> + ); } else { logger.error(`Unknown view ${this.state.view}`); } diff --git a/src/components/structures/SplashPage.tsx b/src/components/structures/SplashPage.tsx new file mode 100644 index 00000000000..539e2f9ae0f --- /dev/null +++ b/src/components/structures/SplashPage.tsx @@ -0,0 +1,27 @@ +/* +Copyright 2022 The Matrix.org Foundation C.I.C. +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + http://www.apache.org/licenses/LICENSE-2.0 +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +import classNames from "classnames"; +import React, { DetailedHTMLProps, HTMLAttributes, ReactNode } from "react"; + +interface Props extends DetailedHTMLProps, HTMLElement> { + className?: string; + children?: ReactNode; +} + +export default function SplashPage({ children, className, ...other }: Props) { + const classes = classNames(className, "mx_SplashPage"); + return
+ { children } +
; +} diff --git a/src/components/views/elements/UseCaseSelection.tsx b/src/components/views/elements/UseCaseSelection.tsx new file mode 100644 index 00000000000..4e8a1e83428 --- /dev/null +++ b/src/components/views/elements/UseCaseSelection.tsx @@ -0,0 +1,86 @@ +/* +Copyright 2022 The Matrix.org Foundation C.I.C. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +import classNames from "classnames"; +import React, { useEffect, useState } from 'react'; + +import { _t } from "../../../languageHandler"; +import { UseCase } from "../../../settings/enums/UseCase"; +import SplashPage from "../../structures/SplashPage"; +import AccessibleButton from "../elements/AccessibleButton"; +import { UseCaseSelectionButton } from "./UseCaseSelectionButton"; + +interface Props { + onFinished: (useCase: UseCase) => void; +} + +const TIMEOUT = 1500; + +export function UseCaseSelection({ onFinished }: Props) { + const [selection, setSelected] = useState(null); + + useEffect(() => { + if (selection) { + setSelected(selection); + let handler: number | null = setTimeout(() => { + handler = null; + onFinished(selection); + }, TIMEOUT); + return () => { + clearTimeout(handler); + handler = null; + }; + } + }, [selection, onFinished]); + + return ( + +
+

{ _t("You're in") }

+
+
+

{ _t("Who will you chat to the most?") }

+

{ _t("We'll help you get connected.") }

+
+
+ + + +
+
+ setSelected(UseCase.Skip)}> + { _t("Skip") } + +
+ + ); +} diff --git a/src/components/views/elements/UseCaseSelectionButton.tsx b/src/components/views/elements/UseCaseSelectionButton.tsx new file mode 100644 index 00000000000..59e022df05c --- /dev/null +++ b/src/components/views/elements/UseCaseSelectionButton.tsx @@ -0,0 +1,59 @@ +/* +Copyright 2022 The Matrix.org Foundation C.I.C. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +import classNames from "classnames"; +import React from "react"; + +import { _t } from "../../../languageHandler"; +import { UseCase } from "../../../settings/enums/UseCase"; +import AccessibleButton from "./AccessibleButton"; + +interface Props { + useCase: UseCase; + selected: boolean; + onClick: (useCase: UseCase) => void; +} + +export function UseCaseSelectionButton({ useCase, onClick, selected }: Props) { + let label: string; + switch (useCase) { + case UseCase.PersonalMessaging: + label = _t("Friends and family"); + break; + case UseCase.WorkMessaging: + label = _t("Coworkers and teams"); + break; + case UseCase.CommunityMessaging: + label = _t("Online community members"); + break; + } + + return ( + onClick(useCase)}> +
+ { label } +
+ + ); +} diff --git a/src/i18n/strings/en_EN.json b/src/i18n/strings/en_EN.json index 6803a57b4f7..f3dcd72288b 100644 --- a/src/i18n/strings/en_EN.json +++ b/src/i18n/strings/en_EN.json @@ -2373,6 +2373,13 @@ "Continue with %(provider)s": "Continue with %(provider)s", "Sign in with single sign-on": "Sign in with single sign-on", "And %(count)s more...|other": "And %(count)s more...", + "You're in": "You're in", + "Who will you chat to the most?": "Who will you chat to the most?", + "We'll help you get connected.": "We'll help you get connected.", + "Skip": "Skip", + "Friends and family": "Friends and family", + "Coworkers and teams": "Coworkers and teams", + "Online community members": "Online community members", "Enter a server name": "Enter a server name", "Looks good": "Looks good", "You are not allowed to view this server's rooms list": "You are not allowed to view this server's rooms list", @@ -2742,7 +2749,6 @@ "Please check your email and click on the link it contains. Once this is done, click continue.": "Please check your email and click on the link it contains. Once this is done, click continue.", "Email address": "Email address", "This will allow you to reset your password and receive notifications.": "This will allow you to reset your password and receive notifications.", - "Skip": "Skip", "Share Room": "Share Room", "Link to most recent message": "Link to most recent message", "Share User": "Share User", diff --git a/src/settings/Settings.tsx b/src/settings/Settings.tsx index d783c19db32..8aa6a30f633 100644 --- a/src/settings/Settings.tsx +++ b/src/settings/Settings.tsx @@ -698,6 +698,10 @@ export const SETTINGS: {[setting: string]: ISetting} = { displayName: _td('Send analytics data'), default: null, }, + "FTUE.useCaseSelection": { + supportedLevels: LEVELS_ACCOUNT_SETTINGS, + default: null, + }, "autocompleteDelay": { supportedLevels: LEVELS_DEVICE_ONLY_SETTINGS_WITH_CONFIG, default: 200, diff --git a/src/settings/enums/UseCase.tsx b/src/settings/enums/UseCase.tsx new file mode 100644 index 00000000000..be101b09749 --- /dev/null +++ b/src/settings/enums/UseCase.tsx @@ -0,0 +1,22 @@ +/* +Copyright 2022 The Matrix.org Foundation C.I.C. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +export enum UseCase { + PersonalMessaging = "PersonalMessaging", + WorkMessaging = "WorkMessaging", + CommunityMessaging = "CommunityMessaging", + Skip = "Skip", +} diff --git a/test/end-to-end-tests/src/usecases/signup.ts b/test/end-to-end-tests/src/usecases/signup.ts index 86d27205356..5099d7584e1 100644 --- a/test/end-to-end-tests/src/usecases/signup.ts +++ b/test/end-to-end-tests/src/usecases/signup.ts @@ -77,6 +77,10 @@ export async function signup( const acceptButton = await session.query('.mx_InteractiveAuthEntryComponents_termsSubmit'); await acceptButton.click(); + //now click the 'Skip' button to skip the use case selection + const skipUseCaseButton = await session.query('.mx_UseCaseSelection_skip .mx_AccessibleButton'); + await skipUseCaseButton.click(); + //wait for registration to finish so the hash gets set //onhashchange better? diff --git a/yarn.lock b/yarn.lock index 10b1f6c3518..96b1f59b0b6 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1570,10 +1570,10 @@ resolved "https://registry.yarnpkg.com/@mapbox/whoots-js/-/whoots-js-3.1.0.tgz#497c67a1cef50d1a2459ba60f315e448d2ad87fe" integrity sha512-Es6WcD0nO5l+2BOQS4uLfNPYQaNDfbot3X1XUoloz+x0mPDS3eeORZJl06HXjwBG1fOGwCRnzK88LMdxKRrd6Q== -"@matrix-org/analytics-events@^0.1.1": - version "0.1.1" - resolved "https://registry.yarnpkg.com/@matrix-org/analytics-events/-/analytics-events-0.1.1.tgz#ae95b0c1fb86a094c5f51d121f10e6a1b1ddca68" - integrity sha512-PIDkfYMNmph6x/rfgtIeQXUWj9hGzTLnOCFUYZFBnoTiS4UXkH73bz77Ho12uoUezUz4v40mxTXdrFxp8Zo6zA== +"@matrix-org/analytics-events@^0.1.2": + version "0.1.2" + resolved "https://registry.yarnpkg.com/@matrix-org/analytics-events/-/analytics-events-0.1.2.tgz#820b1a78d1471f21da96274d92eb161b41f9e880" + integrity sha512-TumnmENiuTtSmfcVwzovLDq4pRgRlUmuq1bxOtli9XWMgscs3Z6URu5PJcvuFj87L7bKJrGCNS3zR+DMUxc7kg== "@matrix-org/olm@https://gitlab.matrix.org/api/v4/projects/27/packages/npm/@matrix-org/olm/-/@matrix-org/olm-3.2.8.tgz": version "3.2.8"