Merge pull request #6466 from matrix-org/t3chguy/fix/18096

pull/21833/head
Michael Telatynski 2021-07-29 15:53:57 +01:00 committed by GitHub
commit d587ae44af
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
18 changed files with 213 additions and 257 deletions

View File

@ -67,7 +67,6 @@
@import "./views/dialogs/_AddExistingToSpaceDialog.scss"; @import "./views/dialogs/_AddExistingToSpaceDialog.scss";
@import "./views/dialogs/_AddressPickerDialog.scss"; @import "./views/dialogs/_AddressPickerDialog.scss";
@import "./views/dialogs/_Analytics.scss"; @import "./views/dialogs/_Analytics.scss";
@import "./views/dialogs/_BetaFeedbackDialog.scss";
@import "./views/dialogs/_BugReportDialog.scss"; @import "./views/dialogs/_BugReportDialog.scss";
@import "./views/dialogs/_ChangelogDialog.scss"; @import "./views/dialogs/_ChangelogDialog.scss";
@import "./views/dialogs/_ChatCreateOrReuseChatDialog.scss"; @import "./views/dialogs/_ChatCreateOrReuseChatDialog.scss";
@ -82,6 +81,7 @@
@import "./views/dialogs/_EditCommunityPrototypeDialog.scss"; @import "./views/dialogs/_EditCommunityPrototypeDialog.scss";
@import "./views/dialogs/_FeedbackDialog.scss"; @import "./views/dialogs/_FeedbackDialog.scss";
@import "./views/dialogs/_ForwardDialog.scss"; @import "./views/dialogs/_ForwardDialog.scss";
@import "./views/dialogs/_GenericFeatureFeedbackDialog.scss";
@import "./views/dialogs/_GroupAddressPicker.scss"; @import "./views/dialogs/_GroupAddressPicker.scss";
@import "./views/dialogs/_HostSignupDialog.scss"; @import "./views/dialogs/_HostSignupDialog.scss";
@import "./views/dialogs/_IncomingSasDialog.scss"; @import "./views/dialogs/_IncomingSasDialog.scss";

View File

@ -61,6 +61,7 @@ limitations under the License.
.mx_AccessibleButton_kind_link { .mx_AccessibleButton_kind_link {
padding: 0; padding: 0;
font-size: inherit;
} }
.mx_SearchBox { .mx_SearchBox {

View File

@ -335,24 +335,17 @@ $SpaceRoomViewInnerWidth: 428px;
word-wrap: break-word; word-wrap: break-word;
} }
> hr {
border: none;
height: 1px;
background-color: $groupFilterPanel-bg-color;
}
.mx_SearchBox { .mx_SearchBox {
margin: 0 0 20px; margin: 0 0 20px;
flex: 0; flex: 0;
} }
.mx_SpaceFeedbackPrompt { .mx_SpaceFeedbackPrompt {
margin-bottom: 16px; padding: 7px; // 8px - 1px border
border: 1px solid $menu-border-color;
// hide the HR as we have our own border-radius: 8px;
& + hr { width: max-content;
display: none; margin: 0 0 -40px auto; // collapse its own height to not push other components down
}
} }
.mx_SpaceRoomDirectory_list { .mx_SpaceRoomDirectory_list {
@ -513,66 +506,3 @@ $SpaceRoomViewInnerWidth: 428px;
} }
} }
} }
.mx_SpaceFeedbackPrompt {
margin-top: 18px;
margin-bottom: 12px;
> hr {
border: none;
border-top: 1px solid $input-border-color;
margin-bottom: 12px;
}
> div {
display: flex;
flex-direction: row;
font-size: $font-15px;
line-height: $font-24px;
> span {
color: $secondary-fg-color;
position: relative;
padding-left: 32px;
font-size: inherit;
line-height: inherit;
margin-right: auto;
&::before {
content: '';
position: absolute;
left: 0;
top: 2px;
height: 20px;
width: 20px;
background-color: $secondary-fg-color;
mask-repeat: no-repeat;
mask-size: contain;
mask-image: url('$(res)/img/element-icons/room/room-summary.svg');
mask-position: center;
}
}
.mx_AccessibleButton_kind_link {
color: $accent-color;
position: relative;
padding: 0 0 0 24px;
margin-left: 8px;
font-size: inherit;
line-height: inherit;
&::before {
content: '';
position: absolute;
left: 0;
height: 16px;
width: 16px;
background-color: $accent-color;
mask-repeat: no-repeat;
mask-size: contain;
mask-image: url('$(res)/img/element-icons/chat-bubbles.svg');
mask-position: center;
}
}
}
}

View File

