The Welcome Home Screen: Return Button (#9089)
* Implement button to return to user onboarding screen * Add analytics events * Increase stability of lazy loading test
This commit is contained in:
parent
8db7766a40
commit
9eaf48b176
13 changed files with 241 additions and 28 deletions
|
@ -40,6 +40,13 @@ describe("User Onboarding (new user)", () => {
|
||||||
bot1 = _bot1;
|
bot1 = _bot1;
|
||||||
});
|
});
|
||||||
cy.get('.mx_UserOnboardingPage').should('exist');
|
cy.get('.mx_UserOnboardingPage').should('exist');
|
||||||
|
cy.get('.mx_UserOnboardingButton').should('exist');
|
||||||
|
cy.get('.mx_UserOnboardingList')
|
||||||
|
.should('exist')
|
||||||
|
.should(($list) => {
|
||||||
|
const list = $list.get(0);
|
||||||
|
expect(getComputedStyle(list).opacity).to.be.eq("1");
|
||||||
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -47,20 +54,14 @@ describe("User Onboarding (new user)", () => {
|
||||||
cy.stopSynapse(synapse);
|
cy.stopSynapse(synapse);
|
||||||
});
|
});
|
||||||
|
|
||||||
it("page is shown", () => {
|
it("page is shown and preference exists", () => {
|
||||||
cy.get('.mx_UserOnboardingPage').should('exist');
|
|
||||||
cy.get('.mx_UserOnboardingList')
|
|
||||||
.should('exist')
|
|
||||||
.should(($list) => {
|
|
||||||
const list = $list.get(0);
|
|
||||||
expect(getComputedStyle(list).opacity).to.be.eq("1");
|
|
||||||
});
|
|
||||||
cy.get('.mx_UserOnboardingPage')
|
cy.get('.mx_UserOnboardingPage')
|
||||||
.percySnapshotElement("User onboarding page");
|
.percySnapshotElement("User onboarding page");
|
||||||
|
cy.openUserSettings("Preferences");
|
||||||
|
cy.contains("Show shortcut to welcome checklist above the room list").should("exist");
|
||||||
});
|
});
|
||||||
|
|
||||||
it("app download dialog", () => {
|
it("app download dialog", () => {
|
||||||
cy.get('.mx_UserOnboardingPage').should('exist');
|
|
||||||
cy.contains(".mx_UserOnboardingTask_action", "Download apps").click();
|
cy.contains(".mx_UserOnboardingTask_action", "Download apps").click();
|
||||||
cy.get('[role=dialog]')
|
cy.get('[role=dialog]')
|
||||||
.contains("#mx_BaseDialog_title", "Download Element")
|
.contains("#mx_BaseDialog_title", "Download Element")
|
||||||
|
@ -79,8 +80,7 @@ describe("User Onboarding (new user)", () => {
|
||||||
cy.get(".mx_InviteDialog_editor input").type(bot1.getUserId());
|
cy.get(".mx_InviteDialog_editor input").type(bot1.getUserId());
|
||||||
cy.get(".mx_InviteDialog_buttonAndSpinner").click();
|
cy.get(".mx_InviteDialog_buttonAndSpinner").click();
|
||||||
cy.get(".mx_InviteDialog_buttonAndSpinner").should("not.exist");
|
cy.get(".mx_InviteDialog_buttonAndSpinner").should("not.exist");
|
||||||
cy.visit("/#/home");
|
cy.get(".mx_SendMessageComposer").type("Hi!{enter}");
|
||||||
|
|
||||||
cy.get(".mx_ProgressBar").invoke("val").should("be.greaterThan", oldProgress);
|
cy.get(".mx_ProgressBar").invoke("val").should("be.greaterThan", oldProgress);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
|
@ -40,7 +40,10 @@ describe("User Onboarding (old user)", () => {
|
||||||
cy.stopSynapse(synapse);
|
cy.stopSynapse(synapse);
|
||||||
});
|
});
|
||||||
|
|
||||||
it("page is hidden", () => {
|
it("page and preference are hidden", () => {
|
||||||
cy.get('.mx_UserOnboardingPage').should('not.exist');
|
cy.get('.mx_UserOnboardingPage').should('not.exist');
|
||||||
|
cy.get('.mx_UserOnboardingButton').should('not.exist');
|
||||||
|
cy.openUserSettings("Preferences");
|
||||||
|
cy.contains("Show shortcut to welcome page above the room list").should("not.exist");
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
|
@ -337,6 +337,7 @@
|
||||||
@import "./views/user-onboarding/_UserOnboardingList.pcss";
|
@import "./views/user-onboarding/_UserOnboardingList.pcss";
|
||||||
@import "./views/user-onboarding/_UserOnboardingPage.pcss";
|
@import "./views/user-onboarding/_UserOnboardingPage.pcss";
|
||||||
@import "./views/user-onboarding/_UserOnboardingTask.pcss";
|
@import "./views/user-onboarding/_UserOnboardingTask.pcss";
|
||||||
|
@import "./views/user-onboarding/_UserOnboardingButton.pcss";
|
||||||
@import "./views/verification/_VerificationShowSas.pcss";
|
@import "./views/verification/_VerificationShowSas.pcss";
|
||||||
@import "./views/voip/CallView/_CallViewButtons.pcss";
|
@import "./views/voip/CallView/_CallViewButtons.pcss";
|
||||||
@import "./views/voip/_CallPreview.pcss";
|
@import "./views/voip/_CallPreview.pcss";
|
||||||
|
|
84
res/css/views/user-onboarding/_UserOnboardingButton.pcss
Normal file
84
res/css/views/user-onboarding/_UserOnboardingButton.pcss
Normal file
|
@ -0,0 +1,84 @@
|
||||||
|
/*
|
||||||
|
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_UserOnboardingButton {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
align-content: stretch;
|
||||||
|
align-items: stretch;
|
||||||
|
border-radius: 8px;
|
||||||
|
margin: $spacing-8 $spacing-8 0;
|
||||||
|
padding: $spacing-12;
|
||||||
|
|
||||||
|
&.mx_UserOnboardingButton_selected,
|
||||||
|
&:hover,
|
||||||
|
&:focus-within {
|
||||||
|
background-color: $panel-actions;
|
||||||
|
}
|
||||||
|
|
||||||
|
.mx_UserOnboardingButton_content {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: row;
|
||||||
|
gap: 5px;
|
||||||
|
align-items: center;
|
||||||
|
|
||||||
|
.mx_Heading_h4 {
|
||||||
|
margin-right: auto;
|
||||||
|
font-size: $font-14px;
|
||||||
|
color: $primary-content;
|
||||||
|
}
|
||||||
|
|
||||||
|
.mx_UserOnboardingButton_percentage {
|
||||||
|
font-size: $font-12px;
|
||||||
|
color: $secondary-content;
|
||||||
|
}
|
||||||
|
|
||||||
|
.mx_UserOnboardingButton_close {
|
||||||
|
position: relative;
|
||||||
|
box-sizing: border-box;
|
||||||
|
width: 14px;
|
||||||
|
height: 14px;
|
||||||
|
border-radius: 7px;
|
||||||
|
border: 1px solid $secondary-content;
|
||||||
|
flex-shrink: 0;
|
||||||
|
|
||||||
|
&::before {
|
||||||
|
background-color: $secondary-content;
|
||||||
|
content: "";
|
||||||
|
mask-repeat: no-repeat;
|
||||||
|
mask-position: center;
|
||||||
|
mask-size: contain;
|
||||||
|
width: 7px;
|
||||||
|
height: 7px;
|
||||||
|
position: absolute;
|
||||||
|
left: 50%;
|
||||||
|
top: 50%;
|
||||||
|
transform: translate(-50%, -50%);
|
||||||
|
mask-image: url("$(res)/img/element-icons/cancel-rounded.svg");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.mx_ProgressBar {
|
||||||
|
width: auto;
|
||||||
|
margin-top: $spacing-8;
|
||||||
|
background: $background;
|
||||||
|
}
|
||||||
|
|
||||||
|
&.mx_UserOnboardingButton_completed .mx_ProgressBar {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
}
|
|
@ -45,9 +45,12 @@ import { shouldShowComponent } from "../../customisations/helpers/UIComponents";
|
||||||
import { UIComponent } from "../../settings/UIFeature";
|
import { UIComponent } from "../../settings/UIFeature";
|
||||||
import { ButtonEvent } from "../views/elements/AccessibleButton";
|
import { ButtonEvent } from "../views/elements/AccessibleButton";
|
||||||
import PosthogTrackers from "../../PosthogTrackers";
|
import PosthogTrackers from "../../PosthogTrackers";
|
||||||
|
import PageType from "../../PageTypes";
|
||||||
|
import { UserOnboardingButton } from "../views/user-onboarding/UserOnboardingButton";
|
||||||
|
|
||||||
interface IProps {
|
interface IProps {
|
||||||
isMinimized: boolean;
|
isMinimized: boolean;
|
||||||
|
pageType: PageType;
|
||||||
resizeNotifier: ResizeNotifier;
|
resizeNotifier: ResizeNotifier;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -390,6 +393,10 @@ export default class LeftPanel extends React.Component<IProps, IState> {
|
||||||
onVisibilityChange={this.refreshStickyHeaders}
|
onVisibilityChange={this.refreshStickyHeaders}
|
||||||
/>
|
/>
|
||||||
) }
|
) }
|
||||||
|
<UserOnboardingButton
|
||||||
|
selected={this.props.pageType === PageType.HomePage}
|
||||||
|
minimized={this.props.isMinimized}
|
||||||
|
/>
|
||||||
<div className="mx_LeftPanel_roomListWrapper">
|
<div className="mx_LeftPanel_roomListWrapper">
|
||||||
<div
|
<div
|
||||||
className={roomListClasses}
|
className={roomListClasses}
|
||||||
|
|
|
@ -689,6 +689,7 @@ class LoggedInView extends React.Component<IProps, IState> {
|
||||||
data-collapsed={this.props.collapseLhs ? true : undefined}
|
data-collapsed={this.props.collapseLhs ? true : undefined}
|
||||||
>
|
>
|
||||||
<LeftPanel
|
<LeftPanel
|
||||||
|
pageType={this.props.page_type as PageTypes}
|
||||||
isMinimized={this.props.collapseLhs || false}
|
isMinimized={this.props.collapseLhs || false}
|
||||||
resizeNotifier={this.props.resizeNotifier}
|
resizeNotifier={this.props.resizeNotifier}
|
||||||
/>
|
/>
|
||||||
|
|
|
@ -46,6 +46,7 @@ interface IState {
|
||||||
export default class PreferencesUserSettingsTab extends React.Component<IProps, IState> {
|
export default class PreferencesUserSettingsTab extends React.Component<IProps, IState> {
|
||||||
private static ROOM_LIST_SETTINGS = [
|
private static ROOM_LIST_SETTINGS = [
|
||||||
'breadcrumbs',
|
'breadcrumbs',
|
||||||
|
"FTUE.userOnboardingButton",
|
||||||
];
|
];
|
||||||
|
|
||||||
private static SPACES_SETTINGS = [
|
private static SPACES_SETTINGS = [
|
||||||
|
|
102
src/components/views/user-onboarding/UserOnboardingButton.tsx
Normal file
102
src/components/views/user-onboarding/UserOnboardingButton.tsx
Normal file
|
@ -0,0 +1,102 @@
|
||||||
|
/*
|
||||||
|
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, { useCallback } from "react";
|
||||||
|
|
||||||
|
import { Action } from "../../../dispatcher/actions";
|
||||||
|
import defaultDispatcher from "../../../dispatcher/dispatcher";
|
||||||
|
import { useSettingValue } from "../../../hooks/useSettings";
|
||||||
|
import { useUserOnboardingContext } from "../../../hooks/useUserOnboardingContext";
|
||||||
|
import { useUserOnboardingTasks } from "../../../hooks/useUserOnboardingTasks";
|
||||||
|
import { _t } from "../../../languageHandler";
|
||||||
|
import PosthogTrackers from "../../../PosthogTrackers";
|
||||||
|
import { UseCase } from "../../../settings/enums/UseCase";
|
||||||
|
import { SettingLevel } from "../../../settings/SettingLevel";
|
||||||
|
import SettingsStore from "../../../settings/SettingsStore";
|
||||||
|
import AccessibleButton, { ButtonEvent } from "../../views/elements/AccessibleButton";
|
||||||
|
import ProgressBar from "../../views/elements/ProgressBar";
|
||||||
|
import Heading from "../../views/typography/Heading";
|
||||||
|
import { showUserOnboardingPage } from "./UserOnboardingPage";
|
||||||
|
|
||||||
|
function toPercentage(progress: number): string {
|
||||||
|
return (progress * 100).toFixed(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
interface Props {
|
||||||
|
selected: boolean;
|
||||||
|
minimized: boolean;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function UserOnboardingButton({ selected, minimized }: Props) {
|
||||||
|
const context = useUserOnboardingContext();
|
||||||
|
const [completedTasks, waitingTasks] = useUserOnboardingTasks(context);
|
||||||
|
|
||||||
|
const completed = completedTasks.length;
|
||||||
|
const waiting = waitingTasks.length;
|
||||||
|
const total = completed + waiting;
|
||||||
|
|
||||||
|
let progress = 1;
|
||||||
|
if (context && waiting) {
|
||||||
|
progress = completed / total;
|
||||||
|
}
|
||||||
|
|
||||||
|
const onDismiss = useCallback((ev: ButtonEvent) => {
|
||||||
|
PosthogTrackers.trackInteraction("WebRoomListUserOnboardingIgnoreButton", ev);
|
||||||
|
SettingsStore.setValue("FTUE.userOnboardingButton", null, SettingLevel.ACCOUNT, false);
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
const onClick = useCallback((ev: ButtonEvent) => {
|
||||||
|
PosthogTrackers.trackInteraction("WebRoomListUserOnboardingButton", ev);
|
||||||
|
defaultDispatcher.fire(Action.ViewHomePage);
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
const useCase = useSettingValue<UseCase | null>("FTUE.useCaseSelection");
|
||||||
|
const visible = useSettingValue<boolean>("FTUE.userOnboardingButton");
|
||||||
|
if (!visible || minimized || !showUserOnboardingPage(useCase)) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<AccessibleButton
|
||||||
|
className={classNames("mx_UserOnboardingButton", {
|
||||||
|
"mx_UserOnboardingButton_selected": selected,
|
||||||
|
"mx_UserOnboardingButton_minimized": minimized,
|
||||||
|
"mx_UserOnboardingButton_completed": !waiting || !context,
|
||||||
|
})}
|
||||||
|
onClick={onClick}>
|
||||||
|
{ !minimized && (
|
||||||
|
<>
|
||||||
|
<div className="mx_UserOnboardingButton_content">
|
||||||
|
<Heading size="h4" className="mx_Heading_h4">
|
||||||
|
{ _t("Welcome") }
|
||||||
|
</Heading>
|
||||||
|
{ context && !completed && (
|
||||||
|
<div className="mx_UserOnboardingButton_percentage">
|
||||||
|
{ toPercentage(progress) }%
|
||||||
|
</div>
|
||||||
|
) }
|
||||||
|
<AccessibleButton
|
||||||
|
className="mx_UserOnboardingButton_close"
|
||||||
|
onClick={onDismiss}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<ProgressBar value={completed} max={total} animated />
|
||||||
|
</>
|
||||||
|
) }
|
||||||
|
</AccessibleButton>
|
||||||
|
);
|
||||||
|
}
|
|
@ -19,6 +19,7 @@ import * as React from "react";
|
||||||
|
|
||||||
import { useInitialSyncComplete } from "../../../hooks/useIsInitialSyncComplete";
|
import { useInitialSyncComplete } from "../../../hooks/useIsInitialSyncComplete";
|
||||||
import { useSettingValue } from "../../../hooks/useSettings";
|
import { useSettingValue } from "../../../hooks/useSettings";
|
||||||
|
import { useUserOnboardingContext } from "../../../hooks/useUserOnboardingContext";
|
||||||
import { useUserOnboardingTasks } from "../../../hooks/useUserOnboardingTasks";
|
import { useUserOnboardingTasks } from "../../../hooks/useUserOnboardingTasks";
|
||||||
import { MatrixClientPeg } from "../../../MatrixClientPeg";
|
import { MatrixClientPeg } from "../../../MatrixClientPeg";
|
||||||
import SdkConfig from "../../../SdkConfig";
|
import SdkConfig from "../../../SdkConfig";
|
||||||
|
@ -47,7 +48,8 @@ export function UserOnboardingPage({ justRegistered = false }: Props) {
|
||||||
const pageUrl = getHomePageUrl(config);
|
const pageUrl = getHomePageUrl(config);
|
||||||
|
|
||||||
const useCase = useSettingValue<UseCase | null>("FTUE.useCaseSelection");
|
const useCase = useSettingValue<UseCase | null>("FTUE.useCaseSelection");
|
||||||
const [completedTasks, waitingTasks] = useUserOnboardingTasks();
|
const context = useUserOnboardingContext();
|
||||||
|
const [completedTasks, waitingTasks] = useUserOnboardingTasks(context);
|
||||||
|
|
||||||
const initialSyncComplete = useInitialSyncComplete();
|
const initialSyncComplete = useInitialSyncComplete();
|
||||||
const [showList, setShowList] = useState<boolean>(false);
|
const [showList, setShowList] = useState<boolean>(false);
|
||||||
|
|
|
@ -14,8 +14,9 @@ See the License for the specific language governing permissions and
|
||||||
limitations under the License.
|
limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { useCallback, useEffect, useState } from "react";
|
import { logger } from "matrix-js-sdk/src/logger";
|
||||||
import { ClientEvent, IMyDevice, Room } from "matrix-js-sdk/src/matrix";
|
import { ClientEvent, IMyDevice, Room } from "matrix-js-sdk/src/matrix";
|
||||||
|
import { useCallback, useEffect, useState } from "react";
|
||||||
|
|
||||||
import { MatrixClientPeg } from "../MatrixClientPeg";
|
import { MatrixClientPeg } from "../MatrixClientPeg";
|
||||||
import DMRoomMap from "../utils/DMRoomMap";
|
import DMRoomMap from "../utils/DMRoomMap";
|
||||||
|
@ -33,6 +34,7 @@ export function useUserOnboardingContext(): UserOnboardingContext | null {
|
||||||
|
|
||||||
const cli = MatrixClientPeg.get();
|
const cli = MatrixClientPeg.get();
|
||||||
const handler = useCallback(async () => {
|
const handler = useCallback(async () => {
|
||||||
|
try {
|
||||||
const profile = await cli.getProfileInfo(cli.getUserId());
|
const profile = await cli.getProfileInfo(cli.getUserId());
|
||||||
|
|
||||||
const myDevice = cli.getDeviceId();
|
const myDevice = cli.getDeviceId();
|
||||||
|
@ -45,6 +47,10 @@ export function useUserOnboardingContext(): UserOnboardingContext | null {
|
||||||
devices: devices.devices,
|
devices: devices.devices,
|
||||||
dmRooms: dmRooms,
|
dmRooms: dmRooms,
|
||||||
});
|
});
|
||||||
|
} catch (e) {
|
||||||
|
logger.warn("Could not load context for user onboarding task list: ", e);
|
||||||
|
setContext(null);
|
||||||
|
}
|
||||||
}, [cli]);
|
}, [cli]);
|
||||||
|
|
||||||
useEventEmitter(cli, ClientEvent.AccountData, handler);
|
useEventEmitter(cli, ClientEvent.AccountData, handler);
|
||||||
|
|
|
@ -27,7 +27,7 @@ import { Notifier } from "../Notifier";
|
||||||
import PosthogTrackers from "../PosthogTrackers";
|
import PosthogTrackers from "../PosthogTrackers";
|
||||||
import { UseCase } from "../settings/enums/UseCase";
|
import { UseCase } from "../settings/enums/UseCase";
|
||||||
import { useSettingValue } from "./useSettings";
|
import { useSettingValue } from "./useSettings";
|
||||||
import { UserOnboardingContext, useUserOnboardingContext } from "./useUserOnboardingContext";
|
import { UserOnboardingContext } from "./useUserOnboardingContext";
|
||||||
|
|
||||||
export interface UserOnboardingTask {
|
export interface UserOnboardingTask {
|
||||||
id: string;
|
id: string;
|
||||||
|
@ -140,13 +140,12 @@ const tasks: InternalUserOnboardingTask[] = [
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
export function useUserOnboardingTasks(): [UserOnboardingTask[], UserOnboardingTask[]] {
|
export function useUserOnboardingTasks(context: UserOnboardingContext): [UserOnboardingTask[], UserOnboardingTask[]] {
|
||||||
const useCase = useSettingValue<UseCase | null>("FTUE.useCaseSelection") ?? UseCase.Skip;
|
const useCase = useSettingValue<UseCase | null>("FTUE.useCaseSelection") ?? UseCase.Skip;
|
||||||
const relevantTasks = useMemo(
|
const relevantTasks = useMemo(
|
||||||
() => tasks.filter(it => !it.relevant || it.relevant.includes(useCase)),
|
() => tasks.filter(it => !it.relevant || it.relevant.includes(useCase)),
|
||||||
[useCase],
|
[useCase],
|
||||||
);
|
);
|
||||||
const onboardingInfo = useUserOnboardingContext();
|
const completedTasks = relevantTasks.filter(it => context && it.completed(context));
|
||||||
const completedTasks = relevantTasks.filter(it => onboardingInfo && it.completed(onboardingInfo));
|
|
||||||
return [completedTasks, relevantTasks.filter(it => !completedTasks.includes(it))];
|
return [completedTasks, relevantTasks.filter(it => !completedTasks.includes(it))];
|
||||||
}
|
}
|
||||||
|
|
|
@ -951,6 +951,7 @@
|
||||||
"Order rooms by name": "Order rooms by name",
|
"Order rooms by name": "Order rooms by name",
|
||||||
"Show rooms with unread notifications first": "Show rooms with unread notifications first",
|
"Show rooms with unread notifications first": "Show rooms with unread notifications first",
|
||||||
"Show shortcuts to recently viewed rooms above the room list": "Show shortcuts to recently viewed rooms above the room list",
|
"Show shortcuts to recently viewed rooms above the room list": "Show shortcuts to recently viewed rooms above the room list",
|
||||||
|
"Show shortcut to welcome checklist above the room list": "Show shortcut to welcome checklist above the room list",
|
||||||
"Show hidden events in timeline": "Show hidden events in timeline",
|
"Show hidden events in timeline": "Show hidden events in timeline",
|
||||||
"Low bandwidth mode (requires compatible homeserver)": "Low bandwidth mode (requires compatible homeserver)",
|
"Low bandwidth mode (requires compatible homeserver)": "Low bandwidth mode (requires compatible homeserver)",
|
||||||
"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)",
|
"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 @@
|
||||||
"Anchor": "Anchor",
|
"Anchor": "Anchor",
|
||||||
"Headphones": "Headphones",
|
"Headphones": "Headphones",
|
||||||
"Folder": "Folder",
|
"Folder": "Folder",
|
||||||
|
"Welcome": "Welcome",
|
||||||
"How are you finding Element so far?": "How are you finding Element so far?",
|
"How are you finding Element so far?": "How are you finding Element so far?",
|
||||||
"We’d appreciate any feedback on how you’re finding Element.": "We’d appreciate any feedback on how you’re finding Element.",
|
"We’d appreciate any feedback on how you’re finding Element.": "We’d appreciate any feedback on how you’re finding Element.",
|
||||||
"Feedback": "Feedback",
|
"Feedback": "Feedback",
|
||||||
|
|
|
@ -804,6 +804,11 @@ export const SETTINGS: {[setting: string]: ISetting} = {
|
||||||
default: true,
|
default: true,
|
||||||
controller: new IncompatibleController("feature_breadcrumbs_v2", true),
|
controller: new IncompatibleController("feature_breadcrumbs_v2", true),
|
||||||
},
|
},
|
||||||
|
"FTUE.userOnboardingButton": {
|
||||||
|
supportedLevels: LEVELS_ACCOUNT_SETTINGS,
|
||||||
|
displayName: _td("Show shortcut to welcome checklist above the room list"),
|
||||||
|
default: true,
|
||||||
|
},
|
||||||
"showHiddenEventsInTimeline": {
|
"showHiddenEventsInTimeline": {
|
||||||
displayName: _td("Show hidden events in timeline"),
|
displayName: _td("Show hidden events in timeline"),
|
||||||
supportedLevels: LEVELS_DEVICE_ONLY_SETTINGS,
|
supportedLevels: LEVELS_DEVICE_ONLY_SETTINGS,
|
||||||
|
|
Loading…
Reference in a new issue