Implement Use Case Selection screen (#8984)

* Introduce new splash page wrapper
* Introduce new use case selection screen
This commit is contained in:
Janne Mareike Koschinski 2022-07-13 15:43:44 +02:00 committed by GitHub
parent bda272dce4
commit f5f79158ed
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
24 changed files with 597 additions and 26 deletions

View file

@ -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<IProps, IState> {
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<IProps, IState> {
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, were 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<IProps, IState> {
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<IProps, IState> {
fragmentAfterLogin={fragmentAfterLogin}
/>
);
} else if (this.state.view === Views.USE_CASE_SELECTION) {
view = (
<UseCaseSelection onFinished={useCase => this.onShowPostLoginScreen(useCase)} />
);
} else {
logger.error(`Unknown view ${this.state.view}`);
}

View file

@ -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<HTMLAttributes<HTMLElement>, HTMLElement> {
className?: string;
children?: ReactNode;
}
export default function SplashPage({ children, className, ...other }: Props) {
const classes = classNames(className, "mx_SplashPage");
return <main {...other} className={classes}>
{ children }
</main>;
}