mirror of https://github.com/vector-im/riot-web
				
				
				
			Merge pull request #6466 from matrix-org/t3chguy/fix/18096
						commit
						d587ae44af
					
				|  | @ -67,7 +67,6 @@ | |||
| @import "./views/dialogs/_AddExistingToSpaceDialog.scss"; | ||||
| @import "./views/dialogs/_AddressPickerDialog.scss"; | ||||
| @import "./views/dialogs/_Analytics.scss"; | ||||
| @import "./views/dialogs/_BetaFeedbackDialog.scss"; | ||||
| @import "./views/dialogs/_BugReportDialog.scss"; | ||||
| @import "./views/dialogs/_ChangelogDialog.scss"; | ||||
| @import "./views/dialogs/_ChatCreateOrReuseChatDialog.scss"; | ||||
|  | @ -82,6 +81,7 @@ | |||
| @import "./views/dialogs/_EditCommunityPrototypeDialog.scss"; | ||||
| @import "./views/dialogs/_FeedbackDialog.scss"; | ||||
| @import "./views/dialogs/_ForwardDialog.scss"; | ||||
| @import "./views/dialogs/_GenericFeatureFeedbackDialog.scss"; | ||||
| @import "./views/dialogs/_GroupAddressPicker.scss"; | ||||
| @import "./views/dialogs/_HostSignupDialog.scss"; | ||||
| @import "./views/dialogs/_IncomingSasDialog.scss"; | ||||
|  |  | |||
|  | @ -61,6 +61,7 @@ limitations under the License. | |||
| 
 | ||||
|     .mx_AccessibleButton_kind_link { | ||||
|         padding: 0; | ||||
|         font-size: inherit; | ||||
|     } | ||||
| 
 | ||||
|     .mx_SearchBox { | ||||
|  |  | |||
|  | @ -335,24 +335,17 @@ $SpaceRoomViewInnerWidth: 428px; | |||
|             word-wrap: break-word; | ||||
|         } | ||||
| 
 | ||||
|         > hr { | ||||
|             border: none; | ||||
|             height: 1px; | ||||
|             background-color: $groupFilterPanel-bg-color; | ||||
|         } | ||||
| 
 | ||||
|         .mx_SearchBox { | ||||
|             margin: 0 0 20px; | ||||
|             flex: 0; | ||||
|         } | ||||
| 
 | ||||
|         .mx_SpaceFeedbackPrompt { | ||||
|             margin-bottom: 16px; | ||||
| 
 | ||||
|             // hide the HR as we have our own | ||||
|             & + hr { | ||||
|                 display: none; | ||||
|             } | ||||
|             padding: 7px; // 8px - 1px border | ||||
|             border: 1px solid $menu-border-color; | ||||
|             border-radius: 8px; | ||||
|             width: max-content; | ||||
|             margin: 0 0 -40px auto; // collapse its own height to not push other components down | ||||
|         } | ||||
| 
 | ||||
|         .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; | ||||
|             } | ||||
|         } | ||||
|     } | ||||
| } | ||||
|  |  | |||
|  | @ -14,8 +14,8 @@ See the License for the specific language governing permissions and | |||
| limitations under the License. | ||||
| */ | ||||
| 
 | ||||
