Merge commit 'a7d96e6affd4a2da65f09f3f4ffa1b9350bb9a42' into glitch-soc/merge-upstream
commit
fbbe9f1c12
|
@ -8,7 +8,15 @@ class Api::V1::Statuses::TranslationsController < Api::BaseController
|
||||||
before_action :set_translation
|
before_action :set_translation
|
||||||
|
|
||||||
rescue_from TranslationService::NotConfiguredError, with: :not_found
|
rescue_from TranslationService::NotConfiguredError, with: :not_found
|
||||||
rescue_from TranslationService::UnexpectedResponseError, TranslationService::QuotaExceededError, TranslationService::TooManyRequestsError, with: :service_unavailable
|
rescue_from TranslationService::UnexpectedResponseError, with: :service_unavailable
|
||||||
|
|
||||||
|
rescue_from TranslationService::QuotaExceededError do
|
||||||
|
render json: { error: I18n.t('translation.errors.quota_exceeded') }, status: 503
|
||||||
|
end
|
||||||
|
|
||||||
|
rescue_from TranslationService::TooManyRequestsError do
|
||||||
|
render json: { error: I18n.t('translation.errors.too_many_requests') }, status: 503
|
||||||
|
end
|
||||||
|
|
||||||
def create
|
def create
|
||||||
render json: @translation, serializer: REST::TranslationSerializer
|
render json: @translation, serializer: REST::TranslationSerializer
|
||||||
|
|
|
@ -10,8 +10,8 @@ import { groupBy, minBy } from 'lodash';
|
||||||
|
|
||||||
import { getStatusContent } from './status_content';
|
import { getStatusContent } from './status_content';
|
||||||
|
|
||||||
// About two lines on desktop
|
// Fit on a single line on desktop
|
||||||
const VISIBLE_HASHTAGS = 7;
|
const VISIBLE_HASHTAGS = 3;
|
||||||
|
|
||||||
// Those types are not correct, they need to be replaced once this part of the state is typed
|
// Those types are not correct, they need to be replaced once this part of the state is typed
|
||||||
export type TagLike = Record<{ name: string }>;
|
export type TagLike = Record<{ name: string }>;
|
||||||
|
@ -210,7 +210,7 @@ const HashtagBar: React.FC<{
|
||||||
|
|
||||||
const revealedHashtags = expanded
|
const revealedHashtags = expanded
|
||||||
? hashtags
|
? hashtags
|
||||||
: hashtags.slice(0, VISIBLE_HASHTAGS - 1);
|
: hashtags.slice(0, VISIBLE_HASHTAGS);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className='hashtag-bar'>
|
<div className='hashtag-bar'>
|
||||||
|
|
|
@ -9308,19 +9308,24 @@ noscript {
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-wrap: wrap;
|
flex-wrap: wrap;
|
||||||
font-size: 14px;
|
font-size: 14px;
|
||||||
|
line-height: 18px;
|
||||||
gap: 4px;
|
gap: 4px;
|
||||||
|
color: $darker-text-color;
|
||||||
|
|
||||||
a {
|
a {
|
||||||
display: inline-flex;
|
display: inline-flex;
|
||||||
color: $dark-text-color;
|
color: inherit;
|
||||||
text-decoration: none;
|
text-decoration: none;
|
||||||
|
|
||||||
&:hover {
|
&:hover span {
|
||||||
text-decoration: none;
|
text-decoration: underline;
|
||||||
|
|
||||||
span {
|
|
||||||
text-decoration: underline;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.link-button {
|
||||||
|
color: inherit;
|
||||||
|
font-size: inherit;
|
||||||
|
line-height: inherit;
|
||||||
|
padding: 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -44,6 +44,7 @@ class MediaAttachment < ApplicationRecord
|
||||||
|
|
||||||
MAX_VIDEO_MATRIX_LIMIT = 8_294_400 # 3840x2160px
|
MAX_VIDEO_MATRIX_LIMIT = 8_294_400 # 3840x2160px
|
||||||
MAX_VIDEO_FRAME_RATE = 120
|
MAX_VIDEO_FRAME_RATE = 120
|
||||||
|
MAX_VIDEO_FRAMES = 36_000 # Approx. 5 minutes at 120 fps
|
||||||
|
|
||||||
IMAGE_FILE_EXTENSIONS = %w(.jpg .jpeg .png .gif .webp .heic .heif .avif).freeze
|
IMAGE_FILE_EXTENSIONS = %w(.jpg .jpeg .png .gif .webp .heic .heif .avif).freeze
|
||||||
VIDEO_FILE_EXTENSIONS = %w(.webm .mp4 .m4v .mov).freeze
|
VIDEO_FILE_EXTENSIONS = %w(.webm .mp4 .m4v .mov).freeze
|
||||||
|
@ -98,17 +99,12 @@ class MediaAttachment < ApplicationRecord
|
||||||
convert_options: {
|
convert_options: {
|
||||||
output: {
|
output: {
|
||||||
'loglevel' => 'fatal',
|
'loglevel' => 'fatal',
|
||||||
'movflags' => 'faststart',
|
'preset' => 'veryfast',
|
||||||
'pix_fmt' => 'yuv420p',
|
|
||||||
'vf' => 'scale=\'trunc(iw/2)*2:trunc(ih/2)*2\'',
|
|
||||||
'vsync' => 'cfr',
|
|
||||||
'c:v' => 'h264',
|
'c:v' => 'h264',
|
||||||
'maxrate' => '1300K',
|
'c:a' => 'aac',
|
||||||
'bufsize' => '1300K',
|
'b:a' => '192k',
|
||||||
'b:v' => '1300K',
|
|
||||||
'frames:v' => 60 * 60 * 3,
|
|
||||||
'crf' => 18,
|
|
||||||
'map_metadata' => '-1',
|
'map_metadata' => '-1',
|
||||||
|
'frames:v' => MAX_VIDEO_FRAMES,
|
||||||
}.freeze,
|
}.freeze,
|
||||||
}.freeze,
|
}.freeze,
|
||||||
}.freeze
|
}.freeze
|
||||||
|
@ -135,7 +131,7 @@ class MediaAttachment < ApplicationRecord
|
||||||
convert_options: {
|
convert_options: {
|
||||||
output: {
|
output: {
|
||||||
'loglevel' => 'fatal',
|
'loglevel' => 'fatal',
|
||||||
:vf => 'scale=\'min(400\, iw):min(400\, ih)\':force_original_aspect_ratio=decrease',
|
:vf => 'scale=\'min(640\, iw):min(640\, ih)\':force_original_aspect_ratio=decrease',
|
||||||
}.freeze,
|
}.freeze,
|
||||||
}.freeze,
|
}.freeze,
|
||||||
format: 'png',
|
format: 'png',
|
||||||
|
|
|
@ -1709,6 +1709,10 @@ en:
|
||||||
default: "%b %d, %Y, %H:%M"
|
default: "%b %d, %Y, %H:%M"
|
||||||
month: "%b %Y"
|
month: "%b %Y"
|
||||||
time: "%H:%M"
|
time: "%H:%M"
|
||||||
|
translation:
|
||||||
|
errors:
|
||||||
|
quota_exceeded: The server-wide usage quota for the translation service has been exceeded.
|
||||||
|
too_many_requests: There have been too many requests to the translation service recently.
|
||||||
two_factor_authentication:
|
two_factor_authentication:
|
||||||
add: Add
|
add: Add
|
||||||
disable: Disable 2FA
|
disable: Disable 2FA
|
||||||
|
|
|
@ -4,6 +4,9 @@ module Paperclip
|
||||||
# This transcoder is only to be used for the MediaAttachment model
|
# This transcoder is only to be used for the MediaAttachment model
|
||||||
# to check when uploaded videos are actually gifv's
|
# to check when uploaded videos are actually gifv's
|
||||||
class Transcoder < Paperclip::Processor
|
class Transcoder < Paperclip::Processor
|
||||||
|
# This is the H.264 "High" value taken from https://www.dr-lex.be/info-stuff/videocalc.html
|
||||||
|
BITS_PER_PIXEL = 0.11
|
||||||
|
|
||||||
def initialize(file, options = {}, attachment = nil)
|
def initialize(file, options = {}, attachment = nil)
|
||||||
super
|
super
|
||||||
|
|
||||||
|
@ -38,8 +41,11 @@ module Paperclip
|
||||||
@output_options['vframes'] = 1
|
@output_options['vframes'] = 1
|
||||||
when 'mp4'
|
when 'mp4'
|
||||||
unless eligible_to_passthrough?(metadata)
|
unless eligible_to_passthrough?(metadata)
|
||||||
@output_options['acodec'] = 'aac'
|
bitrate = (metadata.width * metadata.height * 30 * BITS_PER_PIXEL) / 1_000
|
||||||
@output_options['strict'] = 'experimental'
|
|
||||||
|
@output_options['b:v'] = "#{bitrate}k"
|
||||||
|
@output_options['maxrate'] = "#{bitrate + 192}k"
|
||||||
|
@output_options['bufsize'] = "#{bitrate * 5}k"
|
||||||
|
|
||||||
if high_vfr?(metadata)
|
if high_vfr?(metadata)
|
||||||
@output_options['vsync'] = 'vfr'
|
@output_options['vsync'] = 'vfr'
|
||||||
|
|
Loading…
Reference in New Issue