diff --git a/app/assets/javascripts/components/components/attachment_list.jsx b/app/assets/javascripts/components/components/attachment_list.jsx new file mode 100644 index 000000000..56238fe19 --- /dev/null +++ b/app/assets/javascripts/components/components/attachment_list.jsx @@ -0,0 +1,34 @@ +import ImmutablePropTypes from 'react-immutable-proptypes'; +import PureRenderMixin from 'react-addons-pure-render-mixin'; + +const filename = url => url.split('/').pop().split('#')[0].split('?')[0]; + +const AttachmentList = React.createClass({ + propTypes: { + media: ImmutablePropTypes.list.isRequired + }, + + mixins: [PureRenderMixin], + + render () { + const { media } = this.props; + + return ( +
+
+ +
+ + +
+ ); + } +}); + +export default AttachmentList; diff --git a/app/assets/javascripts/components/components/status.jsx b/app/assets/javascripts/components/components/status.jsx index abc123f26..a5b9ad87c 100644 --- a/app/assets/javascripts/components/components/status.jsx +++ b/app/assets/javascripts/components/components/status.jsx @@ -5,6 +5,7 @@ import PureRenderMixin from 'react-addons-pure-render-mixin'; import DisplayName from './display_name'; import MediaGallery from './media_gallery'; import VideoPlayer from './video_player'; +import AttachmentList from './attachment_list'; import StatusContent from './status_content'; import StatusActionBar from './status_action_bar'; import { FormattedMessage } from 'react-intl'; @@ -77,7 +78,9 @@ const Status = React.createClass({ } if (status.get('media_attachments').size > 0 && !this.props.muted) { - if (status.getIn(['media_attachments', 0, 'type']) === 'video') { + if (status.get('media_attachments').some(item => item.get('type') === 'unknown')) { + + } else if (status.getIn(['media_attachments', 0, 'type']) === 'video') { media = ; } else { media = ; diff --git a/app/assets/javascripts/components/features/status/components/detailed_status.jsx b/app/assets/javascripts/components/features/status/components/detailed_status.jsx index 9d854f0d3..620af36fe 100644 --- a/app/assets/javascripts/components/features/status/components/detailed_status.jsx +++ b/app/assets/javascripts/components/features/status/components/detailed_status.jsx @@ -5,6 +5,7 @@ import DisplayName from '../../../components/display_name'; import StatusContent from '../../../components/status_content'; import MediaGallery from '../../../components/media_gallery'; import VideoPlayer from '../../../components/video_player'; +import AttachmentList from '../../../components/attachment_list'; import { Link } from 'react-router'; import { FormattedDate, FormattedNumber } from 'react-intl'; import CardContainer from '../containers/card_container'; @@ -40,7 +41,9 @@ const DetailedStatus = React.createClass({ let applicationLink = ''; if (status.get('media_attachments').size > 0) { - if (status.getIn(['media_attachments', 0, 'type']) === 'video') { + if (status.get('media_attachments').some(item => item.get('type') === 'unknown')) { + media = ; + } else if (status.getIn(['media_attachments', 0, 'type']) === 'video') { media = ; } else { media = ; diff --git a/app/assets/stylesheets/components.scss b/app/assets/stylesheets/components.scss index b646b0c77..76a67d8e7 100644 --- a/app/assets/stylesheets/components.scss +++ b/app/assets/stylesheets/components.scss @@ -2346,3 +2346,53 @@ button.icon-button.active i.fa-retweet { } } } + +.attachment-list { + display: flex; + font-size: 14px; + border: 1px solid lighten($color1, 8%); + border-radius: 4px; + margin-top: 14px; + overflow: hidden; +} + +.attachment-list__icon { + flex: 0 0 auto; + color: lighten($color1, 26%); + padding: 8px 18px; + cursor: default; + border-right: 1px solid lighten($color1, 8%); + display: flex; + flex-direction: column; + align-items: center; + justify-content: center; + font-size: 26px; + + .fa { + display: block; + } +} + +.attachment-list__list { + list-style: none; + padding: 4px 0; + padding-left: 8px; + display: flex; + flex-direction: column; + justify-content: center; + + li { + display: block; + padding: 4px 0; + } + + a { + text-decoration: none; + color: lighten($color1, 26%); + font-weight: 500; + + &:hover { + text-decoration: underline; + } + } +} diff --git a/app/models/media_attachment.rb b/app/models/media_attachment.rb index ec1808790..bb16adb5b 100644 --- a/app/models/media_attachment.rb +++ b/app/models/media_attachment.rb @@ -3,7 +3,7 @@ class MediaAttachment < ApplicationRecord self.inheritance_column = nil - enum type: [:image, :gifv, :video] + enum type: [:image, :gifv, :video, :unknown] IMAGE_MIME_TYPES = ['image/jpeg', 'image/png', 'image/gif'].freeze VIDEO_MIME_TYPES = ['video/webm', 'video/mp4'].freeze @@ -95,6 +95,8 @@ class MediaAttachment < ApplicationRecord private def set_shortcode + self.type = :unknown if file.blank? && type.blank? + return unless local? loop do @@ -104,9 +106,10 @@ class MediaAttachment < ApplicationRecord end def set_type_and_extension - self.type = VIDEO_MIME_TYPES.include?(file_content_type) ? :video : :image - - unless file.blank? + if file.blank? + self.type = :unknown + else + self.type = VIDEO_MIME_TYPES.include?(file_content_type) ? :video : :image extension = Paperclip::Interpolations.content_type_extension(file, :original) basename = Paperclip::Interpolations.basename(file, :original) file.instance_write :file_name, [basename, extension].delete_if(&:empty?).join('.')