diff --git a/modules/tchap-translations/tchap_translations.json b/modules/tchap-translations/tchap_translations.json index 3d8cfac19d..1975883996 100644 --- a/modules/tchap-translations/tchap_translations.json +++ b/modules/tchap-translations/tchap_translations.json @@ -713,5 +713,13 @@ "widget|error_need_kick_permission": { "en": "You need to be able to kick users to do that.", "fr": "Vous devez avoir l’autorisation de retirer des utilisateurs pour faire ceci." + }, + "Report a problem": { + "en": "Report a problem", + "fr": "Signaler un problème" + }, + "tchap_voip_bug_report_prefill": { + "en": "I had a problem during a Tchap call.\nDetails: ...", + "fr": "J'ai eu un problème pendant un appel Tchap.\nDétails : ..." } } diff --git a/patches/bug-reporting/matrix-react-sdk+3.92.0.patch b/patches/bug-reporting/matrix-react-sdk+3.92.0.patch index 425a9e57b0..ce11718eab 100644 --- a/patches/bug-reporting/matrix-react-sdk+3.92.0.patch +++ b/patches/bug-reporting/matrix-react-sdk+3.92.0.patch @@ -1,16 +1,17 @@ diff --git a/node_modules/matrix-react-sdk/src/components/views/dialogs/BugReportDialog.tsx b/node_modules/matrix-react-sdk/src/components/views/dialogs/BugReportDialog.tsx -index 5d826f2..5163137 100644 +index 5d826f2..51baf28 100644 --- a/node_modules/matrix-react-sdk/src/components/views/dialogs/BugReportDialog.tsx +++ b/node_modules/matrix-react-sdk/src/components/views/dialogs/BugReportDialog.tsx -@@ -32,6 +32,7 @@ import DialogButtons from "../elements/DialogButtons"; +@@ -32,6 +32,8 @@ import DialogButtons from "../elements/DialogButtons"; import { sendSentryReport } from "../../../sentry"; import defaultDispatcher from "../../../dispatcher/dispatcher"; import { Action } from "../../../dispatcher/actions"; +import { MatrixClientPeg } from '../../../MatrixClientPeg'; // :TCHAP: ++import TchapUtils from "../../../../../../src/tchap/util/TchapUtils"; // :TCHAP: interface IProps { onFinished: (success: boolean) => void; -@@ -96,12 +97,21 @@ export default class BugReportDialog extends React.Component { +@@ -96,12 +98,21 @@ export default class BugReportDialog extends React.Component { }; private onSubmit = (): void => { @@ -32,7 +33,7 @@ index 5d826f2..5163137 100644 const userText = (this.state.text.length > 0 ? this.state.text + "\n\n" : "") + -@@ -111,11 +121,24 @@ export default class BugReportDialog extends React.Component { +@@ -111,11 +122,34 @@ export default class BugReportDialog extends React.Component { this.setState({ busy: true, progress: null, err: null }); this.sendProgressCallback(_t("bug_reporting|preparing_logs")); @@ -43,13 +44,23 @@ index 5d826f2..5163137 100644 - labels: this.props.label ? [this.props.label] : [], + // :TCHAP: customise report : add email, prefix with "tchap-web" + const client = MatrixClientPeg.get(); ++ const customFields = {}; + client.getThreePids().then(result => { -+ const customFields = {}; + result.threepids.forEach(threepid => { + return customFields[threepid.medium] = threepid.address; + }); + return customFields; + }).then(customFields => { ++ // is this a voip report ? Add it in "context" field ++ if (this.props.label === "voip-feedback") { ++ customFields.context = "voip"; ++ } ++ ++ return TchapUtils.isCurrentlyUsingBluetooth().then(isCurrentlyUsingBluetooth => { ++ customFields.audio_input = isCurrentlyUsingBluetooth ? "headset_bluetooth" : "device"; ++ return customFields; ++ }) ++ }).then(customFields => { + return sendBugReport(SdkConfig.get().bug_report_endpoint_url, { + userText, + sendLogs: true, @@ -62,7 +73,7 @@ index 5d826f2..5163137 100644 }).then( () => { if (!this.unmounted) { -@@ -150,6 +173,7 @@ export default class BugReportDialog extends React.Component { +@@ -150,6 +184,7 @@ export default class BugReportDialog extends React.Component { sendLogs: true, progressCallback: this.downloadProgressCallback, labels: this.props.label ? [this.props.label] : [], @@ -70,7 +81,7 @@ index 5d826f2..5163137 100644 }); this.setState({ -@@ -214,6 +238,53 @@ export default class BugReportDialog extends React.Component { +@@ -214,6 +249,53 @@ export default class BugReportDialog extends React.Component { ); } @@ -124,7 +135,7 @@ index 5d826f2..5163137 100644 return ( { +@@ -281,5 +363,6 @@ export default class BugReportDialog extends React.Component { /> ); @@ -144,6 +155,55 @@ index 1eb0379..90955dd 100644 }; /** +diff --git a/node_modules/matrix-react-sdk/src/components/views/messages/LegacyCallEvent.tsx b/node_modules/matrix-react-sdk/src/components/views/messages/LegacyCallEvent.tsx +index 3c8241d..cdd9a83 100644 +--- a/node_modules/matrix-react-sdk/src/components/views/messages/LegacyCallEvent.tsx ++++ b/node_modules/matrix-react-sdk/src/components/views/messages/LegacyCallEvent.tsx +@@ -28,6 +28,10 @@ import AccessibleTooltipButton from "../elements/AccessibleTooltipButton"; + import { formatPreciseDuration } from "../../../DateUtils"; + import Clock from "../audio_messages/Clock"; + ++import Modal from "matrix-react-sdk/src/Modal"; // :TCHAP: ++import BugReportDialog from "matrix-react-sdk/src/components/views/dialogs/BugReportDialog"; // :TCHAP: ++import "../../../../../../res/css/views/messages/TchapLegacyCallEvent.pcss"; // :TCHAP: ++ + const MAX_NON_NARROW_WIDTH = (450 / 70) * 100; + + interface IProps { +@@ -192,6 +196,7 @@ export default class LegacyCallEvent extends React.PureComponent + return ( +
+ {text} ++ {this.renderBugReportButton()} + {this.props.timestamp} +
+ ); +@@ -264,6 +269,25 @@ export default class LegacyCallEvent extends React.PureComponent + ); + } + ++ private onReportBugClick = (): void => { ++ Modal.createDialog(BugReportDialog, { ++ initialText: _t("tchap_voip_bug_report_prefill"), ++ label: "voip-feedback", ++ }); ++ }; ++ ++ private renderBugReportButton(): JSX.Element { ++ return ( ++ ++ {_t("Report a problem")} ++ ++ ); ++ } ++ + public render(): React.ReactNode { + const event = this.props.mxEvent; + const sender = event.sender ? event.sender.name : event.getSender(); diff --git a/node_modules/matrix-react-sdk/src/rageshake/submit-rageshake.ts b/node_modules/matrix-react-sdk/src/rageshake/submit-rageshake.ts index d15f3d9..7c7f6d8 100644 --- a/node_modules/matrix-react-sdk/src/rageshake/submit-rageshake.ts diff --git a/patches/patches.json b/patches/patches.json index d4aafa295f..7cc175e65d 100644 --- a/patches/patches.json +++ b/patches/patches.json @@ -17,12 +17,13 @@ }, "bug-reporting": { "package": "matrix-react-sdk", - "github-issue":"https://github.com/tchapgouv/tchap-web-v4/issues/527, https://github.com/tchapgouv/tchap-web-v4/issues/526", - "comments" : "add email in rageshake", + "github-issue":"https://github.com/tchapgouv/tchap-web-v4/issues/527, https://github.com/tchapgouv/tchap-web-v4/issues/526, https://github.com/tchapgouv/tchap-product/issues/267", + "comments" : "add email in rageshake + voip", "files": [ "src/components/views/dialogs/BugReportDialog.tsx", "src/rageshake/submit-rageshake.ts", - "src/components/views/elements/AccessibleButton.tsx" + "src/components/views/elements/AccessibleButton.tsx", + "src/components/views/messages/LegacyCallEvent.tsx" ] }, "content-scanner": { diff --git a/res/css/views/messages/TchapLegacyCallEvent.pcss b/res/css/views/messages/TchapLegacyCallEvent.pcss new file mode 100644 index 0000000000..23046e63ff --- /dev/null +++ b/res/css/views/messages/TchapLegacyCallEvent.pcss @@ -0,0 +1,9 @@ +.mx_LegacyCallEvent_wrapper { + .mx_LegacyCallEvent { + &.mx_LegacyCallEvent_voice { + .mx_LegacyCallEvent_content_button_reportBug span::before { + mask-image: url("~matrix-react-sdk/res/img/element-icons/warning-badge.svg"); + } + } + } +} \ No newline at end of file diff --git a/src/tchap/util/TchapUtils.ts b/src/tchap/util/TchapUtils.ts index 1b1b3cfc9a..1a5087e07f 100644 --- a/src/tchap/util/TchapUtils.ts +++ b/src/tchap/util/TchapUtils.ts @@ -238,4 +238,37 @@ export default class TchapUtils { } return false; } + + /** + * Whether the user is currently using a bluetooth audio input (bluetooth headset for example). + * In Chrome we can get the information sometimes, and in Firefox and Edge we don't know. + * @returns true if we are sure user is currently using a bluetooth audio input. False if no blutooth, or we don't know. + */ + static async isCurrentlyUsingBluetooth(): Promise { + if (!navigator.mediaDevices?.enumerateDevices) { + console.log("enumerateDevices() not supported. Cannot know if there is a bluetooth device."); + return false; + } else { + // List cameras and microphones. + return navigator.mediaDevices + .enumerateDevices() + .then((devices) => { + let hasBluetooth = false; + devices.forEach((device) => { + console.log(`${device.kind}: ${device.label} id = ${device.deviceId}`); + if (device.kind === "audioinput") { + if (device.label.toLowerCase().includes("bluetooth")) { + hasBluetooth = true; + } + } + }); + return hasBluetooth; + }) + .catch((err) => { + console.error(`${err.name}: ${err.message}`); + return false; + }); + } + } + }