Attachment list for uncached attachments (#2110)
* For undownloaded attachments, set type :unknown, display them as a list in the web UI * Fix case when attachment type is set explicitly
This commit is contained in:
		
							parent
							
								
									5ce8a1811a
								
							
						
					
					
						commit
						bfbc2ca0d8
					
				
					 5 changed files with 99 additions and 6 deletions
				
			
		| 
						 | 
				
			
			@ -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 (
 | 
			
		||||
      <div className='attachment-list'>
 | 
			
		||||
        <div className='attachment-list__icon'>
 | 
			
		||||
          <i className='fa fa-link' />
 | 
			
		||||
        </div>
 | 
			
		||||
 | 
			
		||||
        <ul className='attachment-list__list'>
 | 
			
		||||
          {media.map(attachment =>
 | 
			
		||||
            <li key={attachment.get('id')}>
 | 
			
		||||
              <a href={attachment.get('remote_url')} target='_blank' rel='noopener'>{filename(attachment.get('remote_url'))}</a>
 | 
			
		||||
            </li>
 | 
			
		||||
          )}
 | 
			
		||||
        </ul>
 | 
			
		||||
      </div>
 | 
			
		||||
    );
 | 
			
		||||
  }
 | 
			
		||||
});
 | 
			
		||||
 | 
			
		||||
export default AttachmentList;
 | 
			
		||||
| 
						 | 
				
			
			@ -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 = <VideoPlayer media={status.getIn(['media_attachments', 0])} sensitive={status.get('sensitive')} onOpenVideo={this.props.onOpenVideo} />;
 | 
			
		||||
      } else {
 | 
			
		||||
        media = <MediaGallery media={status.get('media_attachments')} sensitive={status.get('sensitive')} height={110} onOpenMedia={this.props.onOpenMedia} autoPlayGif={this.props.autoPlayGif} />;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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 = <AttachmentList media={status.get('media_attachments')} />;
 | 
			
		||||
      } else if (status.getIn(['media_attachments', 0, 'type']) === 'video') {
 | 
			
		||||
        media = <VideoPlayer sensitive={status.get('sensitive')} media={status.getIn(['media_attachments', 0])} width={300} height={150} onOpenVideo={this.props.onOpenVideo} autoplay />;
 | 
			
		||||
      } else {
 | 
			
		||||
        media = <MediaGallery sensitive={status.get('sensitive')} media={status.get('media_attachments')} height={300} onOpenMedia={this.props.onOpenMedia} autoPlayGif={this.props.autoPlayGif} />;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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;
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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
 | 
			
		||||
    if file.blank?
 | 
			
		||||
      self.type = :unknown
 | 
			
		||||
    else
 | 
			
		||||
      self.type = VIDEO_MIME_TYPES.include?(file_content_type) ? :video : :image
 | 
			
		||||
 | 
			
		||||
    unless file.blank?
 | 
			
		||||
      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('.')
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		
		Reference in a new issue