Skip to content
Extraits de code Groupes Projets
Valider 80c44ed9 rédigé par Eugen Rochko's avatar Eugen Rochko
Parcourir les fichiers

Do not autoplay videos, display play button instead. Use expiring links when...

Do not autoplay videos, display play button instead. Use expiring links when using S3. Do not keep originals
for avatars/headers, resize avatars down to 120x120 instead of 300x300. Set cache headers on S3 stuff, also
make it private (aka only accessible via expiring links to prevent hotlinking)
parent 290ffb63
Aucune branche associée trouvée
Aucune étiquette associée trouvée
Aucune requête de fusion associée trouvée
Affichage de
avec 34 ajouts et 27 suppressions
......@@ -53,7 +53,8 @@ const VideoPlayer = React.createClass({
propTypes: {
media: ImmutablePropTypes.map.isRequired,
width: React.PropTypes.number,
height: React.PropTypes.number
height: React.PropTypes.number,
sensitive: React.PropTypes.bool
},
getDefaultProps () {
......@@ -102,6 +103,12 @@ const VideoPlayer = React.createClass({
<span style={spoilerSubSpanStyle}><FormattedMessage id='status.sensitive_toggle' defaultMessage='Click to view' /></span>
</div>
);
} else if (!sensitive && !this.state.visible) {
return (
<div style={{ cursor: 'pointer', position: 'relative', marginTop: '8px', width: `${width}px`, height: `${height}px`, background: `url(${media.get('preview_url')}) no-repeat center`, backgroundSize: 'cover' }} onClick={this.handleOpen}>
<div style={{ position: 'absolute', top: '50%', left: '50%', fontSize: '36px', transform: 'translate(-50%, -50%)', padding: '5px', borderRadius: '100px', color: 'rgba(255, 255, 255, 0.8)' }}><i className='fa fa-play' /></div>
</div>
);
}
return (
......
......@@ -112,13 +112,11 @@ module AtomBuilderHelper
end
def link_enclosure(xml, media)
xml.link(rel: 'enclosure', href: full_asset_url(media.file.url), type: media.file_content_type, length: media.file_file_size)
xml.link(rel: 'enclosure', href: full_asset_url(media.file.url(:original, false)), type: media.file_content_type, length: media.file_file_size)
end
def link_avatar(xml, account)
single_link_avatar(xml, account, :large, 300)
# single_link_avatar(xml, account, :medium, 96)
# single_link_avatar(xml, account, :small, 48)
single_link_avatar(xml, account, :original, 120)
end
def logo(xml, url)
......
......@@ -6,7 +6,7 @@ module StreamEntriesHelper
end
def avatar_for_status_url(status)
status.reblog? ? status.reblog.account.avatar.url(:large) : status.account.avatar.url(:large)
status.reblog? ? status.reblog.account.avatar.expiring_url(3600, :original) : status.account.avatar.expiring_url(3600, :original)
end
def entry_classes(status, is_predecessor, is_successor, include_threads)
......
......@@ -13,12 +13,12 @@ class Account < ApplicationRecord
validates :username, presence: true, uniqueness: { scope: :domain, case_sensitive: true }, unless: 'local?'
# Avatar upload
has_attached_file :avatar, styles: { large: '300x300#' }, convert_options: { all: '-strip' }
has_attached_file :avatar, styles: { original: '120x120#' }, convert_options: { all: '-quality 80 -strip' }
validates_attachment_content_type :avatar, content_type: IMAGE_MIME_TYPES
validates_attachment_size :avatar, less_than: 2.megabytes
# Header upload
has_attached_file :header, styles: { medium: '700x335#' }, convert_options: { all: '-strip' }
has_attached_file :header, styles: { original: '700x335#' }, convert_options: { all: '-quality 80 -strip' }
validates_attachment_content_type :header, content_type: IMAGE_MIME_TYPES
validates_attachment_size :header, less_than: 2.megabytes
......
......@@ -10,7 +10,7 @@ class MediaAttachment < ApplicationRecord
has_attached_file :file,
styles: -> (f) { file_styles f },
processors: -> (f) { f.video? ? [:transcoder] : [:thumbnail] },
convert_options: { all: '-strip' }
convert_options: { all: '-quality 80 -strip' }
validates_attachment_content_type :file, content_type: IMAGE_MIME_TYPES + VIDEO_MIME_TYPES
validates_attachment_size :file, less_than: 4.megabytes
......
.account-grid-card
.account-grid-card__header
.avatar= image_tag account.avatar.url(:medium)
.avatar= image_tag account.avatar.expiring_url(3600, :original)
.name
= link_to TagManager.instance.url_for(account) do
%span.display_name= display_name(account)
......
.card{ style: "background-image: url(#{@account.header.url(:medium)})" }
.card{ style: "background-image: url(#{@account.header.expiring_url(3600, :original)})" }
- if user_signed_in? && current_account.id != @account.id
.controls
- if current_account.following?(@account)
......@@ -6,7 +6,7 @@
- else
= link_to t('accounts.follow'), follow_account_path(@account), data: { method: :post }, class: 'button'
.avatar= image_tag @account.avatar.url(:large)
.avatar= image_tag @account.avatar.expiring_url(3600, :original)
%h1.name
= display_name(@account)
%small= "@#{@account.username}"
......
......@@ -6,7 +6,7 @@ Nokogiri::XML::Builder.new do |xml|
title xml, @account.display_name
subtitle xml, @account.note
updated_at xml, stream_updated_at
logo xml, full_asset_url(@account.avatar.url(:medium, false))
logo xml, full_asset_url(@account.avatar.expiring_url(3600, :original))
author(xml) do
include_author xml, @account
......
......@@ -4,8 +4,8 @@ attributes :id, :username, :acct, :display_name
node(:note) { |account| Formatter.instance.simplified_format(account) }
node(:url) { |account| TagManager.instance.url_for(account) }
node(:avatar) { |account| full_asset_url(account.avatar.url(:large, false)) }
node(:header) { |account| full_asset_url(account.header.url(:medium, false)) }
node(:avatar) { |account| full_asset_url(account.avatar.expiring_url(3600, :original)) }
node(:header) { |account| full_asset_url(account.header.expiring_url(3600, :original)) }
node(:followers_count) { |account| defined?(@followers_counts_map) ? (@followers_counts_map[account.id] || 0) : (account.try(:followers_count) || account.followers.count) }
node(:following_count) { |account| defined?(@following_counts_map) ? (@following_counts_map[account.id] || 0) : (account.try(:following_count) || account.following.count) }
node(:statuses_count) { |account| defined?(@statuses_counts_map) ? (@statuses_counts_map[account.id] || 0) : (account.try(:statuses_count) || account.statuses.count) }
object @media
attribute :id, :type
node(:url) { |media| full_asset_url(media.file.url) }
node(:preview_url) { |media| full_asset_url(media.file.url(:small)) }
node(:url) { |media| full_asset_url(media.file.expiring_url(3600, :original)) }
node(:preview_url) { |media| full_asset_url(media.file.expiring_url(3600, :small)) }
node(:text_url) { |media| medium_url(media) }
attributes :id, :remote_url, :type
node(:url) { |media| full_asset_url(media.file.url) }
node(:preview_url) { |media| full_asset_url(media.file.url(:small)) }
node(:url) { |media| full_asset_url(media.file.expiring_url(3600, :original)) }
node(:preview_url) { |media| full_asset_url(media.file.expiring_url(3600, :small)) }
......@@ -34,7 +34,7 @@
- if (status.reblog? ? status.reblog : status).media_attachments.size > 0
%ul.media-attachments
- (status.reblog? ? status.reblog : status).media_attachments.each do |media|
%li.transparent-background= link_to '', media.file.url, style: "background-image: url(#{media.file.url(:small)})", target: '_blank'
%li.transparent-background= link_to '', media.file.expiring_url(3600, :original), style: "background-image: url(#{media.file.expiring_url(3600, :small)})", target: '_blank'
- if include_threads
= render partial: 'status', collection: @descendants, as: :status, locals: { is_successor: true }
......@@ -7,7 +7,7 @@
%meta{ name: 'og:title', content: "#{@account.username} on #{Rails.configuration.x.local_domain}" }/
%meta{ name: 'og:article:author', content: @account.username }/
%meta{ name: 'og:description', content: @stream_entry.activity.content }/
%meta{ name: 'og:image', content: @stream_entry.activity.is_a?(Status) && @stream_entry.activity.media_attachments.size > 0 ? full_asset_url(@stream_entry.activity.media_attachments.first.file.url(:small)) : full_asset_url(@account.avatar.url(:large)) }/
%meta{ name: 'og:image', content: @stream_entry.activity.is_a?(Status) && @stream_entry.activity.media_attachments.size > 0 ? full_asset_url(@stream_entry.activity.media_attachments.first.file.expiring_url(3600, :small)) : full_asset_url(@account.avatar.expiring_url(3600, :original)) }/
.activity-stream.activity-stream-headless
= render partial: @type, locals: { @type.to_sym => @stream_entry.activity, include_threads: true }
if ENV['S3_ENABLED'] == 'true'
Aws.eager_autoload!(services: %w(S3))
Paperclip::Attachment.default_options[:storage] = :s3
Paperclip::Attachment.default_options[:s3_protocol] = 'https'
Paperclip::Attachment.default_options[:url] = ':s3_domain_url'
Paperclip::Attachment.default_options[:s3_host_name] = "s3-#{ENV.fetch('S3_REGION')}.amazonaws.com"
Paperclip::Attachment.default_options[:path] = '/:class/:attachment/:id_partition/:style/:filename'
Paperclip::Attachment.default_options[:storage] = :s3
Paperclip::Attachment.default_options[:s3_protocol] = 'https'
Paperclip::Attachment.default_options[:url] = ':s3_domain_url'
Paperclip::Attachment.default_options[:s3_host_name] = "s3-#{ENV.fetch('S3_REGION')}.amazonaws.com"
Paperclip::Attachment.default_options[:path] = '/:class/:attachment/:id_partition/:style/:filename'
Paperclip::Attachment.default_options[:s3_headers] = { 'Cache-Control' => 'max-age=315576000', 'Expires' => 10.years.from_now.httpdate }
Paperclip::Attachment.default_options[:s3_permissions] = :private
unless ENV['S3_CLOUDFRONT_HOST'].blank?
Paperclip::Attachment.default_options[:url] = ':s3_alias_url'
......
public/avatars/medium/missing.png

1,03 ko

Fichier déplacé
public/avatars/small/missing.png

681 octets

......@@ -162,7 +162,7 @@ RSpec.describe AtomBuilderHelper, type: :helper do
let(:account) { Fabricate(:account, username: 'alice') }
it 'creates a link' do
expect(used_with_namespaces { |xml| helper.link_avatar(xml, account) }).to match '<link rel="avatar" type="" media:width="300" media:height="300" href="http://test.host/avatars/large/missing.png"/>'
expect(used_with_namespaces { |xml| helper.link_avatar(xml, account) }).to match '<link rel="avatar" type="" media:width="120" media:height="120" href="http://test.host/avatars/original/missing.png"/>'
end
end
......
0% Chargement en cours ou .
You are about to add 0 people to the discussion. Proceed with caution.
Terminez d'abord l'édition de ce message.
Veuillez vous inscrire ou vous pour commenter