From bf4c8f048fc1619ae70ddb01d9e49b340af0df97 Mon Sep 17 00:00:00 2001
From: Michael Telatynski <7t3chguy@gmail.com>
Date: Tue, 11 May 2021 15:58:19 +0100
Subject: [PATCH 1/3] Add feedback mechanism for beta features
---
res/css/views/beta/_BetaCard.scss | 8 ++-
src/components/views/beta/BetaCard.tsx | 34 +++++++--
.../views/dialogs/BetaFeedbackDialog.tsx | 69 +++++++++++++++++++
src/i18n/strings/en_EN.json | 10 +--
src/rageshake/submit-rageshake.ts | 18 +++++
src/settings/Settings.tsx | 7 +-
6 files changed, 131 insertions(+), 15 deletions(-)
create mode 100644 src/components/views/dialogs/BetaFeedbackDialog.tsx
diff --git a/res/css/views/beta/_BetaCard.scss b/res/css/views/beta/_BetaCard.scss
index 05149b7f6c..3463a653fc 100644
--- a/res/css/views/beta/_BetaCard.scss
+++ b/res/css/views/beta/_BetaCard.scss
@@ -39,19 +39,21 @@ limitations under the License.
font-size: $font-15px;
line-height: $font-20px;
color: $secondary-fg-color;
+ margin-bottom: 20px;
}
.mx_AccessibleButton {
display: block;
- margin: 20px 0;
- padding: 12px 40px;
- width: max-content;
+ margin: 12px 0;
+ padding: 7px 40px;
+ width: auto;
}
.mx_BetaCard_disclaimer {
font-size: $font-12px;
line-height: $font-15px;
color: $secondary-fg-color;
+ margin-top: 20px;
}
}
diff --git a/src/components/views/beta/BetaCard.tsx b/src/components/views/beta/BetaCard.tsx
index 96b1fbabe5..c12b05d119 100644
--- a/src/components/views/beta/BetaCard.tsx
+++ b/src/components/views/beta/BetaCard.tsx
@@ -22,6 +22,9 @@ import AccessibleButton from "../elements/AccessibleButton";
import SettingsStore from "../../../settings/SettingsStore";
import {SettingLevel} from "../../../settings/SettingLevel";
import TextWithTooltip from "../elements/TextWithTooltip";
+import Modal from "../../../Modal";
+import BetaFeedbackDialog from "../dialogs/BetaFeedbackDialog";
+import SdkConfig from "../../../SdkConfig";
interface IProps {
title?: string;
@@ -63,9 +66,23 @@ const BetaCard = ({ title: titleOverride, featureId }: IProps) => {
const info = SettingsStore.getBetaInfo(featureId);
if (!info) return null; // Beta is invalid/disabled
- const { title, caption, disclaimer, image } = info;
+ const { title, caption, disclaimer, image, feedbackLabel, feedbackSubheading } = info;
const value = SettingsStore.getValue(featureId);
+ let feedbackButton;
+ if (value && feedbackLabel && feedbackSubheading && SdkConfig.get().bug_report_endpoint_url) {
+ feedbackButton = {
+ Modal.createTrackedDialog("Beta Feedback", featureId, BetaFeedbackDialog, {
+ featureId,
+ });
+ }}
+ kind="primary"
+ >
+ { _t("Feedback") }
+ ;
+ }
+
return
@@ -73,12 +90,15 @@ const BetaCard = ({ title: titleOverride, featureId }: IProps) => {
{ _t(caption) }
-
SettingsStore.setValue(featureId, null, SettingLevel.DEVICE, !value)}
- kind="primary"
- >
- { value ? _t("Leave the beta") : _t("Join the beta") }
-
+
+ { feedbackButton }
+
SettingsStore.setValue(featureId, null, SettingLevel.DEVICE, !value)}
+ kind={feedbackButton ? "primary_outline" : "primary"}
+ >
+ { value ? _t("Leave the beta") : _t("Join the beta") }
+
+
{ disclaimer &&
{ disclaimer(value) }
}
diff --git a/src/components/views/dialogs/BetaFeedbackDialog.tsx b/src/components/views/dialogs/BetaFeedbackDialog.tsx
new file mode 100644
index 0000000000..702adc8fb1
--- /dev/null
+++ b/src/components/views/dialogs/BetaFeedbackDialog.tsx
@@ -0,0 +1,69 @@
+/*
+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 SettingsStore from "../../../settings/SettingsStore";
+import {submitFeedback} from "../../../rageshake/submit-rageshake";
+
+interface IProps extends IDialogProps {
+ featureId: string;
+}
+
+const BetaFeedbackDialog: React.FC
= ({featureId, onFinished}) => {
+ const info = SettingsStore.getBetaInfo(featureId);
+
+ const [comment, setComment] = useState("");
+
+ const sendFeedback = async (ok: boolean) => {
+ if (!ok) return onFinished(false);
+
+ submitFeedback(SdkConfig.get().bug_report_endpoint_url, info.feedbackLabel, comment);
+ onFinished(true);
+ };
+
+ return (
+ { _t(info.feedbackSubheading) }
+
+
+
;
};
@@ -555,6 +580,7 @@ const SpaceAddExistingRooms = ({ space, onFinished }) => {
{ buttonLabel }
+
;
};
@@ -574,6 +600,7 @@ const SpaceSetupPublicShare = ({ justCreatedOpts, space, onFinished }) => {
{ _t("Go to my first room") }
+
;
};
@@ -600,6 +627,7 @@ const SpaceSetupPrivateScope = ({ space, justCreatedOpts, onFinished }) => {
{ _t("Me and my teammates") }
{ _t("A private space for you and your teammates") }
+
;
};
@@ -721,6 +749,7 @@ const SpaceSetupPrivateInvite = ({ space, onFinished }) => {
value={buttonLabel}
/>
+
;
};
diff --git a/src/components/views/beta/BetaCard.tsx b/src/components/views/beta/BetaCard.tsx
index c12b05d119..821c448f4f 100644
--- a/src/components/views/beta/BetaCard.tsx
+++ b/src/components/views/beta/BetaCard.tsx
@@ -73,9 +73,7 @@ const BetaCard = ({ title: titleOverride, featureId }: IProps) => {
if (value && feedbackLabel && feedbackSubheading && SdkConfig.get().bug_report_endpoint_url) {
feedbackButton = {
- Modal.createTrackedDialog("Beta Feedback", featureId, BetaFeedbackDialog, {
- featureId,
- });
+ Modal.createTrackedDialog("Beta Feedback", featureId, BetaFeedbackDialog, { featureId });
}}
kind="primary"
>
diff --git a/src/components/views/dialogs/AddExistingToSpaceDialog.tsx b/src/components/views/dialogs/AddExistingToSpaceDialog.tsx
index ed7ae613bd..8ac68e99b7 100644
--- a/src/components/views/dialogs/AddExistingToSpaceDialog.tsx
+++ b/src/components/views/dialogs/AddExistingToSpaceDialog.tsx
@@ -36,6 +36,7 @@ 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";
interface IProps extends IDialogProps {
matrixClient: MatrixClient;
@@ -307,6 +308,7 @@ const AddExistingToSpaceDialog: React.FC = ({ matrixClient: cli, space,
{ footer }
+ onFinished(false)} />
;
};
diff --git a/src/components/views/dialogs/SpaceSettingsDialog.tsx b/src/components/views/dialogs/SpaceSettingsDialog.tsx
index 83f5d7141b..dfee5d63e3 100644
--- a/src/components/views/dialogs/SpaceSettingsDialog.tsx
+++ b/src/components/views/dialogs/SpaceSettingsDialog.tsx
@@ -32,6 +32,7 @@ import Modal from "../../../Modal";
import defaultDispatcher from "../../../dispatcher/dispatcher";
import {allSettled} from "../../../utils/promise";
import {useDispatcher} from "../../../hooks/useDispatcher";
+import {SpaceFeedbackPrompt} from "../../structures/SpaceRoomView";
interface IProps extends IDialogProps {
matrixClient: MatrixClient;
@@ -111,6 +112,8 @@ const SpaceSettingsDialog: React.FC = ({ matrixClient: cli, space, onFin
{ error && { error }
}
+ onFinished(false)} />
+
{
return (
@@ -152,6 +153,8 @@ const SpaceCreateMenu = ({ onFinished }) => {
/>
{ _t("You can change this later") }
+
+
;
} else {
body =
diff --git a/src/i18n/strings/en_EN.json b/src/i18n/strings/en_EN.json
index 0f1e8c8fbd..96cc245c7a 100644
--- a/src/i18n/strings/en_EN.json
+++ b/src/i18n/strings/en_EN.json
@@ -2682,9 +2682,10 @@
"Mark as suggested": "Mark as suggested",
"No results found": "No results found",
"You may want to try a different search or check for typos.": "You may want to try a different search or check for typos.",
- "Search names and description": "Search names and description",
+ "Search names and descriptions": "Search names and descriptions",
"If you can't find the room you're looking for, ask for an invite or create a new room.": "If you can't find the room you're looking for, ask for an invite or create a new room.",
"Create room": "Create room",
+ "Spaces are a beta feature.": "Spaces are a beta feature.",
"Public space": "Public space",
"Private space": "Private space",
" invites you": " invites you",
From 7396ce76e559bb4c3849d163847de708f31a7a92 Mon Sep 17 00:00:00 2001
From: Michael Telatynski <7t3chguy@gmail.com>
Date: Tue, 11 May 2021 17:30:33 +0100
Subject: [PATCH 3/3] Tweak the feedbacks a tad
---
res/css/_components.scss | 1 +
res/css/structures/_SpaceRoomView.scss | 13 +++++-
.../views/dialogs/_BetaFeedbackDialog.scss | 30 ++++++++++++
.../views/dialogs/BetaFeedbackDialog.tsx | 46 +++++++++++++++++--
src/i18n/strings/en_EN.json | 10 ++--
src/rageshake/submit-rageshake.ts | 4 +-
6 files changed, 93 insertions(+), 11 deletions(-)
create mode 100644 res/css/views/dialogs/_BetaFeedbackDialog.scss
diff --git a/res/css/_components.scss b/res/css/_components.scss
index e6c55c0250..d8e5247f9d 100644
--- a/res/css/_components.scss
+++ b/res/css/_components.scss
@@ -63,6 +63,7 @@
@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";
diff --git a/res/css/structures/_SpaceRoomView.scss b/res/css/structures/_SpaceRoomView.scss
index 3f8a2c5d58..503fe72414 100644
--- a/res/css/structures/_SpaceRoomView.scss
+++ b/res/css/structures/_SpaceRoomView.scss
@@ -339,6 +339,15 @@ $SpaceRoomViewInnerWidth: 428px;
.mx_SearchBox {
margin: 0 0 20px;
}
+
+ .mx_SpaceFeedbackPrompt {
+ margin-bottom: 16px;
+
+ // hide the HR as we have our own
+ & + hr {
+ display: none;
+ }
+ }
}
.mx_SpaceRoomView_privateScope {
@@ -495,7 +504,7 @@ $SpaceRoomViewInnerWidth: 428px;
}
.mx_AccessibleButton_kind_link {
- color: $accent-color-alt;
+ color: $accent-color;
position: relative;
padding: 0 0 0 24px;
margin-left: 8px;
@@ -508,7 +517,7 @@ $SpaceRoomViewInnerWidth: 428px;
left: 0;
height: 16px;
width: 16px;
- background-color: $accent-color-alt;
+ background-color: $accent-color;
mask-repeat: no-repeat;
mask-size: contain;
mask-image: url('$(res)/img/element-icons/chat-bubbles.svg');
diff --git a/res/css/views/dialogs/_BetaFeedbackDialog.scss b/res/css/views/dialogs/_BetaFeedbackDialog.scss
new file mode 100644
index 0000000000..fe3df01986
--- /dev/null
+++ b/res/css/views/dialogs/_BetaFeedbackDialog.scss
@@ -0,0 +1,30 @@
+/*
+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.
+*/
+
+.mx_BetaFeedbackDialog {
+ .mx_BetaFeedbackDialog_subheading {
+ color: $secondary-fg-color;
+ font-size: $font-14px;
+ line-height: $font-20px;
+ margin-bottom: 24px;
+ }
+
+ .mx_AccessibleButton_kind_link {
+ padding: 0;
+ font-size: inherit;
+ line-height: inherit;
+ }
+}
diff --git a/src/components/views/dialogs/BetaFeedbackDialog.tsx b/src/components/views/dialogs/BetaFeedbackDialog.tsx
index 702adc8fb1..119799c609 100644
--- a/src/components/views/dialogs/BetaFeedbackDialog.tsx
+++ b/src/components/views/dialogs/BetaFeedbackDialog.tsx
@@ -23,6 +23,13 @@ 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 {USER_LABS_TAB} from "./UserSettingsDialog";
interface IProps extends IDialogProps {
featureId: string;
@@ -32,25 +39,47 @@ const BetaFeedbackDialog: React.FC = ({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);
- submitFeedback(SdkConfig.get().bug_report_endpoint_url, info.feedbackLabel, comment);
+ submitFeedback(SdkConfig.get().bug_report_endpoint_url, info.feedbackLabel, comment, canContact);
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 (
- { _t(info.feedbackSubheading) }
+
+ { _t(info.feedbackSubheading) }
+
+ { _t("Your platform and username will be noted to help us use your feedback as much as we can.")}
+
+
{
+ onFinished(false);
+ defaultDispatcher.dispatch({
+ action: Action.ViewUserSettings,
+ initialTabId: USER_LABS_TAB,
+ });
+ }}>
+ { _t("To leave the beta, visit your settings.") }
+
+
}
button={_t("Send feedback")}
buttonDisabled={!comment}
diff --git a/src/i18n/strings/en_EN.json b/src/i18n/strings/en_EN.json
index 96cc245c7a..b5d402132e 100644
--- a/src/i18n/strings/en_EN.json
+++ b/src/i18n/strings/en_EN.json
@@ -2065,8 +2065,11 @@
"Invite anyway": "Invite anyway",
"Close dialog": "Close dialog",
"Beta feedback": "Beta feedback",
- "Add comment": "Add comment",
- "Comment": "Comment",
+ "Thank you for your feedback, we really appreciate it.": "Thank you for your feedback, we really appreciate it.",
+ "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",
@@ -2194,9 +2197,10 @@
"Rate %(brand)s": "Rate %(brand)s",
"Tell us below how you feel about %(brand)s so far.": "Tell us below how you feel about %(brand)s so far.",
"Please go into as much detail as you like, so we can track down the problem.": "Please go into as much detail as you like, so we can track down the problem.",
+ "Add comment": "Add 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.",
"PRO TIP: If you start a bug, please submit debug logs to help us track down the problem.": "PRO TIP: If you start a bug, please submit debug logs to help us track down the problem.",
- "Feedback": "Feedback",
"Report a bug": "Report a bug",
"Please view existing bugs on Github first. No match? Start a new one.": "Please view existing bugs on Github first. No match? Start a new one.",
"Confirm abort of host creation": "Confirm abort of host creation",
diff --git a/src/rageshake/submit-rageshake.ts b/src/rageshake/submit-rageshake.ts
index 9c4fe1f95b..f46dd88fba 100644
--- a/src/rageshake/submit-rageshake.ts
+++ b/src/rageshake/submit-rageshake.ts
@@ -269,7 +269,7 @@ function uint8ToString(buf: Buffer) {
return out;
}
-export async function submitFeedback(endpoint: string, label: string, comment: string) {
+export async function submitFeedback(endpoint: string, label: string, comment: string, canContact = false) {
let version = "UNKNOWN";
try {
version = await PlatformPeg.get().getAppVersion();
@@ -278,10 +278,12 @@ export async function submitFeedback(endpoint: string, label: string, comment: s
const body = new FormData();
body.append("label", label);
body.append("text", comment);
+ body.append("can_contact", canContact ? "yes" : "no");
body.append("app", "element-web");
body.append("version", version);
body.append("platform", PlatformPeg.get().getHumanReadableName());
+ body.append("user_id", MatrixClientPeg.get()?.getUserId());
await _submitReport(SdkConfig.get().bug_report_endpoint_url, body, () => {});
}