video works although may have bugs

This commit is contained in:
or-else
2022-12-14 16:50:00 -08:00
parent 830d15f7ec
commit 8c3287941a
10 changed files with 229 additions and 67 deletions
+22 -6
View File
@@ -23,7 +23,8 @@ class BaseChatMessage extends React.PureComponent {
props.uploader.onProgress = this.handleProgress.bind(this);
}
this.handleImagePreview = this.handleImagePreview.bind(this);
this.handleExpandImage = this.handleExpandImage.bind(this);
this.handlePlayVideo = this.handlePlayVideo.bind(this);
this.handleFormButtonClick = this.handleFormButtonClick.bind(this);
this.handleContextClick = this.handleContextClick.bind(this);
this.handleCancelUpload = this.handleCancelUpload.bind(this);
@@ -34,18 +35,18 @@ class BaseChatMessage extends React.PureComponent {
viewportWidth: props.viewportWidth,
authorizeURL: props.tinode.authorizeURL.bind(props.tinode),
onImagePreview: this.handleImagePreview,
onVideoPreview: this.handleImagePreview,
onImagePreview: this.handleExpandImage,
onVideoPreview: this.handlePlayVideo,
onFormButtonClick: this.handleFormButtonClick,
onQuoteClick: this.handleQuoteClick
};
}
handleImagePreview(e) {
handleExpandImage(e) {
e.preventDefault();
this.props.onImagePreview({
this.props.onExpandMedia({
url: e.target.src,
filename: e.target.title,
filename: e.target.dataset.name,
width: e.target.dataset.width,
height: e.target.dataset.height,
size: e.target.dataset.size,
@@ -53,6 +54,21 @@ class BaseChatMessage extends React.PureComponent {
});
}
handlePlayVideo(e) {
e.preventDefault();
this.props.onExpandMedia({
video: true,
url: e.target.dataset.src,
preview: e.target.src,
filename: e.target.dataset.name,
width: e.target.dataset.width,
height: e.target.dataset.height,
duration: e.target.dataset.duration,
size: e.target.dataset.size,
type: e.target.dataset.mime
});
}
handleFormButtonClick(e) {
e.preventDefault();
const data = {
+7 -7
View File
@@ -47,25 +47,25 @@ export default class ImagePreview extends React.PureComponent {
// Average font aspect ratio is ~0.5; File name takes 1/3 of the viewport width.
const maxlength = Math.max(((this.state.width / REM_SIZE / 1.5) | 0) - 2, 12);
const fname = shortenFileName(this.props.content.name, maxlength) || '-';
const fname = shortenFileName(this.props.content.filename, maxlength) || '-';
const width = this.props.content.width || '-';
const height = this.props.content.height || '-';
return (
<div id="image-preview">
<div id="image-preview-caption-panel">
{!this.props.onSendMessage ?
<a href={this.props.content.url} download={true}>
{this.props.onSendMessage ?
<span>{fname}</span>
:
<a href={this.props.content.url} download={this.props.content.filename}>
<i className="material-icons">file_download</i> <FormattedMessage
id="download_action" defaultMessage="download" description="Call to action [download]" />
</a>
:
<span>{fname}</span>
}
<a href="#" onClick={(e) => {e.preventDefault(); this.props.onClose();}}><i className="material-icons gray">close</i></a>
</div>
<div id="image-preview-container" ref={(node) => this.assignWidth(node)}>
<img src={this.props.content.url} style={size} className="image-preview" alt={this.props.content.name} />
<img src={this.props.content.url} style={size} className="image-preview" alt={this.props.content.filename} />
</div>
{this.props.onSendMessage ?
<SendMessage
@@ -81,7 +81,7 @@ export default class ImagePreview extends React.PureComponent {
<div>
<div><b><FormattedMessage id="label_file_name" defaultMessage="File name:"
description="Label for a file name" /></b></div>
<div><span title={this.props.content.name}>{fname}</span></div>
<div><span title={this.props.content.filename}>{fname}</span></div>
</div>
<div>
<div><b><FormattedMessage id="label_content_type" defaultMessage="Content type:"
+14 -2
View File
@@ -8,15 +8,27 @@ import { secondsToTime } from '../lib/strformat.js'
export default class InlineVideo extends React.PureComponent {
constructor(props) {
super(props);
this.videoRef = React.createRef();
this.handleClick = this.handleClick.bind(this);
}
handleClick(e) {
if (this.props.onClick) {
// the click target has to be the image element.
this.props.onClick(e);
}
}
render() {
const duration = secondsToTime(this.props['data-duration'] / 1000);
const className = 'inline-video' + (this.props.onClick ? ' clickable' : '');
return (
<div className="inline-video">
<div className={className}>
{React.createElement('img', this.props)}
{this.props.onClick ?
<div className="play-control" onClick={this.props.onClick}>
<div className="play-control">
<i className="material-icons white bigger">play_arrow</i>
</div>
: null}
+36 -3
View File
@@ -1,6 +1,9 @@
import React from 'react';
import { FormattedMessage } from 'react-intl';
import SendMessage from './send-message.jsx';
import { bytesToHumanSize } from '../lib/strformat.js';
export default class VideoPreview extends React.PureComponent {
constructor(props) {
super(props);
@@ -17,7 +20,7 @@ export default class VideoPreview extends React.PureComponent {
height: this.videoRef.current.videoHeight,
duration: (this.videoRef.current.duration * 1000) | 0,
mime: this.props.content.mime,
name: this.props.content.name
name: this.props.content.filename
}
// Capture screen from a video.
@@ -37,15 +40,27 @@ export default class VideoPreview extends React.PureComponent {
return null;
}
const width = this.props.content.width || '-';
const height = this.props.content.height || '-';
const controlist = this.props.onSendMessage ? 'nodownload' : '';
return (
<div id="image-preview">
<div id="image-preview-caption-panel">
<span>{this.props.content.name}</span>
<span>{this.props.content.filename}</span>
<a href="#" onClick={e => {e.preventDefault(); this.props.onClose();}}><i className="material-icons gray">close</i></a>
</div>
<div id="image-preview-container">
<video controls ref={this.videoRef} src={this.props.content.url} className="image-preview" alt={this.props.content.name} />
<video
className="image-preview"
controls controlist={controlist}
disablePictureInPicture ref={this.videoRef}
src={this.props.tinode.authorizeURL(this.props.content.url)}
poster={this.props.content.preview}
alt={this.props.content.filename} />
</div>
{this.props.onSendMessage ?
<SendMessage
messagePrompt="add_image_caption"
acceptBlank={true}
@@ -54,6 +69,24 @@ export default class VideoPreview extends React.PureComponent {
onCancelReply={this.props.onCancelReply}
onSendMessage={this.handleSendVideo}
onError={this.props.onError} />
:
<div id="image-preview-footer">
<div>
<div><b><FormattedMessage id="label_file_name" defaultMessage="File name:"
description="Label for a file name" /></b></div>
<div><span title={this.props.content.filename}>{this.props.content.filename}</span></div>
</div>
<div>
<div><b><FormattedMessage id="label_content_type" defaultMessage="Content type:"
description="Label for file content type (mime)" /></b></div>
<div>{this.props.content.type}</div>
</div>
<div>
<div><b><FormattedMessage id="label_size" defaultMessage="Size:"
description="Label for file size" /></b></div>
<div>{width} &times; {height} px; {bytesToHumanSize(this.props.content.size)}</div>
</div>
</div>}
</div>
);
}