Microphone timer

pull/1102/head
Vincent 5 years ago
parent 8d8abf1e43
commit 2dc5885c88

@ -876,6 +876,10 @@
"description":
"Shown in toast if user clicks on quote references messages not loaded in view, but in database"
},
"recording": {
"message": "Recording",
"description": "Shown on SessionRecording when recording is active."
},
"voiceNoteMustBeOnlyAttachment": {
"message":
"A voice note must be the only attachment included in a message.",

@ -942,6 +942,7 @@
.toString(36)
.substring(3);
window.toasts = new Map();
window.pushToast = options => {
// Setting toasts with the same ID can be used to prevent identical

@ -63,6 +63,7 @@
"@journeyapps/sqlcipher": "https://github.com/scottnonnenberg-signal/node-sqlcipher.git#2e28733b61640556b0272a3bfc78b0357daf71e6",
"@sindresorhus/is": "0.8.0",
"@types/dompurify": "^2.0.0",
"@types/moment": "^2.13.0",
"@types/rc-slider": "^8.6.5",
"@types/react-mic": "^12.4.1",
"backbone": "1.3.3",

@ -79,6 +79,7 @@ window.CONSTANTS = {
// at which more messages should be loaded
MESSAGE_CONTAINER_BUFFER_OFFSET_PX: 30,
MESSAGE_FETCH_INTERVAL: 1,
MAX_VOICE_MESSAGE_DURATION: 600,
};
window.versionInfo = {

@ -266,11 +266,10 @@ $composition-container-height: 60px;
canvas {
width: 100%;
padding: 0px $session-margin-lg;
max-width: 700px;
}
}
&--delete {
&--status {
display: flex;
justify-content: center;
position: absolute;
@ -278,7 +277,7 @@ $composition-container-height: 60px;
right: 0;
bottom: $composition-container-height + $session-margin-md;
.session-button.danger-alt{
.session-button{
display: flex;
justify-content: center;
align-items: center;
@ -286,6 +285,29 @@ $composition-container-height: 60px;
font-weight: 300;
font-family: "SF Pro Text";
&.primary {
cursor: default;
user-select: none;
&:hover{
filter: brightness(100%);
}
}
}
}
&--timer {
display: inline-flex;
align-items: center;
font-family: "SF Pro Text";
font-weight: bold;
font-size: 14px;
&-light{
height: $session-margin-sm;
width: $session-margin-sm;
border-radius: 50%;
background-color: $session-color-danger-alt;
margin-left: $session-margin-sm;
}
}
}

@ -1,5 +1,5 @@
import React from 'react';
import moment from 'moment';
import { SessionIconButton, SessionIconSize, SessionIconType } from '../icon';
import { SessionButton, SessionButtonType, SessionButtonColor } from '../SessionButton';
@ -17,6 +17,9 @@ interface State {
actionHover: boolean;
mediaSetting?: boolean;
volumeArray?: Array<number>;
startTimestamp: number;
nowTimestamp: number;
updateTimerInterval: NodeJS.Timeout;
}
export class SessionRecording extends React.Component<Props, State> {
@ -26,15 +29,6 @@ export class SessionRecording extends React.Component<Props, State> {
constructor(props: any) {
super(props);
this.state = {
recordDuration: 0,
isRecording: true,
isPaused: false,
actionHover: false,
mediaSetting: undefined,
volumeArray: undefined,
};
this.handleHoverActions = this.handleHoverActions.bind(this);
this.handleUnhoverActions = this.handleUnhoverActions.bind(this);
@ -44,25 +38,52 @@ export class SessionRecording extends React.Component<Props, State> {
this.onSendVoiceMessage = this.onSendVoiceMessage.bind(this);
this.onDeleteVoiceMessage = this.onDeleteVoiceMessage.bind(this);
this.timerUpdate = this.timerUpdate.bind(this);
this.onStream = this.onStream.bind(this);
this.visualisationRef = React.createRef();
this.visualisationCanvas = React.createRef();
const now = moment().unix();
const updateTimerInterval = setInterval(this.timerUpdate, 1000);
this.state = {
recordDuration: 0,
isRecording: true,
isPaused: false,
actionHover: false,
mediaSetting: undefined,
volumeArray: undefined,
startTimestamp: now,
nowTimestamp: now,
updateTimerInterval: updateTimerInterval,
};
}
public async componentWillMount(){
// This turns on the microphone on the system. Later we need to turn it off.
this.initiateStream();
}
public componentWillUnmount(){
clearInterval(this.state.updateTimerInterval);
}
render() {
const actionPause = (this.state.actionHover && this.state.isRecording);
const actionPlay = (!this.state.isRecording || this.state.isPaused);
const actionDefault = !actionPause && !actionPlay;
const { isRecording, startTimestamp, nowTimestamp } = this.state;
const elapsedTime = nowTimestamp - startTimestamp;
const displayTimeString = moment(elapsedTime).format('mm:ss');
console.log(`[vince][time] Elapsed time: `, this.state.nowTimestamp - this.state.startTimestamp);
console.log(`[vince][time] Elapsed time calculated: `, elapsedTime);
return (
<div className="session-recording">
@ -104,23 +125,43 @@ export class SessionRecording extends React.Component<Props, State> {
</div>
<div className="send-message-button">
<SessionIconButton
iconType={SessionIconType.Send}
iconSize={SessionIconSize.Large}
iconColor={'#FFFFFF'}
iconRotation={90}
onClick={this.onSendVoiceMessage}
/>
</div>
{ isRecording ? (
<div className="session-recording--timer">
{ displayTimeString }
<div className="session-recording--timer-light">
</div>
</div>
) : (
<div className="send-message-button">
<SessionIconButton
iconType={SessionIconType.Send}
iconSize={SessionIconSize.Large}
iconColor={'#FFFFFF'}
iconRotation={90}
onClick={this.onSendVoiceMessage}
/>
</div>
)}
<div className="session-recording--delete">
<SessionButton
text={window.i18n('delete')}
<div className="session-recording--status">
{ isRecording ? (
<SessionButton
text={window.i18n('recording')}
buttonType={SessionButtonType.Brand}
buttonColor={SessionButtonColor.DangerAlt}
onClick={this.onDeleteVoiceMessage}
/>
buttonColor={SessionButtonColor.Primary}
/>
) : (
<SessionButton
text={window.i18n('delete')}
buttonType={SessionButtonType.Brand}
buttonColor={SessionButtonColor.DangerAlt}
onClick={this.onDeleteVoiceMessage}
/>
)}
</div>
</div>
);
@ -140,6 +181,12 @@ export class SessionRecording extends React.Component<Props, State> {
}
}
private timerUpdate(){
this.setState({
nowTimestamp: moment().unix()
});
}
private handleUnhoverActions() {
if (this.state.isRecording && this.state.actionHover) {
this.setState({
@ -245,7 +292,6 @@ export class SessionRecording extends React.Component<Props, State> {
// Chop off values which exceed the bouinds of the container
volumeArray = volumeArray.slice(0, numBars);
console.log(`[vince][mic] Width: `, VISUALISATION_WIDTH);
canvas && (canvas.height = CANVAS_HEIGHT);
canvas && (canvas.width = CANVAS_WIDTH);
@ -286,6 +332,8 @@ export class SessionRecording extends React.Component<Props, State> {
}
private onStreamError(error: any) {
return error;
}
@ -306,4 +354,3 @@ export class SessionRecording extends React.Component<Props, State> {
}

@ -281,6 +281,13 @@
resolved "https://registry.yarnpkg.com/@types/mocha/-/mocha-5.0.0.tgz#a3014921991066193f6c8e47290d4d598dfd19e6"
integrity sha512-ZS0vBV7Jn5Z/Q4T3VXauEKMDCV8nWOtJJg90OsDylkYJiQwcWtKuLzohWzrthBkerUF7DLMmJcwOPEP0i/AOXw==
"@types/moment@^2.13.0":
version "2.13.0"
resolved "https://registry.yarnpkg.com/@types/moment/-/moment-2.13.0.tgz#604ebd189bc3bc34a1548689404e61a2a4aac896"
integrity sha1-YE69GJvDvDShVIaJQE5hoqSqyJY=
dependencies:
moment "*"
"@types/node@*":
version "13.1.6"
resolved "https://registry.yarnpkg.com/@types/node/-/node-13.1.6.tgz#076028d0b0400be8105b89a0a55550c86684ffec"
@ -6609,16 +6616,16 @@ modify-filename@^1.1.0:
resolved "https://registry.yarnpkg.com/modify-filename/-/modify-filename-1.1.0.tgz#9a2dec83806fbb2d975f22beec859ca26b393aa1"
integrity sha1-mi3sg4Bvuy2XXyK+7IWcoms5OqE=
moment@*, moment@^2.10.6:
version "2.24.0"
resolved "https://registry.yarnpkg.com/moment/-/moment-2.24.0.tgz#0d055d53f5052aa653c9f6eb68bb5d12bf5c2b5b"
integrity sha512-bV7f+6l2QigeBBZSM/6yTNq4P2fNpSWj/0e7jQcy87A8e7o2nAfP/34/2ky5Vw4B9S446EtIhodAzkFCcR4dQg==
moment@2.21.0:
version "2.21.0"
resolved "https://registry.yarnpkg.com/moment/-/moment-2.21.0.tgz#2a114b51d2a6ec9e6d83cf803f838a878d8a023a"
integrity sha512-TCZ36BjURTeFTM/CwRcViQlfkMvL1/vFISuNLO5GkcVm1+QHfbSiNqZuWeMFjj1/3+uAjXswgRk30j1kkLYJBQ==
moment@^2.10.6:
version "2.24.0"
resolved "https://registry.yarnpkg.com/moment/-/moment-2.24.0.tgz#0d055d53f5052aa653c9f6eb68bb5d12bf5c2b5b"
integrity sha512-bV7f+6l2QigeBBZSM/6yTNq4P2fNpSWj/0e7jQcy87A8e7o2nAfP/34/2ky5Vw4B9S446EtIhodAzkFCcR4dQg==
move-concurrently@^1.0.1:
version "1.0.1"
resolved "https://registry.yarnpkg.com/move-concurrently/-/move-concurrently-1.0.1.tgz#be2c005fda32e0b29af1f05d7c4b33214c701f92"

Loading…
Cancel
Save