Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Initial commit for support of video-type attachments #1430

Draft
wants to merge 1 commit into
base: stable
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
74 changes: 74 additions & 0 deletions src/components/post-attachment-video.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
import { PureComponent } from 'react';
import { faFileVideo, faPlayCircle } from '@fortawesome/free-regular-svg-icons';
import { faTimes } from '@fortawesome/free-solid-svg-icons';

import { formatFileSize } from '../utils';
import { ButtonLink } from './button-link';
import { Icon } from './fontawesome-icons';

class VideoAttachment extends PureComponent {
state = {
isOpen: false,
};

handleClickOnRemoveAttachment = () => {
this.props.removeAttachment(this.props.id);
};

toggleOpen = () => {
this.setState({ isOpen: true });
};

render() {
const { props } = this;
const { isOpen } = this.state;
const formattedFileSize = formatFileSize(props.fileSize);

const title = `${props.fileName} (${formattedFileSize})`;

const thumbnailStyle = {
width: props.imageSizes.t?.w,
height: props.imageSizes.t?.h,
backgroundImage: `url(${props.imageSizes.t?.url})`,
};

return (
<div className="attachment" role="figure" aria-label={`Video attachment ${title}`}>
{isOpen ? (
<div>
<video title={title} autoPlay controls>
<source src={props.url} />
Your browser does not support HTML5 video tag.
</video>
</div>
) : (
<ButtonLink
onClick={this.toggleOpen}
className="video-attachment-thumb"
title="Click to play video"
style={thumbnailStyle}
>
<Icon icon={faPlayCircle} className="video-attachment-click-to-play" />
</ButtonLink>
)}
<div>
<a href={props.url} title={title} target="_blank">
<Icon icon={faFileVideo} className="attachment-icon" />
<span>{title}</span>
</a>

{props.isEditing && (
<Icon
icon={faTimes}
className="remove-attachment"
title="Remove video file"
onClick={this.handleClickOnRemoveAttachment}
/>
)}
</div>
</div>
);
}
}

export default VideoAttachment;
37 changes: 34 additions & 3 deletions src/components/post-attachments.jsx
Original file line number Diff line number Diff line change
@@ -1,12 +1,29 @@
import ImageAttachmentsContainer from './post-attachment-image-container';
import AudioAttachment from './post-attachment-audio';
import GeneralAttachment from './post-attachment-general';
import VideoAttachment from './post-attachment-video';
import ErrorBoundary from './error-boundary';

export default (props) => {
const attachments = props.attachments || [];

const imageAttachments = attachments.filter((attachment) => attachment.mediaType === 'image');
const imageAttachments = [];
const audioAttachments = [];
const videoAttachments = [];
const generalAttachments = [];

attachments.forEach((attachment) => {
if (attachment.mediaType === 'image') {
imageAttachments.push(attachment);
} else if (attachment.mediaType === 'audio') {
audioAttachments.push(attachment);
} else if (attachment.mediaType === 'video') {
videoAttachments.push(attachment);
} else {
generalAttachments.push(attachment);
}
});

const imageAttachmentsContainer =
imageAttachments.length > 0 ? (
<ImageAttachmentsContainer
Expand All @@ -22,7 +39,6 @@ export default (props) => {
false
);

const audioAttachments = attachments.filter((attachment) => attachment.mediaType === 'audio');
const audioAttachmentsNodes = audioAttachments.map((attachment) => (
<AudioAttachment
key={attachment.id}
Expand All @@ -38,7 +54,21 @@ export default (props) => {
false
);

const generalAttachments = attachments.filter((attachment) => attachment.mediaType === 'general');
const videoAttachmentsNodes = videoAttachments.map((attachment) => (
<VideoAttachment
key={attachment.id}
isEditing={props.isEditing}
removeAttachment={props.removeAttachment}
{...attachment}
/>
));
const videoAttachmentsContainer =
videoAttachments.length > 0 ? (
<div className="video-attachments">{videoAttachmentsNodes}</div>
) : (
false
);

const generalAttachmentsNodes = generalAttachments.map((attachment) => (
<GeneralAttachment
key={attachment.id}
Expand All @@ -59,6 +89,7 @@ export default (props) => {
<ErrorBoundary>
{imageAttachmentsContainer}
{audioAttachmentsContainer}
{videoAttachmentsContainer}
{generalAttachmentsContainer}
</ErrorBoundary>
</div>
Expand Down
1 change: 1 addition & 0 deletions styles/shared/attachments-edit.scss
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,7 @@
}

.audio-attachments,
.video-attachments,
.general-attachments {
.attachment:hover .remove-attachment {
display: block;
Expand Down
31 changes: 31 additions & 0 deletions styles/shared/attachments.scss
Original file line number Diff line number Diff line change
Expand Up @@ -132,6 +132,7 @@
}

.audio-attachments,
.video-attachments,
.general-attachments {
.attachment {
position: relative;
Expand All @@ -149,3 +150,33 @@
}
}
}

.video-attachments {
.video-attachment-thumb {
display: flex;
width: 80px;
height: 80px;
justify-content: center;
align-items: center;
border-radius: 2px;
background-color: #000;
background-position: center;
background-repeat: no-repeat;
font-size: 2em;

&:hover {
font-size: 2.5em;
}
}

.video-attachment-click-to-play {
filter: drop-shadow(0px 0px 3px #000);
color: #fff;
}

video {
max-width: 100%;
max-height: 400px;
background-color: #eee;
}
}
9 changes: 5 additions & 4 deletions styles/shared/media-viewer.scss
Original file line number Diff line number Diff line change
Expand Up @@ -34,10 +34,11 @@
width: 100%;
height: 100%;
}
}
video {
width: 100% !important;
height: auto !important;

video {
width: 100% !important;
height: auto !important;
}
}
.media-link {
.icon-bond {
Expand Down
5 changes: 5 additions & 0 deletions test/jest-setup.js
Original file line number Diff line number Diff line change
@@ -1 +1,6 @@
require('../config/lib/loader-node');

// https://github.com/testing-library/react-testing-library/issues/470
Object.defineProperty(HTMLMediaElement.prototype, 'muted', {
set: () => {},
});
Loading