@ -14,8 +14,8 @@ See the License for the specific language governing permissions and
limitations under the License. limitations under the License.
*/ */
.mx_BetaFeedbackDialog { .mx_GenericFeatureFeedbackDialog {
.mx_BetaFeedbackDialog_subheading { .mx_GenericFeatureFeedbackDialog_subheading {
color: $primary-fg-color; color: $primary-fg-color;
font-size: $font-14px; font-size: $font-14px;
line-height: $font-20px; line-height: $font-20px;

View File

@ -43,6 +43,12 @@ $spacePanelWidth: 71px;
color: $secondary-fg-color; color: $secondary-fg-color;
margin: 0; margin: 0;
} }
.mx_SpaceFeedbackPrompt {
border-top: 1px solid $input-border-color;
padding-top: 12px;
margin-top: 16px;
}
} }
// XXX remove this when spaces leaves Beta // XXX remove this when spaces leaves Beta
@ -99,3 +105,25 @@ $spacePanelWidth: 71px;
} }
} }
} }
.mx_SpaceFeedbackPrompt {
font-size: $font-15px;
line-height: $font-24px;
> span {
color: $secondary-fg-color;
position: relative;
font-size: inherit;
line-height: inherit;
margin-right: auto;
}
.mx_AccessibleButton_kind_link {
color: $accent-color;
position: relative;
padding: 0;
margin-left: 8px;
font-size: inherit;
line-height: inherit;
}
}

View File

@ -72,10 +72,8 @@ import IconizedContextMenu, {
import AccessibleTooltipButton from "../views/elements/AccessibleTooltipButton"; import AccessibleTooltipButton from "../views/elements/AccessibleTooltipButton";
import { BetaPill } from "../views/beta/BetaCard"; import { BetaPill } from "../views/beta/BetaCard";
import { UserTab } from "../views/dialogs/UserSettingsDialog"; import { UserTab } from "../views/dialogs/UserSettingsDialog";
import Modal from "../../Modal";
import BetaFeedbackDialog from "../views/dialogs/BetaFeedbackDialog";
import SdkConfig from "../../SdkConfig";
import { EffectiveMembership, getEffectiveMembership } from "../../utils/membership"; import { EffectiveMembership, getEffectiveMembership } from "../../utils/membership";
import { SpaceFeedbackPrompt } from "../views/spaces/SpaceCreateMenu";
interface IProps { interface IProps {
space: Room; space: Room;
@ -102,28 +100,6 @@ enum Phase {
PrivateExistingRooms, PrivateExistingRooms,
} }
// XXX: Temporary for the Spaces Beta only
export const SpaceFeedbackPrompt = ({ onClick }: { onClick?: () => void }) => {
if (!SdkConfig.get().bug_report_endpoint_url) return null;
return <div className="mx_SpaceFeedbackPrompt">
<hr />
<div>
<span className="mx_SpaceFeedbackPrompt_text">{ _t("Spaces are a beta feature.") }</span>
<AccessibleButton
kind="link"
onClick={() => {
if (onClick) onClick();
Modal.createTrackedDialog("Beta Feedback", "feature_spaces", BetaFeedbackDialog, {
featureId: "feature_spaces",
});
}}>
{ _t("Feedback") }
</AccessibleButton>
</div>
</div>;
};
const RoomMemberCount = ({ room, children }) => { const RoomMemberCount = ({ room, children }) => {
const members = useRoomMembers(room); const members = useRoomMembers(room);
const count = members.length; const count = members.length;
@ -432,6 +408,7 @@ const SpaceLanding = ({ space }) => {
}; };
return <div className="mx_SpaceRoomView_landing"> return <div className="mx_SpaceRoomView_landing">
<SpaceFeedbackPrompt />
<RoomAvatar room={space} height={80} width={80} viewAvatarOnClick={true} /> <RoomAvatar room={space} height={80} width={80} viewAvatarOnClick={true} />
<div className="mx_SpaceRoomView_landing_name"> <div className="mx_SpaceRoomView_landing_name">
<RoomName room={space}> <RoomName room={space}>
@ -456,8 +433,6 @@ const SpaceLanding = ({ space }) => {
</div> </div>
) } ) }
</RoomTopic> </RoomTopic>
<SpaceFeedbackPrompt />
<hr />
<SpaceHierarchy space={space} showRoom={showRoom} additionalButtons={addRoomButton} /> <SpaceHierarchy space={space} showRoom={showRoom} additionalButtons={addRoomButton} />
</div>; </div>;
@ -542,7 +517,6 @@ const SpaceSetupFirstRooms = ({ space, title, description, onFinished }) => {
value={buttonLabel} value={buttonLabel}
/> />
</div> </div>
<SpaceFeedbackPrompt />
</div>; </div>;
}; };
@ -567,7 +541,6 @@ const SpaceAddExistingRooms = ({ space, onFinished }) => {
spacesRenderer={defaultSpacesRenderer} spacesRenderer={defaultSpacesRenderer}
dmsRenderer={defaultDmsRenderer} dmsRenderer={defaultDmsRenderer}
/> />
<SpaceFeedbackPrompt />
</div>; </div>;
}; };
@ -587,7 +560,6 @@ const SpaceSetupPublicShare = ({ justCreatedOpts, space, onFinished, createdRoom
{ createdRooms ? _t("Go to my first room") : _t("Go to my space") } { createdRooms ? _t("Go to my first room") : _t("Go to my space") }
</AccessibleButton> </AccessibleButton>
</div> </div>
<SpaceFeedbackPrompt />
</div>; </div>;
}; };
@ -616,9 +588,8 @@ const SpaceSetupPrivateScope = ({ space, justCreatedOpts, onFinished }) => {
</AccessibleButton> </AccessibleButton>
<div className="mx_SpaceRoomView_betaWarning"> <div className="mx_SpaceRoomView_betaWarning">
<h3>{ _t("Teammates might not be able to view or join any private rooms you make.") }</h3> <h3>{ _t("Teammates might not be able to view or join any private rooms you make.") }</h3>
<p>{ _t("We're working on this as part of the beta, but just want to let you know.") }</p> <p>{ _t("We're working on this, but just want to let you know.") }</p>
</div> </div>
<SpaceFeedbackPrompt />
</div>; </div>;
}; };
@ -741,7 +712,6 @@ const SpaceSetupPrivateInvite = ({ space, onFinished }) => {
value={buttonLabel} value={buttonLabel}
/> />
</div> </div>
<SpaceFeedbackPrompt />
</div>; </div>;
}; };

