From 854ddb1bb3c906bcbc5669bde5c7a34ffc32448c Mon Sep 17 00:00:00 2001 From: Badi Ifaoui Date: Tue, 20 Feb 2024 10:52:44 +0100 Subject: [PATCH] feat: superhero feedback (#61) --- components.json | 3 +- config.sample.json | 11 +- .../views/dialogs/FeedbackDialog.tsx | 161 ++++++++++++++++++ 3 files changed, 173 insertions(+), 2 deletions(-) create mode 100644 src/components/views/dialogs/FeedbackDialog.tsx diff --git a/components.json b/components.json index f1c6646f347..2a54e08e9a5 100644 --- a/components.json +++ b/components.json @@ -21,5 +21,6 @@ "src/linkify-matrix.ts": "src/linkify-matrix.ts", "src/components/structures/LeftPanel.tsx": "src/components/structures/LeftPanel.tsx", "src/components/views/rooms/RoomList.tsx": "src/components/views/rooms/RoomList.tsx", - "src/components/views/rooms/RoomSublist.tsx": "src/components/views/rooms/RoomSublist.tsx" + "src/components/views/rooms/RoomSublist.tsx": "src/components/views/rooms/RoomSublist.tsx", + "src/components/views/dialogs/FeedbackDialog.tsx": "src/components/views/dialogs/FeedbackDialog.tsx" } diff --git a/config.sample.json b/config.sample.json index 25f886b6a97..ff5e158548d 100644 --- a/config.sample.json +++ b/config.sample.json @@ -47,5 +47,14 @@ "participant_limit": 8, "brand": "Element Call" }, - "map_style_url": "https://api.maptiler.com/maps/streets/style.json?key=fU3vlMsMn4Jb6dnEIFsx" + "map_style_url": "https://api.maptiler.com/maps/streets/style.json?key=fU3vlMsMn4Jb6dnEIFsx", + "branding": { + "auth_header_logo_url": "themes/superhero/img/logos/superhero-logo.svg" + }, + "feedback": { + "existing_issues_url": "https://github.com/superhero-com/superhero-chat-web/issues?q=is%3Aopen+is%3Aissue+sort%3Areactions-%2B1-desc", + "new_issue_url": "https://github.com/superhero-com/superhero-chat-web/issues/new/choose" + }, + "bug_report_endpoint_url": "https://github.com/superhero-com/superhero-chat-web/issues?q=is%3Aopen+is%3Aissue+sort%3Areactions-%2B1-desc", + "support_channel_room_id": "#superhero_feedback:superhero.chat" } diff --git a/src/components/views/dialogs/FeedbackDialog.tsx b/src/components/views/dialogs/FeedbackDialog.tsx new file mode 100644 index 00000000000..9f89717e3b3 --- /dev/null +++ b/src/components/views/dialogs/FeedbackDialog.tsx @@ -0,0 +1,161 @@ +/* +Copyright 2018 New Vector Ltd + +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, { useEffect, useRef, useState } from "react"; +import QuestionDialog from "matrix-react-sdk/src/components/views/dialogs/QuestionDialog"; +import { _t } from "matrix-react-sdk/src/languageHandler"; +import Field from "matrix-react-sdk/src/components/views/elements/Field"; +import AccessibleButton from "matrix-react-sdk/src/components/views/elements/AccessibleButton"; +import SdkConfig from "matrix-react-sdk/src/SdkConfig"; +import Modal from "matrix-react-sdk/src/Modal"; +import BugReportDialog from "matrix-react-sdk/src/components/views/dialogs/BugReportDialog"; +import { useStateToggle } from "matrix-react-sdk/src/hooks/useStateToggle"; +import StyledCheckbox from "matrix-react-sdk/src/components/views/elements/StyledCheckbox"; +import ExternalLink from "matrix-react-sdk/src/components/views/elements/ExternalLink"; +import { MatrixClientPeg } from "matrix-react-sdk/src/MatrixClientPeg"; +interface IProps { + feature?: string; + onFinished(): void; +} + +const FeedbackDialog: React.FC = (props: IProps) => { + const feedbackRef = useRef(null); + const [comment, setComment] = useState(""); + const [canContact, toggleCanContact] = useStateToggle(false); + const client = MatrixClientPeg.safeGet(); + + useEffect(() => { + // autofocus doesn't work on textareas + feedbackRef.current?.focus(); + }, []); + + const onDebugLogsLinkClick = (): void => { + props.onFinished(); + Modal.createDialog(BugReportDialog, {}); + }; + + const hasFeedback = !!SdkConfig.get().bug_report_endpoint_url; + const supportChannelRoomId = (SdkConfig.get() as any).support_channel_room_id; + + const onFinished = async (sendFeedback: boolean): Promise => { + if (hasFeedback && sendFeedback) { + window.open(`#/room/${supportChannelRoomId}`, "_self"); + + const actualRoomId = await client.getRoomIdForAlias(supportChannelRoomId); + client.sendTextMessage(actualRoomId.room_id, comment); + } + props.onFinished(); + }; + + let feedbackSection: JSX.Element | undefined; + if (hasFeedback) { + feedbackSection = ( +
+

{_t("feedback|comment_label")}

+ + {/*

{_t("feedback|platform_username")}

*/} +

Ready to make a difference? Drop a message to share your feedback, thoughts, or suggestions.

+ + { + setComment(ev.target.value); + }} + ref={feedbackRef} + /> + + + {_t("feedback|may_contact_label")} + +
+ ); + } + + let bugReports: JSX.Element | undefined; + if (hasFeedback) { + bugReports = ( +

+ {_t( + "feedback|pro_type", + {}, + { + debugLogsLink: (sub) => ( + + {sub} + + ), + }, + )} +

+ ); + } + + const existingIssuesUrl = SdkConfig.getObject("feedback").get("existing_issues_url"); + const newIssueUrl = SdkConfig.getObject("feedback").get("new_issue_url"); + + return ( + +
+

{_t("common|report_a_bug")}

+

+ {_t( + "feedback|existing_issue_link", + {}, + { + existingIssuesLink: (sub) => { + return ( + + {sub} + + ); + }, + newIssueLink: (sub) => { + return ( + + {sub} + + ); + }, + }, + )} +

+ {bugReports} +
+ {feedbackSection} + + } + button={hasFeedback ? _t("feedback|send_feedback_action") : _t("action|go_back")} + buttonDisabled={hasFeedback && !comment} + onFinished={onFinished} + /> + ); +}; + +export default FeedbackDialog;