| .mx_BetaFeedbackDialog { | ||||
|     .mx_BetaFeedbackDialog_subheading { | ||||
| .mx_GenericFeatureFeedbackDialog { | ||||
|     .mx_GenericFeatureFeedbackDialog_subheading { | ||||
|         color: $primary-fg-color; | ||||
|         font-size: $font-14px; | ||||
|         line-height: $font-20px; | ||||
|  | @ -43,6 +43,12 @@ $spacePanelWidth: 71px; | |||
|                 color: $secondary-fg-color; | ||||
|                 margin: 0; | ||||
|             } | ||||
| 
 | ||||
|             .mx_SpaceFeedbackPrompt { | ||||
|                 border-top: 1px solid $input-border-color; | ||||
|                 padding-top: 12px; | ||||
|                 margin-top: 16px; | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
|         // 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; | ||||
|     } | ||||
| } | ||||
|  |  | |||
|  | @ -72,10 +72,8 @@ import IconizedContextMenu, { | |||
| import AccessibleTooltipButton from "../views/elements/AccessibleTooltipButton"; | ||||
| import { BetaPill } from "../views/beta/BetaCard"; | ||||
| 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 { SpaceFeedbackPrompt } from "../views/spaces/SpaceCreateMenu"; | ||||
| 
 | ||||
| interface IProps { | ||||
|     space: Room; | ||||
|  | @ -102,28 +100,6 @@ enum Phase { | |||
|     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 members = useRoomMembers(room); | ||||
|     const count = members.length; | ||||
|  | @ -432,6 +408,7 @@ const SpaceLanding = ({ space }) => { | |||
|     }; | ||||
| 
 | ||||
|     return <div className="mx_SpaceRoomView_landing"> | ||||
|         <SpaceFeedbackPrompt /> | ||||
|         <RoomAvatar room={space} height={80} width={80} viewAvatarOnClick={true} /> | ||||
|         <div className="mx_SpaceRoomView_landing_name"> | ||||
|             <RoomName room={space}> | ||||
|  | @ -456,8 +433,6 @@ const SpaceLanding = ({ space }) => { | |||
|                 </div> | ||||
|             ) } | ||||
|         </RoomTopic> | ||||
|         <SpaceFeedbackPrompt /> | ||||
|         <hr /> | ||||
| 
 | ||||
|         <SpaceHierarchy space={space} showRoom={showRoom} additionalButtons={addRoomButton} /> | ||||
|     </div>; | ||||
|  | @ -542,7 +517,6 @@ const SpaceSetupFirstRooms = ({ space, title, description, onFinished }) => { | |||
|                 value={buttonLabel} | ||||
|             /> | ||||
|         </div> | ||||
|         <SpaceFeedbackPrompt /> | ||||
|     </div>; | ||||
| }; | ||||
| 
 | ||||
|  | @ -567,7 +541,6 @@ const SpaceAddExistingRooms = ({ space, onFinished }) => { | |||
|             spacesRenderer={defaultSpacesRenderer} | ||||
|             dmsRenderer={defaultDmsRenderer} | ||||
|         /> | ||||
|         <SpaceFeedbackPrompt /> | ||||
|     </div>; | ||||
| }; | ||||
| 
 | ||||
|  | @ -587,7 +560,6 @@ const SpaceSetupPublicShare = ({ justCreatedOpts, space, onFinished, createdRoom | |||
|                 { createdRooms ? _t("Go to my first room") : _t("Go to my space") } | ||||
|             </AccessibleButton> | ||||
|         </div> | ||||
|         <SpaceFeedbackPrompt /> | ||||
|     </div>; | ||||
| }; | ||||
| 
 | ||||
|  | @ -616,9 +588,8 @@ const SpaceSetupPrivateScope = ({ space, justCreatedOpts, onFinished }) => { | |||
|         </AccessibleButton> | ||||
|         <div className="mx_SpaceRoomView_betaWarning"> | ||||
|             <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> | ||||
|         <SpaceFeedbackPrompt /> | ||||
|     </div>; | ||||
| }; | ||||
| 
 | ||||
|  | @ -741,7 +712,6 @@ const SpaceSetupPrivateInvite = ({ space, onFinished }) => { | |||
|                 value={buttonLabel} | ||||
|             /> | ||||
|         </div> | ||||
|         <SpaceFeedbackPrompt /> | ||||
|     </div>; | ||||
| }; | ||||
| 
 | ||||
|  |  | |||
|  | @ -27,6 +27,8 @@ import BetaFeedbackDialog from "../dialogs/BetaFeedbackDialog"; | |||
| import SdkConfig from "../../../SdkConfig"; | ||||
| import SettingsFlag from "../elements/SettingsFlag"; | ||||
| 
 | ||||
| // XXX: Keep this around for re-use in future Betas
 | ||||
| 
 | ||||
| interface IProps { | ||||
|     title?: string; | ||||
|     featureId: string; | ||||
|  |  | |||
|  | @ -21,7 +21,6 @@ import { _t } from '../../../languageHandler'; | |||
| import BaseDialog from "./BaseDialog"; | ||||
| import AccessibleButton from "../elements/AccessibleButton"; | ||||
| import MatrixClientContext from "../../../contexts/MatrixClientContext"; | ||||
| import { SpaceFeedbackPrompt } from "../../structures/SpaceRoomView"; | ||||
| import { AddExistingToSpace, defaultSpacesRenderer, SubspaceSelector } from "./AddExistingToSpaceDialog"; | ||||
| 
 | ||||
| interface IProps { | ||||
|  | @ -61,8 +60,6 @@ const AddExistingSubspaceDialog: React.FC<IProps> = ({ space, onCreateSubspaceCl | |||
|                 spacesRenderer={defaultSpacesRenderer} | ||||
|             /> | ||||
|         </MatrixClientContext.Provider> | ||||
| 
 | ||||
|         <SpaceFeedbackPrompt onClick={() => onFinished(false)} /> | ||||
|     </BaseDialog>; | ||||
| }; | ||||
| 
 | ||||
|  |  | |||
|  | @ -35,7 +35,6 @@ import StyledCheckbox from "../elements/StyledCheckbox"; | |||
| import MatrixClientContext from "../../../contexts/MatrixClientContext"; | ||||
| import { sortRooms } from "../../../stores/room-list/algorithms/tag-sorting/RecentAlgorithm"; | ||||
| import ProgressBar from "../elements/ProgressBar"; | ||||
| import { SpaceFeedbackPrompt } from "../../structures/SpaceRoomView"; | ||||
| import DecoratedRoomAvatar from "../avatars/DecoratedRoomAvatar"; | ||||
| import QueryMatcher from "../../../autocomplete/QueryMatcher"; | ||||
| import TruncatedList from "../elements/TruncatedList"; | ||||
|  | @ -446,8 +445,6 @@ const AddExistingToSpaceDialog: React.FC<IProps> = ({ space, onCreateRoomClick, | |||
|                 dmsRenderer={defaultDmsRenderer} | ||||
|             /> | ||||
|         </MatrixClientContext.Provider> | ||||
| 
 | ||||
|         <SpaceFeedbackPrompt onClick={() => onFinished(false)} /> | ||||
|     </BaseDialog>; | ||||
| }; | ||||
| 
 | ||||
|  |  | |||
|  | @ -14,22 +14,18 @@ See the License for the specific language governing permissions and | |||
| limitations under the License. | ||||
| */ | ||||
| 
 | ||||
| import React, { useState } from "react"; | ||||
| import React from "react"; | ||||
| 
 | ||||
| import QuestionDialog from './QuestionDialog'; | ||||
| import { _t } from '../../../languageHandler'; | ||||
| import Field from "../elements/Field"; | ||||
| import SdkConfig from "../../../SdkConfig"; | ||||
| import { IDialogProps } from "./IDialogProps"; | ||||
| 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 defaultDispatcher from "../../../dispatcher/dispatcher"; | ||||
| import { Action } from "../../../dispatcher/actions"; | ||||
| import { UserTab } from "./UserSettingsDialog"; | ||||
| import GenericFeatureFeedbackDialog from "./GenericFeatureFeedbackDialog"; | ||||
| 
 | ||||
| // XXX: Keep this around for re-use in future Betas
 | ||||
| 
 | ||||
| interface IProps extends IDialogProps { | ||||
|     featureId: string; | ||||
|  | @ -38,77 +34,28 @@ interface IProps extends IDialogProps { | |||
| const BetaFeedbackDialog: React.FC<IProps> = ({ featureId, onFinished }) => { | ||||
|     const info = SettingsStore.getBetaInfo(featureId); | ||||
| 
 | ||||
|     const [comment, setComment] = useState(""); | ||||
|     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} | ||||
|     return <GenericFeatureFeedbackDialog | ||||
|         title={_t("%(featureName)s beta feedback", { featureName: info.title })} | ||||
|         description={<React.Fragment> | ||||
|             <div className="mx_BetaFeedbackDialog_subheading"> | ||||
|                 { _t(info.feedbackSubheading) } | ||||
|                   | ||||
|                 { _t("Your platform and username will be noted to help us use your feedback as much as we can.") } | ||||
| 
 | ||||
|                 <AccessibleButton | ||||
|                     kind="link" | ||||
|                     onClick={() => { | ||||
|                         onFinished(false); | ||||
|                         defaultDispatcher.dispatch({ | ||||
|                         action: Action.ViewUserSettings, | ||||
|                         initialTabId: UserTab.Labs, | ||||
|                         }); | ||||
|                     }} | ||||
|                 > | ||||
|                     { _t("To leave the beta, visit your settings.") } | ||||
|                 </AccessibleButton> | ||||
|             </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} | ||||
|                 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} | ||||
|     />); | ||||
|         subheading={_t(info.feedbackSubheading)} | ||||
|         onFinished={onFinished} | ||||
|         rageshakeLabel={info.feedbackLabel} | ||||
|         rageshakeData={Object.fromEntries((SettingsStore.getBetaInfo(featureId)?.extraSettings || []).map(k => { | ||||
|             return SettingsStore.getValue(k); | ||||
|         }))} | ||||
|     > | ||||
|         <AccessibleButton | ||||
|             kind="link" | ||||
|             onClick={() => { | ||||
|                 onFinished(false); | ||||
|                 defaultDispatcher.dispatch({ | ||||
|                     action: Action.ViewUserSettings, | ||||
|                     initialTabId: UserTab.Labs, | ||||
|                 }); | ||||
|             }} | ||||
|         > | ||||
|             { _t("To leave the beta, visit your settings.") } | ||||
|         </AccessibleButton> | ||||
|     </GenericFeatureFeedbackDialog>; | ||||
| }; | ||||
| 
 | ||||
| export default BetaFeedbackDialog; | ||||
|  |  | |||
|  | @ -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 } | ||||
|                   | ||||
|                 { _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; | ||||
|  | @ -26,15 +26,14 @@ import createRoom from "../../../createRoom"; | |||
| import MatrixClientContext from "../../../contexts/MatrixClientContext"; | ||||
| import SpaceBasicSettings, { SpaceAvatar } from "./SpaceBasicSettings"; | ||||
| 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 withValidation from "../elements/Validation"; | ||||
| import { SpaceFeedbackPrompt } from "../../structures/SpaceRoomView"; | ||||
| import { HistoryVisibility, Preset } from "matrix-js-sdk/src/@types/partials"; | ||||
| 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 }) => { | ||||
|     return ( | ||||
|  | @ -65,6 +64,34 @@ const nameToAlias = (name: string, domain: string): string => { | |||
|     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">; | ||||
| interface ISpaceCreateFormProps extends BProps { | ||||
|     busy: boolean; | ||||
|  | @ -280,13 +307,6 @@ const SpaceCreateMenu = ({ onFinished }) => { | |||
|         managed={false} | ||||
|     > | ||||
|         <FocusLock returnFocus={true}> | ||||
|             <BetaPill onClick={() => { | ||||
|                 onFinished(); | ||||
|                 defaultDispatcher.dispatch({ | ||||
|                     action: Action.ViewUserSettings, | ||||
|                     initialTabId: UserTab.Labs, | ||||
|                 }); | ||||
|             }} /> | ||||
|             { body } | ||||
|         </FocusLock> | ||||
|     </ContextMenu>; | ||||
|  |  | |||
|  | @ -21,7 +21,6 @@ import { EventType } from "matrix-js-sdk/src/@types/event"; | |||
| 
 | ||||
| import { _t } from "../../../languageHandler"; | ||||
| import AccessibleButton from "../elements/AccessibleButton"; | ||||
| import { SpaceFeedbackPrompt } from "../../structures/SpaceRoomView"; | ||||
| import SpaceBasicSettings from "./SpaceBasicSettings"; | ||||
| import { avatarUrlForRoom } from "../../../Avatar"; | ||||
| import { IDialogProps } from "../dialogs/IDialogProps"; | ||||
|  | @ -96,8 +95,6 @@ const SpaceSettingsGeneralTab = ({ matrixClient: cli, space, onFinished }: IProp | |||
| 
 | ||||
|         { error && <div className="mx_SpaceRoomView_errorText">{ error }</div> } | ||||
| 
 | ||||
|         <SpaceFeedbackPrompt /> | ||||
| 
 | ||||
|         <div className="mx_SettingsTab_section"> | ||||
|             <SpaceBasicSettings | ||||
|                 avatarUrl={avatarUrlForRoom(space, 80, 80, "crop")} | ||||
|  |  | |||
|  | @ -1005,6 +1005,10 @@ | |||
|     "Name": "Name", | ||||
|     "Description": "Description", | ||||
|     "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", | ||||
|     "Address": "Address", | ||||
|     "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": "Invite anyway", | ||||
|     "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", | ||||
|     "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.", | ||||
|     "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.", | ||||
|     "Preparing to send logs": "Preparing to send logs", | ||||
|     "Logs sent": "Logs sent", | ||||
|  | @ -2293,8 +2290,10 @@ | |||
|     "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.", | ||||
|     "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", | ||||
|     "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", | ||||
|     "Sending": "Sending", | ||||
|     "Sent": "Sent", | ||||
|  | @ -2302,6 +2301,10 @@ | |||
|     "Forward message": "Forward message", | ||||
|     "Message preview": "Message preview", | ||||
|     "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", | ||||
|     "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", | ||||
|  | @ -2813,7 +2816,6 @@ | |||
|     "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>.", | ||||
|     "Create room": "Create room", | ||||
|     "Spaces are a beta feature.": "Spaces are a beta feature.", | ||||
|     "Private space": "Private space", | ||||
|     "<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>", | ||||
|  | @ -2840,7 +2842,7 @@ | |||
|     "Me and my teammates": "Me and my 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.", | ||||
|     "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", | ||||
|     "Inviting...": "Inviting...", | ||||
|     "Invite your teammates": "Invite your teammates", | ||||
|  |  | |||
|  | @ -124,6 +124,7 @@ export interface ISetting { | |||
|     // not use this for new settings.
 | ||||
|     invertedSettingName?: string; | ||||
| 
 | ||||
|     // XXX: Keep this around for re-use in future Betas
 | ||||
|     betaInfo?: { | ||||
|         title: string; // _td
 | ||||
|         caption: string; // _td
 | ||||
|  |  | |||
|  | @ -141,21 +141,3 @@ export function objectKeyChanges<O extends {}>(a: O, b: O): (keyof O)[] { | |||
| export function objectClone<O extends {}>(obj: O): O { | ||||
|     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; | ||||
| } | ||||
|  |  | |||
|  | @ -29,7 +29,6 @@ import { | |||
|     ArrayUtil, | ||||
|     GroupedArray, | ||||
| } from "../../src/utils/arrays"; | ||||
| import { objectFromEntries } from "../../src/utils/objects"; | ||||
| 
 | ||||
| function expectSample(i: number, input: number[], expected: number[], smooth = false) { | ||||
|     console.log(`Resample case index: ${i}`); // for debugging test failures
 | ||||
|  | @ -336,7 +335,7 @@ describe('arrays', () => { | |||
|             expect(result).toBeDefined(); | ||||
|             expect(result.value).toBeDefined(); | ||||
| 
 | ||||
|             const asObject = objectFromEntries(result.value.entries()); | ||||
|             const asObject = Object.fromEntries(result.value.entries()); | ||||
|             expect(asObject).toMatchObject(output); | ||||
|         }); | ||||
|     }); | ||||
|  |  | |||
|  | @ -18,7 +18,6 @@ import { | |||
|     objectClone, | ||||
|     objectDiff, | ||||
|     objectExcluding, | ||||
|     objectFromEntries, | ||||
|     objectHasDiff, | ||||
|     objectKeyChanges, | ||||
|     objectShallowClone, | ||||
|  | @ -242,21 +241,4 @@ describe('objects', () => { | |||
|             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); | ||||
|         }); | ||||
|     }); | ||||
| }); | ||||
|  |  | |||
		Loading…
	
		Reference in New Issue
	
	 Michael Telatynski
						Michael Telatynski