View File

@ -27,6 +27,8 @@ import BetaFeedbackDialog from "../dialogs/BetaFeedbackDialog";
import SdkConfig from "../../../SdkConfig"; import SdkConfig from "../../../SdkConfig";
import SettingsFlag from "../elements/SettingsFlag"; import SettingsFlag from "../elements/SettingsFlag";
// XXX: Keep this around for re-use in future Betas
interface IProps { interface IProps {
title?: string; title?: string;
featureId: string; featureId: string;

View File

@ -21,7 +21,6 @@ import { _t } from '../../../languageHandler';
import BaseDialog from "./BaseDialog"; import BaseDialog from "./BaseDialog";
import AccessibleButton from "../elements/AccessibleButton"; import AccessibleButton from "../elements/AccessibleButton";
import MatrixClientContext from "../../../contexts/MatrixClientContext"; import MatrixClientContext from "../../../contexts/MatrixClientContext";
import { SpaceFeedbackPrompt } from "../../structures/SpaceRoomView";
import { AddExistingToSpace, defaultSpacesRenderer, SubspaceSelector } from "./AddExistingToSpaceDialog"; import { AddExistingToSpace, defaultSpacesRenderer, SubspaceSelector } from "./AddExistingToSpaceDialog";
interface IProps { interface IProps {
@ -61,8 +60,6 @@ const AddExistingSubspaceDialog: React.FC<IProps> = ({ space, onCreateSubspaceCl
spacesRenderer={defaultSpacesRenderer} spacesRenderer={defaultSpacesRenderer}
/> />
</MatrixClientContext.Provider> </MatrixClientContext.Provider>
<SpaceFeedbackPrompt onClick={() => onFinished(false)} />
</BaseDialog>; </BaseDialog>;
}; };

View File

@ -35,7 +35,6 @@ import StyledCheckbox from "../elements/StyledCheckbox";
import MatrixClientContext from "../../../contexts/MatrixClientContext"; import MatrixClientContext from "../../../contexts/MatrixClientContext";
import { sortRooms } from "../../../stores/room-list/algorithms/tag-sorting/RecentAlgorithm"; import { sortRooms } from "../../../stores/room-list/algorithms/tag-sorting/RecentAlgorithm";
import ProgressBar from "../elements/ProgressBar"; import ProgressBar from "../elements/ProgressBar";
import { SpaceFeedbackPrompt } from "../../structures/SpaceRoomView";
import DecoratedRoomAvatar from "../avatars/DecoratedRoomAvatar"; import DecoratedRoomAvatar from "../avatars/DecoratedRoomAvatar";
import QueryMatcher from "../../../autocomplete/QueryMatcher"; import QueryMatcher from "../../../autocomplete/QueryMatcher";
import TruncatedList from "../elements/TruncatedList"; import TruncatedList from "../elements/TruncatedList";
@ -446,8 +445,6 @@ const AddExistingToSpaceDialog: React.FC<IProps> = ({ space, onCreateRoomClick,
dmsRenderer={defaultDmsRenderer} dmsRenderer={defaultDmsRenderer}
/> />
</MatrixClientContext.Provider> </MatrixClientContext.Provider>
<SpaceFeedbackPrompt onClick={() => onFinished(false)} />
</BaseDialog>; </BaseDialog>;
}; };

View File

@ -14,22 +14,18 @@ See the License for the specific language governing permissions and
limitations under the License. limitations under the License.
*/ */
import React, { useState } from "react"; import React from "react";
import QuestionDialog from './QuestionDialog';
import { _t } from '../../../languageHandler'; import { _t } from '../../../languageHandler';
import Field from "../elements/Field";
import SdkConfig from "../../../SdkConfig";
import { IDialogProps } from "./IDialogProps"; import { IDialogProps } from "./IDialogProps";
import SettingsStore from "../../../settings/SettingsStore"; import SettingsStore from "../../../settings/SettingsStore";
import { submitFeedback } from "../../../rageshake/submit-rageshake";
import StyledCheckbox from "../elements/StyledCheckbox";
import Modal from "../../../Modal";
import InfoDialog from "./InfoDialog";
import AccessibleButton from "../elements/AccessibleButton"; import AccessibleButton from "../elements/AccessibleButton";
import defaultDispatcher from "../../../dispatcher/dispatcher"; import defaultDispatcher from "../../../dispatcher/dispatcher";
import { Action } from "../../../dispatcher/actions"; import { Action } from "../../../dispatcher/actions";
import { UserTab } from "./UserSettingsDialog"; import { UserTab } from "./UserSettingsDialog";
import GenericFeatureFeedbackDialog from "./GenericFeatureFeedbackDialog";
// XXX: Keep this around for re-use in future Betas
interface IProps extends IDialogProps { interface IProps extends IDialogProps {
featureId: string; featureId: string;
@ -38,77 +34,28 @@ interface IProps extends IDialogProps {
const BetaFeedbackDialog: React.FC<IProps> = ({ featureId, onFinished }) => { const BetaFeedbackDialog: React.FC<IProps> = ({ featureId, onFinished }) => {
const info = SettingsStore.getBetaInfo(featureId); const info = SettingsStore.getBetaInfo(featureId);
const [comment, setComment] = useState(""); return <GenericFeatureFeedbackDialog
const [canContact, setCanContact] = useState(false);
const sendFeedback = async (ok: boolean) => {
if (!ok) return onFinished(false);
const extraData = SettingsStore.getBetaInfo(featureId)?.extraSettings.reduce((o, k) => {
o[k] = SettingsStore.getValue(k);
return o;
}, {});
submitFeedback(SdkConfig.get().bug_report_endpoint_url, info.feedbackLabel, comment, canContact, extraData);
onFinished(true);
Modal.createTrackedDialog("Beta Dialog Sent", featureId, InfoDialog, {
title: _t("Beta feedback"),
description: _t("Thank you for your feedback, we really appreciate it."),
button: _t("Done"),
hasCloseButton: false,
fixedWidth: false,
});
};
return (<QuestionDialog
className="mx_BetaFeedbackDialog"
hasCancelButton={true}
title={_t("%(featureName)s beta feedback", { featureName: info.title })} title={_t("%(featureName)s beta feedback", { featureName: info.title })}
description={<React.Fragment> subheading={_t(info.feedbackSubheading)}
<div className="mx_BetaFeedbackDialog_subheading"> onFinished={onFinished}
{ _t(info.feedbackSubheading) } rageshakeLabel={info.feedbackLabel}
&nbsp; rageshakeData={Object.fromEntries((SettingsStore.getBetaInfo(featureId)?.extraSettings || []).map(k => {
{ _t("Your platform and username will be noted to help us use your feedback as much as we can.") } return SettingsStore.getValue(k);
}))}
<AccessibleButton >
kind="link" <AccessibleButton
onClick={() => { kind="link"
onFinished(false); onClick={() => {
defaultDispatcher.dispatch({ onFinished(false);
action: Action.ViewUserSettings, defaultDispatcher.dispatch({
initialTabId: UserTab.Labs, action: Action.ViewUserSettings,
}); initialTabId: UserTab.Labs,
}} });
> }}
{ _t("To leave the beta, visit your settings.") } >
</AccessibleButton> { _t("To leave the beta, visit your settings.") }
</div> </AccessibleButton>
</GenericFeatureFeedbackDialog>;
<Field
id="feedbackComment"
label={_t("Feedback")}
type="text"
autoComplete="off"
value={comment}
element="textarea"
onChange={(ev) => {
setComment(ev.target.value);
}}
autoFocus={true}
/>
<StyledCheckbox
checked={canContact}
onClick={e => setCanContact((e.target as HTMLInputElement).checked)}
>
{ _t("You may contact me if you have any follow up questions") }
</StyledCheckbox>
</React.Fragment>}
button={_t("Send feedback")}
buttonDisabled={!comment}
onFinished={sendFeedback}
/>);
}; };
export default BetaFeedbackDialog; export default BetaFeedbackDialog;

View File

@ -0,0 +1,101 @@
/*
Copyright 2021 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 React, { useState } from "react";
import QuestionDialog from './QuestionDialog';
import { _t } from '../../../languageHandler';
import Field from "../elements/Field";
import SdkConfig from "../../../SdkConfig";
import { IDialogProps } from "./IDialogProps";
import { submitFeedback } from "../../../rageshake/submit-rageshake";
import StyledCheckbox from "../elements/StyledCheckbox";
import Modal from "../../../Modal";
import InfoDialog from "./InfoDialog";
interface IProps extends IDialogProps {
title: string;
subheading: string;
rageshakeLabel: string;
rageshakeData?: Record<string, string>;
}
const GenericFeatureFeedbackDialog: React.FC<IProps> = ({
title,
subheading,
children,
rageshakeLabel,
rageshakeData = {},
onFinished,
}) => {
const [comment, setComment] = useState("");
const [canContact, setCanContact] = useState(false);
const sendFeedback = async (ok: boolean) => {
if (!ok) return onFinished(false);
submitFeedback(SdkConfig.get().bug_report_endpoint_url, rageshakeLabel, comment, canContact, rageshakeData);
onFinished(true);
Modal.createTrackedDialog("Feedback Sent", rageshakeLabel, InfoDialog, {
title,
description: _t("Thank you for your feedback, we really appreciate it."),
button: _t("Done"),
hasCloseButton: false,
fixedWidth: false,
});
};
return (<QuestionDialog
className="mx_GenericFeatureFeedbackDialog"
hasCancelButton={true}
title={title}
description={<React.Fragment>
<div className="mx_GenericFeatureFeedbackDialog_subheading">
{ subheading }
&nbsp;
{ _t("Your platform and username will be noted to help us use your feedback as much as we can.") }
{ children }
</div>
<Field
id="feedbackComment"
label={_t("Feedback")}
type="text"
autoComplete="off"
value={comment}
element="textarea"
onChange={(ev) => {
setComment(ev.target.value);
}}
autoFocus={true}
/>
<StyledCheckbox
checked={canContact}
onChange={e => setCanContact((e.target as HTMLInputElement).checked)}
>
{ _t("You may contact me if you have any follow up questions") }
</StyledCheckbox>
</React.Fragment>}
button={_t("Send feedback")}
buttonDisabled={!comment}
onFinished={sendFeedback}
/>);
};
export default GenericFeatureFeedbackDialog;

View File

@ -26,15 +26,14 @@ import createRoom from "../../../createRoom";
import MatrixClientContext from "../../../contexts/MatrixClientContext"; import MatrixClientContext from "../../../contexts/MatrixClientContext";
import SpaceBasicSettings, { SpaceAvatar } from "./SpaceBasicSettings"; import SpaceBasicSettings, { SpaceAvatar } from "./SpaceBasicSettings";
import AccessibleButton from "../elements/AccessibleButton"; import AccessibleButton from "../elements/AccessibleButton";
import { BetaPill } from "../beta/BetaCard";
import defaultDispatcher from "../../../dispatcher/dispatcher";
import { Action } from "../../../dispatcher/actions";
import { UserTab } from "../dialogs/UserSettingsDialog";
import Field from "../elements/Field"; import Field from "../elements/Field";
import withValidation from "../elements/Validation"; import withValidation from "../elements/Validation";
import { SpaceFeedbackPrompt } from "../../structures/SpaceRoomView";
import { HistoryVisibility, Preset } from "matrix-js-sdk/src/@types/partials"; import { HistoryVisibility, Preset } from "matrix-js-sdk/src/@types/partials";
import RoomAliasField from "../elements/RoomAliasField"; import RoomAliasField from "../elements/RoomAliasField";
import SdkConfig from "../../../SdkConfig";
import Modal from "../../../Modal";
import GenericFeatureFeedbackDialog from "../dialogs/GenericFeatureFeedbackDialog";
import SettingsStore from "../../../settings/SettingsStore";
const SpaceCreateMenuType = ({ title, description, className, onClick }) => { const SpaceCreateMenuType = ({ title, description, className, onClick }) => {
return ( return (
@ -65,6 +64,34 @@ const nameToAlias = (name: string, domain: string): string => {
return `#${localpart}:${domain}`; return `#${localpart}:${domain}`;
}; };
// XXX: Temporary for the Spaces release only
export const SpaceFeedbackPrompt = ({ onClick }: { onClick?: () => void }) => {
if (!SdkConfig.get().bug_report_endpoint_url) return null;
return <div className="mx_SpaceFeedbackPrompt">
<span className="mx_SpaceFeedbackPrompt_text">{ _t("Spaces are a new feature.") }</span>
<AccessibleButton
kind="link"
onClick={() => {
if (onClick) onClick();
Modal.createTrackedDialog("Spaces Feedback", "", GenericFeatureFeedbackDialog, {
title: _t("Spaces feedback"),
subheading: _t("Thank you for trying Spaces. " +
"Your feedback will help inform the next versions."),
rageshakeLabel: "spaces-feedback",
rageshakeData: Object.fromEntries([
"feature_spaces.all_rooms",
"feature_spaces.space_member_dms",
"feature_spaces.space_dm_badges",
].map(k => [k, SettingsStore.getValue(k)])),
});
}}
>
{ _t("Give feedback.") }
</AccessibleButton>
</div>;
};
type BProps = Pick<ComponentProps<typeof SpaceBasicSettings>, "setAvatar" | "name" | "setName" | "topic" | "setTopic">; type BProps = Pick<ComponentProps<typeof SpaceBasicSettings>, "setAvatar" | "name" | "setName" | "topic" | "setTopic">;
interface ISpaceCreateFormProps extends BProps { interface ISpaceCreateFormProps extends BProps {
busy: boolean; busy: boolean;
@ -280,13 +307,6 @@ const SpaceCreateMenu = ({ onFinished }) => {
managed={false} managed={false}
> >
<FocusLock returnFocus={true}> <FocusLock returnFocus={true}>
<BetaPill onClick={() => {
onFinished();
defaultDispatcher.dispatch({
action: Action.ViewUserSettings,
initialTabId: UserTab.Labs,
});
}} />
{ body } { body }
</FocusLock> </FocusLock>
</ContextMenu>; </ContextMenu>;

View File

@ -21,7 +21,6 @@ import { EventType } from "matrix-js-sdk/src/@types/event";
import { _t } from "../../../languageHandler"; import { _t } from "../../../languageHandler";
import AccessibleButton from "../elements/AccessibleButton"; import AccessibleButton from "../elements/AccessibleButton";
import { SpaceFeedbackPrompt } from "../../structures/SpaceRoomView";
import SpaceBasicSettings from "./SpaceBasicSettings"; import SpaceBasicSettings from "./SpaceBasicSettings";
import { avatarUrlForRoom } from "../../../Avatar"; import { avatarUrlForRoom } from "../../../Avatar";
import { IDialogProps } from "../dialogs/IDialogProps"; import { IDialogProps } from "../dialogs/IDialogProps";
@ -96,8 +95,6 @@ const SpaceSettingsGeneralTab = ({ matrixClient: cli, space, onFinished }: IProp
{ error && <div className="mx_SpaceRoomView_errorText">{ error }</div> } { error && <div className="mx_SpaceRoomView_errorText">{ error }</div> }
<SpaceFeedbackPrompt />
<div className="mx_SettingsTab_section"> <div className="mx_SettingsTab_section">
<SpaceBasicSettings <SpaceBasicSettings
avatarUrl={avatarUrlForRoom(space, 80, 80, "crop")} avatarUrl={avatarUrlForRoom(space, 80, 80, "crop")}

View File

@ -1005,6 +1005,10 @@
"Name": "Name", "Name": "Name",
"Description": "Description", "Description": "Description",
"Please enter a name for the space": "Please enter a name for the space", "Please enter a name for the space": "Please enter a name for the space",
"Spaces are a new feature.": "Spaces are a new feature.",
"Spaces feedback": "Spaces feedback",
"Thank you for trying Spaces. Your feedback will help inform the next versions.": "Thank you for trying Spaces. Your feedback will help inform the next versions.",
"Give feedback.": "Give feedback.",
"e.g. my-space": "e.g. my-space", "e.g. my-space": "e.g. my-space",
"Address": "Address", "Address": "Address",
"Create a space": "Create a space", "Create a space": "Create a space",
@ -2138,15 +2142,8 @@
"Invite anyway and never warn me again": "Invite anyway and never warn me again", "Invite anyway and never warn me again": "Invite anyway and never warn me again",
"Invite anyway": "Invite anyway", "Invite anyway": "Invite anyway",
"Close dialog": "Close dialog", "Close dialog": "Close dialog",
"Beta feedback": "Beta feedback",
"Thank you for your feedback, we really appreciate it.": "Thank you for your feedback, we really appreciate it.",
"Done": "Done",
"%(featureName)s beta feedback": "%(featureName)s beta feedback", "%(featureName)s beta feedback": "%(featureName)s beta feedback",
"Your platform and username will be noted to help us use your feedback as much as we can.": "Your platform and username will be noted to help us use your feedback as much as we can.",
"To leave the beta, visit your settings.": "To leave the beta, visit your settings.", "To leave the beta, visit your settings.": "To leave the beta, visit your settings.",
"Feedback": "Feedback",
"You may contact me if you have any follow up questions": "You may contact me if you have any follow up questions",
"Send feedback": "Send feedback",
"Please tell us what went wrong or, better, create a GitHub issue that describes the problem.": "Please tell us what went wrong or, better, create a GitHub issue that describes the problem.", "Please tell us what went wrong or, better, create a GitHub issue that describes the problem.": "Please tell us what went wrong or, better, create a GitHub issue that describes the problem.",
"Preparing to send logs": "Preparing to send logs", "Preparing to send logs": "Preparing to send logs",
"Logs sent": "Logs sent", "Logs sent": "Logs sent",
@ -2293,8 +2290,10 @@
"Comment": "Comment", "Comment": "Comment",
"There are two ways you can provide feedback and help us improve %(brand)s.": "There are two ways you can provide feedback and help us improve %(brand)s.", "There are two ways you can provide feedback and help us improve %(brand)s.": "There are two ways you can provide feedback and help us improve %(brand)s.",
"PRO TIP: If you start a bug, please submit <debugLogsLink>debug logs</debugLogsLink> to help us track down the problem.": "PRO TIP: If you start a bug, please submit <debugLogsLink>debug logs</debugLogsLink> to help us track down the problem.", "PRO TIP: If you start a bug, please submit <debugLogsLink>debug logs</debugLogsLink> to help us track down the problem.": "PRO TIP: If you start a bug, please submit <debugLogsLink>debug logs</debugLogsLink> to help us track down the problem.",
"Feedback": "Feedback",
"Report a bug": "Report a bug", "Report a bug": "Report a bug",
"Please view <existingIssuesLink>existing bugs on Github</existingIssuesLink> first. No match? <newIssueLink>Start a new one</newIssueLink>.": "Please view <existingIssuesLink>existing bugs on Github</existingIssuesLink> first. No match? <newIssueLink>Start a new one</newIssueLink>.", "Please view <existingIssuesLink>existing bugs on Github</existingIssuesLink> first. No match? <newIssueLink>Start a new one</newIssueLink>.": "Please view <existingIssuesLink>existing bugs on Github</existingIssuesLink> first. No match? <newIssueLink>Start a new one</newIssueLink>.",
"Send feedback": "Send feedback",
"You don't have permission to do this": "You don't have permission to do this", "You don't have permission to do this": "You don't have permission to do this",
"Sending": "Sending", "Sending": "Sending",
"Sent": "Sent", "Sent": "Sent",
@ -2302,6 +2301,10 @@
"Forward message": "Forward message", "Forward message": "Forward message",
"Message preview": "Message preview", "Message preview": "Message preview",
"Search for rooms or people": "Search for rooms or people", "Search for rooms or people": "Search for rooms or people",
"Thank you for your feedback, we really appreciate it.": "Thank you for your feedback, we really appreciate it.",
"Done": "Done",
"Your platform and username will be noted to help us use your feedback as much as we can.": "Your platform and username will be noted to help us use your feedback as much as we can.",
"You may contact me if you have any follow up questions": "You may contact me if you have any follow up questions",
"Confirm abort of host creation": "Confirm abort of host creation", "Confirm abort of host creation": "Confirm abort of host creation",
"Are you sure you wish to abort creation of the host? The process cannot be continued.": "Are you sure you wish to abort creation of the host? The process cannot be continued.", "Are you sure you wish to abort creation of the host? The process cannot be continued.": "Are you sure you wish to abort creation of the host? The process cannot be continued.",
"Abort": "Abort", "Abort": "Abort",
@ -2813,7 +2816,6 @@
"Search names and descriptions": "Search names and descriptions", "Search names and descriptions": "Search names and descriptions",
"If you can't find the room you're looking for, ask for an invite or <a>create a new room</a>.": "If you can't find the room you're looking for, ask for an invite or <a>create a new room</a>.", "If you can't find the room you're looking for, ask for an invite or <a>create a new room</a>.": "If you can't find the room you're looking for, ask for an invite or <a>create a new room</a>.",
"Create room": "Create room", "Create room": "Create room",
"Spaces are a beta feature.": "Spaces are a beta feature.",
"Private space": "Private space", "Private space": "Private space",
"<inviter/> invites you": "<inviter/> invites you", "<inviter/> invites you": "<inviter/> invites you",
"To view %(spaceName)s, turn on the <a>Spaces beta</a>": "To view %(spaceName)s, turn on the <a>Spaces beta</a>", "To view %(spaceName)s, turn on the <a>Spaces beta</a>": "To view %(spaceName)s, turn on the <a>Spaces beta</a>",
@ -2840,7 +2842,7 @@
"Me and my teammates": "Me and my teammates", "Me and my teammates": "Me and my teammates",
"A private space for you and your teammates": "A private space for you and your teammates", "A private space for you and your teammates": "A private space for you and your teammates",
"Teammates might not be able to view or join any private rooms you make.": "Teammates might not be able to view or join any private rooms you make.", "Teammates might not be able to view or join any private rooms you make.": "Teammates might not be able to view or join any private rooms you make.",
"We're working on this as part of the beta, but just want to let you know.": "We're working on this as part of the beta, but just want to let you know.", "We're working on this, but just want to let you know.": "We're working on this, but just want to let you know.",
"Failed to invite the following users to your space: %(csvUsers)s": "Failed to invite the following users to your space: %(csvUsers)s", "Failed to invite the following users to your space: %(csvUsers)s": "Failed to invite the following users to your space: %(csvUsers)s",
"Inviting...": "Inviting...", "Inviting...": "Inviting...",
"Invite your teammates": "Invite your teammates", "Invite your teammates": "Invite your teammates",

View File

@ -124,6 +124,7 @@ export interface ISetting {
// not use this for new settings. // not use this for new settings.
invertedSettingName?: string; invertedSettingName?: string;
// XXX: Keep this around for re-use in future Betas
betaInfo?: { betaInfo?: {
title: string; // _td title: string; // _td
caption: string; // _td caption: string; // _td

View File

@ -141,21 +141,3 @@ export function objectKeyChanges<O extends {}>(a: O, b: O): (keyof O)[] {
export function objectClone<O extends {}>(obj: O): O { export function objectClone<O extends {}>(obj: O): O {
return JSON.parse(JSON.stringify(obj)); return JSON.parse(JSON.stringify(obj));
} }
/**
* Converts a series of entries to an object.
* @param entries The entries to convert.
* @returns The converted object.
*/
// NOTE: Deprecated once we have Object.fromEntries() support.
// @ts-ignore - return type is complaining about non-string keys, but we know better
export function objectFromEntries<K, V>(entries: Iterable<[K, V]>): {[k: K]: V} {
const obj: {
// @ts-ignore - same as return type
[k: K]: V;} = {};
for (const e of entries) {
// @ts-ignore - same as return type
obj[e[0]] = e[1];
}
return obj;
}

View File

@ -29,7 +29,6 @@ import {
ArrayUtil, ArrayUtil,
GroupedArray, GroupedArray,
} from "../../src/utils/arrays"; } from "../../src/utils/arrays";
import { objectFromEntries } from "../../src/utils/objects";
function expectSample(i: number, input: number[], expected: number[], smooth = false) { function expectSample(i: number, input: number[], expected: number[], smooth = false) {
console.log(`Resample case index: ${i}`); // for debugging test failures console.log(`Resample case index: ${i}`); // for debugging test failures
@ -336,7 +335,7 @@ describe('arrays', () => {
expect(result).toBeDefined(); expect(result).toBeDefined();
expect(result.value).toBeDefined(); expect(result.value).toBeDefined();
const asObject = objectFromEntries(result.value.entries()); const asObject = Object.fromEntries(result.value.entries());
expect(asObject).toMatchObject(output); expect(asObject).toMatchObject(output);
}); });
}); });

View File

@ -18,7 +18,6 @@ import {
objectClone, objectClone,
objectDiff, objectDiff,
objectExcluding, objectExcluding,
objectFromEntries,
objectHasDiff, objectHasDiff,
objectKeyChanges, objectKeyChanges,
objectShallowClone, objectShallowClone,
@ -242,21 +241,4 @@ describe('objects', () => {
expect(result.test.third).not.toBe(a.test.third); expect(result.test.third).not.toBe(a.test.third);
}); });
}); });
describe('objectFromEntries', () => {
it('should create an object from an array of entries', () => {
const output = { a: 1, b: 2, c: 3 };
const result = objectFromEntries(Object.entries(output));
expect(result).toBeDefined();
expect(result).toMatchObject(output);
});
it('should maintain pointers in values', () => {
const output = { a: {}, b: 2, c: 3 };
const result = objectFromEntries(Object.entries(output));
expect(result).toBeDefined();
expect(result).toMatchObject(output);
expect(result['a']).toBe(output.a);
});
});
}); });