diff --git a/res/css/views/voip/_CallContainer.scss b/res/css/views/voip/_CallContainer.scss
index 8262075559..168a8bb74b 100644
--- a/res/css/views/voip/_CallContainer.scss
+++ b/res/css/views/voip/_CallContainer.scss
@@ -98,5 +98,29 @@ limitations under the License.
line-height: $font-24px;
}
}
+
+ .mx_IncomingCallBox_iconButton {
+ position: absolute;
+ right: 8px;
+
+ &::before {
+ content: '';
+
+ height: 20px;
+ width: 20px;
+ background-color: $icon-button-color;
+ mask-repeat: no-repeat;
+ mask-size: contain;
+ mask-position: center;
+ }
+ }
+
+ .mx_IncomingCallBox_silence::before {
+ mask-image: url('$(res)/img/voip/silence.svg');
+ }
+
+ .mx_IncomingCallBox_unSilence::before {
+ mask-image: url('$(res)/img/voip/un-silence.svg');
+ }
}
}
diff --git a/res/img/voip/silence.svg b/res/img/voip/silence.svg
new file mode 100644
index 0000000000..332932dfff
--- /dev/null
+++ b/res/img/voip/silence.svg
@@ -0,0 +1,3 @@
+
diff --git a/res/img/voip/un-silence.svg b/res/img/voip/un-silence.svg
new file mode 100644
index 0000000000..c00b366f84
--- /dev/null
+++ b/res/img/voip/un-silence.svg
@@ -0,0 +1,4 @@
+
diff --git a/src/CallHandler.tsx b/src/CallHandler.tsx
index bf7cb3473d..448b1cb780 100644
--- a/src/CallHandler.tsx
+++ b/src/CallHandler.tsx
@@ -99,7 +99,7 @@ const CHECK_PROTOCOLS_ATTEMPTS = 3;
// (and store the ID of their native room)
export const VIRTUAL_ROOM_EVENT_TYPE = 'im.vector.is_virtual_room';
-enum AudioID {
+export enum AudioID {
Ring = 'ringAudio',
Ringback = 'ringbackAudio',
CallEnd = 'callendAudio',
diff --git a/src/components/views/voip/IncomingCallBox.tsx b/src/components/views/voip/IncomingCallBox.tsx
index 2abdc0641d..a0660318bc 100644
--- a/src/components/views/voip/IncomingCallBox.tsx
+++ b/src/components/views/voip/IncomingCallBox.tsx
@@ -21,17 +21,20 @@ import {MatrixClientPeg} from '../../../MatrixClientPeg';
import dis from '../../../dispatcher/dispatcher';
import { _t } from '../../../languageHandler';
import { ActionPayload } from '../../../dispatcher/payloads';
-import CallHandler from '../../../CallHandler';
+import CallHandler, { AudioID } from '../../../CallHandler';
import RoomAvatar from '../avatars/RoomAvatar';
import FormButton from '../elements/FormButton';
import { CallState } from 'matrix-js-sdk/src/webrtc/call';
import {replaceableComponent} from "../../../utils/replaceableComponent";
+import AccessibleTooltipButton from '../elements/AccessibleTooltipButton';
+import classNames from 'classnames';
interface IProps {
}
interface IState {
incomingCall: any;
+ silenced: boolean;
}
@replaceableComponent("views.voip.IncomingCallBox")
@@ -44,6 +47,7 @@ export default class IncomingCallBox extends React.Component {
this.dispatcherRef = dis.register(this.onAction);
this.state = {
incomingCall: null,
+ silenced: false,
};
}
@@ -58,6 +62,7 @@ export default class IncomingCallBox extends React.Component {
if (call && call.state === CallState.Ringing) {
this.setState({
incomingCall: call,
+ silenced: false, // Reset silenced state for new call
});
} else {
this.setState({
@@ -84,6 +89,13 @@ export default class IncomingCallBox extends React.Component {
});
};
+ private onSilenceClick: React.MouseEventHandler = (e) => {
+ e.stopPropagation();
+ const newState = !this.state.silenced
+ this.setState({silenced: newState});
+ newState ? CallHandler.sharedInstance().pause(AudioID.Ring) : CallHandler.sharedInstance().play(AudioID.Ring);
+ }
+
public render() {
if (!this.state.incomingCall) {
return null;
@@ -107,6 +119,12 @@ export default class IncomingCallBox extends React.Component {
}
}
+ const silenceClass = classNames({
+ "mx_IncomingCallBox_iconButton": true,
+ "mx_IncomingCallBox_unSilence": this.state.silenced,
+ "mx_IncomingCallBox_silence": !this.state.silenced,
+ });
+
return
{
{caller}
{incomingCallText}
+