This commit is contained in:
or-else
2022-12-07 19:17:18 -08:00
parent 563f82d265
commit 7731c6700b
49 changed files with 750 additions and 78 deletions
+13 -2
View File
@@ -1,6 +1,7 @@
// Audio recorder widget.
import React from 'react';
import { defineMessages, injectIntl } from 'react-intl';
import { secondsToTime } from '../lib/strformat';
import { base64ToIntArray } from '../lib/blob-helpers';
@@ -18,7 +19,15 @@ const THUMB_COLOR = '#444E';
// Minimum number of amplitude bars to draw.
const MIN_PREVIEW_LENGTH = 16;
export default class AudioPlayer extends React.PureComponent {
const messages = defineMessages({
icon_title_play: {
id: 'icon_title_play',
defaultMessage: 'Play recording',
description: 'Icon tool tip for starting audio playback'
}
});
class AudioPlayer extends React.PureComponent {
constructor(props) {
super(props);
@@ -237,7 +246,7 @@ export default class AudioPlayer extends React.PureComponent {
const playClass = 'material-icons' +
(this.props.short ? '' : ' large') +
(this.state.canPlay ? '' : ' disabled');
const play = (<a href="#" onClick={this.handlePlay} title="Play">
const play = (<a href="#" onClick={this.handlePlay} title={this.props.intl.formatMessage(messages.icon_title_play)}>
<i className={playClass}>{this.state.playing ? 'pause_circle' :
(this.state.canPlay ? 'play_circle' : 'not_interested')}</i>
</a>);
@@ -258,3 +267,5 @@ export default class AudioPlayer extends React.PureComponent {
</div>);
}
}
export default injectIntl(AudioPlayer);
+32 -5
View File
@@ -1,6 +1,7 @@
// Audio recorder widget.
import React from 'react';
import { defineMessages, injectIntl } from 'react-intl';
import AudioPlayer from './audio-player.jsx';
// Workaround for https://bugs.chromium.org/p/chromium/issues/detail?id=642012
@@ -33,7 +34,30 @@ const MAX_SAMPLES_PER_BAR = 10;
// Recording format.
const AUDIO_MIME_TYPE = 'audio/webm';
export default class AudioRecorder extends React.PureComponent {
const messages = defineMessages({
icon_title_delete: {
id: 'icon_title_delete',
defaultMessage: 'Delete recording',
description: 'Icon tool tip for deleting recorded audio'
},
icon_title_pause: {
id: 'icon_title_pause',
defaultMessage: 'Pause playback',
description: 'Icon tool tip for pausing audio playback'
},
icon_title_resume: {
id: 'icon_title_resume',
defaultMessage: 'Resume playback',
description: 'Icon tool tip for resuming audio playback'
},
icon_title_send: {
id: 'icon_title_send',
defaultMessage: 'Send message',
description: 'Icon tool tip for sending a message'
},
});
class AudioRecorder extends React.PureComponent {
constructor(props) {
super(props);
@@ -315,10 +339,11 @@ export default class AudioRecorder extends React.PureComponent {
}
render() {
const {formatMessage} = this.props.intl;
const resumeClass = 'material-icons ' + (this.state.enabled ? 'red' : 'gray');
return (
<div className="audio">
<a href="#" onClick={this.handleDelete} title="Delete">
<a href="#" onClick={this.handleDelete} title={formatMessage(messages.icon_title_delete)}>
<i className="material-icons gray">delete_outline</i>
</a>
{this.state.recording ?
@@ -332,17 +357,19 @@ export default class AudioRecorder extends React.PureComponent {
}
<div className="duration">{this.state.duration}</div>
{this.state.recording ?
<a href="#" onClick={this.handlePause} title="Pause">
<a href="#" onClick={this.handlePause} title={formatMessage(messages.icon_title_pause)}>
<i className="material-icons">pause_circle_outline</i>
</a> :
<a href="#" onClick={this.handleResume} title="Resume">
<a href="#" onClick={this.handleResume} title={formatMessage(messages.icon_title_resume)}>
<i className={resumeClass}>radio_button_checked</i>
</a>
}
<a href="#" onClick={this.handleDone} title="Send">
<a href="#" onClick={this.handleDone} title={formatMessage(messages.icon_title_send)}>
<i className="material-icons">send</i>
</a>
</div>
);
}
}
export default injectIntl(AudioRecorder);
+24 -4
View File
@@ -37,6 +37,26 @@ const messages = defineMessages({
defaultMessage: 'Cannot initiate file upload.',
description: 'Generic error messagewhen attachment fails'
},
icon_title_record_voice: {
id: 'icon_title_record_voice',
defaultMessage: 'Record voice message',
description: 'Icon tool tip for recording a voice message'
},
icon_title_attach_file: {
id: 'icon_title_attach_file',
defaultMessage: 'Attach file',
description: 'Icon tool tip for attaching a file'
},
icon_title_add_image: {
id: 'icon_title_add_image',
defaultMessage: 'Add image',
description: 'Icon tool tip for attaching an image'
},
icon_title_send: {
id: 'icon_title_send',
defaultMessage: 'Send message',
description: 'Icon tool tip for sending a message'
},
});
class SendMessage extends React.PureComponent {
@@ -221,10 +241,10 @@ class SendMessage extends React.PureComponent {
<>
{this.props.onAttachFile && !this.state.audioRec ?
<>
<a href="#" onClick={e => {e.preventDefault(); this.attachImage.click();}} title="Add image">
<a href="#" onClick={e => {e.preventDefault(); this.attachImage.click();}} title={formatMessage(messages.icon_title_add_image)}>
<i className="material-icons secondary">photo</i>
</a>
<a href="#" onClick={e => {e.preventDefault(); this.attachFile.click();}} title="Attach file">
<a href="#" onClick={e => {e.preventDefault(); this.attachFile.click();}} title={formatMessage(messages.icon_title_attach_file)}>
<i className="material-icons secondary">attach_file</i>
</a>
</>
@@ -245,11 +265,11 @@ class SendMessage extends React.PureComponent {
ref={(ref) => {this.messageEditArea = ref;}}
autoFocus />)}
{this.state.message || !audioEnabled ?
<a href="#" onClick={this.handleSend} title="Send">
<a href="#" onClick={this.handleSend} title={formatMessage(messages.icon_title_send)}>
<i className="material-icons">{sendIcon}</i>
</a> :
!this.state.audioRec ?
<a href="#" onClick={e => {e.preventDefault(); this.setState({audioRec: true})}} title="Voice">
<a href="#" onClick={e => {e.preventDefault(); this.setState({audioRec: true})}} title={formatMessage(messages.icon_title_record_voice)}>
<i className="material-icons">mic</i>
</a> :
null