mirror of https://framagit.org/tykayn/mastodon
Merge branch 'main' into glitch-soc/merge-upstream
Conflicts: - `app/models/status.rb`: Upstream updated media and edit-related code textually close to glitch-soc additions (local-only and content-type). Ported upstream changes. - `app/models/status_edit.rb`: Upstream changes textually close to glitch-soc additions (content-type). Ported upstream changes. - `app/serializers/activitypub/note_serializer.rb`: Upstream changed how media attachments are handled. Not really a conflict, but textually close to glitch-soc additions (directMessage attribute). Ported upstream changes. - `app/services/remove_status_service.rb`: Upstream changed how media attachments are handled. Not really a conflict, but textually close to glitch-soc additions (DM timeline). Ported upstream changes. - `app/services/update_status_service.rb`: Upstream fixed an issue with language selection. Not really a conflict, but textually close to glitch-soc additions (content-type). Ported upstream changes. - `db/schema.rb`: Upstream added columns to the `status_edits` table, the conflict is because of an additional column (`content-type`) in glitch-soc. Ported upstream changes. - `package.json`: Upstream dependency (express) textually adjacent to a glitch-soc-specific one (favico.js) got updated. Updated it as well.master
commit
24e83246f9
3
Gemfile
3
Gemfile
|
@ -40,6 +40,7 @@ end
|
|||
gem 'net-ldap', '~> 0.17'
|
||||
gem 'omniauth-cas', '~> 2.0'
|
||||
gem 'omniauth-saml', '~> 1.10'
|
||||
gem 'gitlab-omniauth-openid-connect', '~>0.5.0', require: 'omniauth_openid_connect'
|
||||
gem 'omniauth', '~> 1.9'
|
||||
gem 'omniauth-rails_csrf_protection', '~> 0.1'
|
||||
|
||||
|
@ -115,7 +116,7 @@ end
|
|||
group :test do
|
||||
gem 'capybara', '~> 3.36'
|
||||
gem 'climate_control', '~> 0.2'
|
||||
gem 'faker', '~> 2.19'
|
||||
gem 'faker', '~> 2.20'
|
||||
gem 'microformats', '~> 4.2'
|
||||
gem 'rails-controller-testing', '~> 1.0'
|
||||
gem 'rspec-sidekiq', '~> 3.1'
|
||||
|
|
55
Gemfile.lock
55
Gemfile.lock
|
@ -68,6 +68,7 @@ GEM
|
|||
zeitwerk (~> 2.3)
|
||||
addressable (2.8.0)
|
||||
public_suffix (>= 2.0.2, < 5.0)
|
||||
aes_key_wrap (1.1.0)
|
||||
airbrussh (1.4.0)
|
||||
sshkit (>= 1.6.1, != 1.7.0)
|
||||
android_key_attestation (0.3.0)
|
||||
|
@ -77,6 +78,7 @@ GEM
|
|||
ast (2.4.2)
|
||||
attr_encrypted (3.1.0)
|
||||
encryptor (~> 3.0.0)
|
||||
attr_required (1.0.1)
|
||||
awrence (1.1.1)
|
||||
aws-eventstream (1.2.0)
|
||||
aws-partitions (1.558.0)
|
||||
|
@ -126,7 +128,7 @@ GEM
|
|||
sshkit (>= 1.9.0)
|
||||
capistrano-bundler (2.0.1)
|
||||
capistrano (~> 3.1)
|
||||
capistrano-rails (1.6.1)
|
||||
capistrano-rails (1.6.2)
|
||||
capistrano (~> 3.1)
|
||||
capistrano-bundler (>= 1.1, < 3)
|
||||
capistrano-rbenv (2.2.0)
|
||||
|
@ -210,8 +212,8 @@ GEM
|
|||
tzinfo
|
||||
excon (0.76.0)
|
||||
fabrication (2.27.0)
|
||||
faker (2.19.0)
|
||||
i18n (>= 1.6, < 2)
|
||||
faker (2.20.0)
|
||||
i18n (>= 1.8.11, < 2)
|
||||
faraday (1.9.3)
|
||||
faraday-em_http (~> 1.0)
|
||||
faraday-em_synchrony (~> 1.0)
|
||||
|
@ -260,6 +262,10 @@ GEM
|
|||
fuubar (2.5.1)
|
||||
rspec-core (~> 3.0)
|
||||
ruby-progressbar (~> 1.4)
|
||||
gitlab-omniauth-openid-connect (0.5.0)
|
||||
addressable (~> 2.7)
|
||||
omniauth (~> 1.9)
|
||||
openid_connect (~> 1.2)
|
||||
globalid (1.0.0)
|
||||
activesupport (>= 5.0)
|
||||
hamlit (2.13.0)
|
||||
|
@ -288,10 +294,11 @@ GEM
|
|||
domain_name (~> 0.5)
|
||||
http-form_data (2.3.0)
|
||||
http_accept_language (2.1.1)
|
||||
httpclient (2.8.3)
|
||||
httplog (1.5.0)
|
||||
rack (>= 1.0)
|
||||
rainbow (>= 2.0.0)
|
||||
i18n (1.9.1)
|
||||
i18n (1.10.0)
|
||||
concurrent-ruby (~> 1.0)
|
||||
i18n-tasks (0.9.37)
|
||||
activesupport (>= 4.0.2)
|
||||
|
@ -308,6 +315,10 @@ GEM
|
|||
jmespath (1.6.0)
|
||||
json (2.5.1)
|
||||
json-canonicalization (0.3.0)
|
||||
json-jwt (1.13.0)
|
||||
activesupport (>= 4.2)
|
||||
aes_key_wrap
|
||||
bindata
|
||||
json-ld (3.2.0)
|
||||
htmlentities (~> 4.3)
|
||||
json-canonicalization (~> 0.3)
|
||||
|
@ -408,6 +419,16 @@ GEM
|
|||
omniauth-saml (1.10.3)
|
||||
omniauth (~> 1.3, >= 1.3.2)
|
||||
ruby-saml (~> 1.9)
|
||||
openid_connect (1.2.0)
|
||||
activemodel
|
||||
attr_required (>= 1.0.0)
|
||||
json-jwt (>= 1.5.0)
|
||||
rack-oauth2 (>= 1.6.1)
|
||||
swd (>= 1.0.0)
|
||||
tzinfo
|
||||
validate_email
|
||||
validate_url
|
||||
webfinger (>= 1.0.1)
|
||||
openssl (2.2.0)
|
||||
openssl-signature_algorithm (0.4.0)
|
||||
orm_adapter (0.5.0)
|
||||
|
@ -451,6 +472,12 @@ GEM
|
|||
rack (>= 1.0, < 3)
|
||||
rack-cors (1.1.1)
|
||||
rack (>= 2.0.0)
|
||||
rack-oauth2 (1.16.0)
|
||||
activesupport
|
||||
attr_required
|
||||
httpclient
|
||||
json-jwt (>= 1.11.0)
|
||||
rack (>= 2.1.0)
|
||||
rack-proxy (0.7.0)
|
||||
rack
|
||||
rack-test (1.1.0)
|
||||
|
@ -498,7 +525,7 @@ GEM
|
|||
rdf (~> 3.2)
|
||||
redcarpet (3.5.1)
|
||||
redis (4.5.1)
|
||||
redis-namespace (1.8.1)
|
||||
redis-namespace (1.8.2)
|
||||
redis (>= 3.0.4)
|
||||
regexp_parser (2.2.0)
|
||||
request_store (1.5.0)
|
||||
|
@ -606,11 +633,15 @@ GEM
|
|||
sshkit (1.21.2)
|
||||
net-scp (>= 1.1.2)
|
||||
net-ssh (>= 2.8.0)
|
||||
stackprof (0.2.17)
|
||||
stackprof (0.2.19)
|
||||
statsd-ruby (1.5.0)
|
||||
stoplight (2.2.1)
|
||||
strong_migrations (0.7.9)
|
||||
activerecord (>= 5)
|
||||
swd (1.2.0)
|
||||
activesupport (>= 3)
|
||||
attr_required (>= 0.0.5)
|
||||
httpclient (>= 2.4)
|
||||
temple (0.8.2)
|
||||
terminal-table (3.0.2)
|
||||
unicode-display_width (>= 1.1.1, < 3)
|
||||
|
@ -645,6 +676,12 @@ GEM
|
|||
unf_ext (0.0.8)
|
||||
unicode-display_width (2.1.0)
|
||||
uniform_notifier (1.14.2)
|
||||
validate_email (0.1.6)
|
||||
activemodel (>= 3.0)
|
||||
mail (>= 2.2.5)
|
||||
validate_url (1.0.13)
|
||||
activemodel (>= 3.0.0)
|
||||
public_suffix
|
||||
warden (1.2.9)
|
||||
rack (>= 2.0.9)
|
||||
webauthn (3.0.0.alpha1)
|
||||
|
@ -657,6 +694,9 @@ GEM
|
|||
safety_net_attestation (~> 0.4.0)
|
||||
securecompare (~> 1.0)
|
||||
tpm-key_attestation (~> 0.9.0)
|
||||
webfinger (1.1.0)
|
||||
activesupport
|
||||
httpclient (>= 2.4)
|
||||
webmock (3.14.0)
|
||||
addressable (>= 2.8.0)
|
||||
crack (>= 0.3.2)
|
||||
|
@ -714,12 +754,13 @@ DEPENDENCIES
|
|||
dotenv-rails (~> 2.7)
|
||||
ed25519 (~> 1.3)
|
||||
fabrication (~> 2.27)
|
||||
faker (~> 2.19)
|
||||
faker (~> 2.20)
|
||||
fast_blank (~> 1.0)
|
||||
fastimage
|
||||
fog-core (<= 2.1.0)
|
||||
fog-openstack (~> 0.3)
|
||||
fuubar (~> 2.5)
|
||||
gitlab-omniauth-openid-connect (~> 0.5.0)
|
||||
hamlit-rails (~> 0.2)
|
||||
hcaptcha (~> 7.1)
|
||||
hiredis (~> 0.6)
|
||||
|
|
|
@ -57,7 +57,7 @@ class StatusesIndex < Chewy::Index
|
|||
field :id, type: 'long'
|
||||
field :account_id, type: 'long'
|
||||
|
||||
field :text, type: 'text', value: ->(status) { [status.spoiler_text, Formatter.instance.plaintext(status)].concat(status.media_attachments.map(&:description)).concat(status.preloadable_poll ? status.preloadable_poll.options : []).join("\n\n") } do
|
||||
field :text, type: 'text', value: ->(status) { [status.spoiler_text, Formatter.instance.plaintext(status)].concat(status.ordered_media_attachments.map(&:description)).concat(status.preloadable_poll ? status.preloadable_poll.options : []).join("\n\n") } do
|
||||
field :stemmed, type: 'text', analyzer: 'content'
|
||||
end
|
||||
|
||||
|
|
|
@ -56,10 +56,6 @@ module Admin
|
|||
end
|
||||
end
|
||||
|
||||
def show
|
||||
authorize @domain_block, :show?
|
||||
end
|
||||
|
||||
def destroy
|
||||
authorize @domain_block, :destroy?
|
||||
UnblockDomainService.new.call(@domain_block)
|
||||
|
|
|
@ -4,28 +4,26 @@ module Admin
|
|||
class InstancesController < BaseController
|
||||
before_action :set_instances, only: :index
|
||||
before_action :set_instance, except: :index
|
||||
before_action :set_exhausted_deliveries_days, only: :show
|
||||
|
||||
def index
|
||||
authorize :instance, :index?
|
||||
preload_delivery_failures!
|
||||
end
|
||||
|
||||
def show
|
||||
authorize :instance, :show?
|
||||
@time_period = (6.days.ago.to_date...Time.now.utc.to_date)
|
||||
end
|
||||
|
||||
def destroy
|
||||
authorize :instance, :destroy?
|
||||
|
||||
Admin::DomainPurgeWorker.perform_async(@instance.domain)
|
||||
|
||||
log_action :destroy, @instance
|
||||
redirect_to admin_instances_path, notice: I18n.t('admin.instances.destroyed_msg', domain: @instance.domain)
|
||||
end
|
||||
|
||||
def clear_delivery_errors
|
||||
authorize :delivery, :clear_delivery_errors?
|
||||
|
||||
@instance.delivery_failure_tracker.clear_failures!
|
||||
redirect_to admin_instance_path(@instance.domain)
|
||||
end
|
||||
|
@ -33,11 +31,9 @@ module Admin
|
|||
def restart_delivery
|
||||
authorize :delivery, :restart_delivery?
|
||||
|
||||
last_unavailable_domain = unavailable_domain
|
||||
|
||||
if last_unavailable_domain.present?
|
||||
if @instance.unavailable?
|
||||
@instance.delivery_failure_tracker.track_success!
|
||||
log_action :destroy, last_unavailable_domain
|
||||
log_action :destroy, @instance.unavailable_domain
|
||||
end
|
||||
|
||||
redirect_to admin_instance_path(@instance.domain)
|
||||
|
@ -45,8 +41,7 @@ module Admin
|
|||
|
||||
def stop_delivery
|
||||
authorize :delivery, :stop_delivery?
|
||||
|
||||
UnavailableDomain.create(domain: @instance.domain)
|
||||
unavailable_domain = UnavailableDomain.create!(domain: @instance.domain)
|
||||
log_action :create, unavailable_domain
|
||||
redirect_to admin_instance_path(@instance.domain)
|
||||
end
|
||||
|
@ -57,12 +52,11 @@ module Admin
|
|||
@instance = Instance.find(params[:id])
|
||||
end
|
||||
|
||||
def set_exhausted_deliveries_days
|
||||
@exhausted_deliveries_days = @instance.delivery_failure_tracker.exhausted_deliveries_days
|
||||
end
|
||||
|
||||
def set_instances
|
||||
@instances = filtered_instances.page(params[:page])
|
||||
end
|
||||
|
||||
def preload_delivery_failures!
|
||||
warning_domains_map = DeliveryFailureTracker.warning_domains_map
|
||||
|
||||
@instances.each do |instance|
|
||||
|
@ -70,10 +64,6 @@ module Admin
|
|||
end
|
||||
end
|
||||
|
||||
def unavailable_domain
|
||||
UnavailableDomain.find_by(domain: @instance.domain)
|
||||
end
|
||||
|
||||
def filtered_instances
|
||||
InstanceFilter.new(whitelist_mode? ? { allowed: true } : filter_params).results
|
||||
end
|
||||
|
|
|
@ -10,6 +10,7 @@ class Api::V1::StatusesController < Api::BaseController
|
|||
before_action :set_thread, only: [:create]
|
||||
|
||||
override_rate_limit_headers :create, family: :statuses
|
||||
override_rate_limit_headers :update, family: :statuses
|
||||
|
||||
# This API was originally unlimited, pagination cannot be introduced without
|
||||
# breaking backwards-compatibility. Arbitrarily high number to cover most
|
||||
|
|
|
@ -4,8 +4,6 @@ class Auth::OmniauthCallbacksController < Devise::OmniauthCallbacksController
|
|||
skip_before_action :verify_authenticity_token
|
||||
|
||||
def self.provides_callback_for(provider)
|
||||
provider_id = provider.to_s.chomp '_oauth2'
|
||||
|
||||
define_method provider do
|
||||
@user = User.find_for_oauth(request.env['omniauth.auth'], current_user)
|
||||
|
||||
|
@ -20,7 +18,7 @@ class Auth::OmniauthCallbacksController < Devise::OmniauthCallbacksController
|
|||
)
|
||||
|
||||
sign_in_and_redirect @user, event: :authentication
|
||||
set_flash_message(:notice, :success, kind: provider_id.capitalize) if is_navigational_format?
|
||||
set_flash_message(:notice, :success, kind: Devise.omniauth_configs[provider].strategy.display_name.capitalize) if is_navigational_format?
|
||||
else
|
||||
session["devise.#{provider}_data"] = request.env['omniauth.auth']
|
||||
redirect_to new_user_registration_url
|
||||
|
@ -33,7 +31,7 @@ class Auth::OmniauthCallbacksController < Devise::OmniauthCallbacksController
|
|||
end
|
||||
|
||||
def after_sign_in_path_for(resource)
|
||||
if resource.email_verified?
|
||||
if resource.email_present?
|
||||
root_path
|
||||
else
|
||||
auth_setup_path(missing_email: '1')
|
||||
|
|
|
@ -241,6 +241,15 @@ module LanguagesHelper
|
|||
code
|
||||
end
|
||||
|
||||
def valid_locale_cascade(*arr)
|
||||
arr.each do |str|
|
||||
locale = valid_locale_or_nil(str)
|
||||
return locale if locale.present?
|
||||
end
|
||||
|
||||
nil
|
||||
end
|
||||
|
||||
def valid_locale?(locale)
|
||||
locale.present? && SUPPORTED_LOCALES.key?(locale.to_sym)
|
||||
end
|
||||
|
|
|
@ -132,7 +132,7 @@ module StatusesHelper
|
|||
end
|
||||
|
||||
def render_video_component(status, **options)
|
||||
video = status.media_attachments.first
|
||||
video = status.ordered_media_attachments.first
|
||||
|
||||
meta = video.file.meta || {}
|
||||
|
||||
|
@ -150,12 +150,12 @@ module StatusesHelper
|
|||
}.merge(**options)
|
||||
|
||||
react_component :video, component_params do
|
||||
render partial: 'statuses/attachment_list', locals: { attachments: status.media_attachments }
|
||||
render partial: 'statuses/attachment_list', locals: { attachments: status.ordered_media_attachments }
|
||||
end
|
||||
end
|
||||
|
||||
def render_audio_component(status, **options)
|
||||
audio = status.media_attachments.first
|
||||
audio = status.ordered_media_attachments.first
|
||||
|
||||
meta = audio.file.meta || {}
|
||||
|
||||
|
@ -170,7 +170,7 @@ module StatusesHelper
|
|||
}.merge(**options)
|
||||
|
||||
react_component :audio, component_params do
|
||||
render partial: 'statuses/attachment_list', locals: { attachments: status.media_attachments }
|
||||
render partial: 'statuses/attachment_list', locals: { attachments: status.ordered_media_attachments }
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -178,11 +178,11 @@ module StatusesHelper
|
|||
component_params = {
|
||||
sensitive: sensitized?(status, current_account),
|
||||
autoplay: prefers_autoplay?,
|
||||
media: status.media_attachments.map { |a| ActiveModelSerializers::SerializableResource.new(a, serializer: REST::MediaAttachmentSerializer).as_json },
|
||||
media: status.ordered_media_attachments.map { |a| ActiveModelSerializers::SerializableResource.new(a, serializer: REST::MediaAttachmentSerializer).as_json },
|
||||
}.merge(**options)
|
||||
|
||||
react_component :media_gallery, component_params do
|
||||
render partial: 'statuses/attachment_list', locals: { attachments: status.media_attachments }
|
||||
render partial: 'statuses/attachment_list', locals: { attachments: status.ordered_media_attachments }
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
@ -68,12 +68,12 @@ export default class Counter extends React.PureComponent {
|
|||
);
|
||||
} else {
|
||||
const measure = data[0];
|
||||
const percentChange = percIncrease(measure.previous_total * 1, measure.total * 1);
|
||||
const percentChange = measure.previous_total && percIncrease(measure.previous_total * 1, measure.total * 1);
|
||||
|
||||
content = (
|
||||
<React.Fragment>
|
||||
<span className='sparkline__value__total'><FormattedNumber value={measure.total} /></span>
|
||||
<span className={classNames('sparkline__value__change', { positive: percentChange > 0, negative: percentChange < 0 })}>{percentChange > 0 && '+'}<FormattedNumber value={percentChange} style='percent' /></span>
|
||||
<span className='sparkline__value__total'>{measure.human_value || <FormattedNumber value={measure.total} />}</span>
|
||||
{measure.previous_total && (<span className={classNames('sparkline__value__change', { positive: percentChange > 0, negative: percentChange < 0 })}>{percentChange > 0 && '+'}<FormattedNumber value={percentChange} style='percent' /></span>)}
|
||||
</React.Fragment>
|
||||
);
|
||||
}
|
||||
|
|
|
@ -0,0 +1,116 @@
|
|||
import React from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import ImmutablePropTypes from 'react-immutable-proptypes';
|
||||
import ImmutablePureComponent from 'react-immutable-pure-component';
|
||||
import { MediaGallery, Video, Audio } from 'mastodon/features/ui/util/async-components';
|
||||
import Bundle from 'mastodon/features/ui/components/bundle';
|
||||
import noop from 'lodash/noop';
|
||||
|
||||
export default class MediaAttachments extends ImmutablePureComponent {
|
||||
|
||||
static propTypes = {
|
||||
status: ImmutablePropTypes.map.isRequired,
|
||||
height: PropTypes.number,
|
||||
width: PropTypes.number,
|
||||
};
|
||||
|
||||
static defaultProps = {
|
||||
height: 110,
|
||||
width: 239,
|
||||
};
|
||||
|
||||
updateOnProps = [
|
||||
'status',
|
||||
];
|
||||
|
||||
renderLoadingMediaGallery = () => {
|
||||
const { height, width } = this.props;
|
||||
|
||||
return (
|
||||
<div className='media-gallery' style={{ height, width }} />
|
||||
);
|
||||
}
|
||||
|
||||
renderLoadingVideoPlayer = () => {
|
||||
const { height, width } = this.props;
|
||||
|
||||
return (
|
||||
<div className='video-player' style={{ height, width }} />
|
||||
);
|
||||
}
|
||||
|
||||
renderLoadingAudioPlayer = () => {
|
||||
const { height, width } = this.props;
|
||||
|
||||
return (
|
||||
<div className='audio-player' style={{ height, width }} />
|
||||
);
|
||||
}
|
||||
|
||||
render () {
|
||||
const { status, width, height } = this.props;
|
||||
const mediaAttachments = status.get('media_attachments');
|
||||
|
||||
if (mediaAttachments.size === 0) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (mediaAttachments.getIn([0, 'type']) === 'audio') {
|
||||
const audio = mediaAttachments.get(0);
|
||||
|
||||
return (
|
||||
<Bundle fetchComponent={Audio} loading={this.renderLoadingAudioPlayer} >
|
||||
{Component => (
|
||||
<Component
|
||||
src={audio.get('url')}
|
||||
alt={audio.get('description')}
|
||||
width={width}
|
||||
height={height}
|
||||
poster={audio.get('preview_url') || status.getIn(['account', 'avatar_static'])}
|
||||
backgroundColor={audio.getIn(['meta', 'colors', 'background'])}
|
||||
foregroundColor={audio.getIn(['meta', 'colors', 'foreground'])}
|
||||
accentColor={audio.getIn(['meta', 'colors', 'accent'])}
|
||||
duration={audio.getIn(['meta', 'original', 'duration'], 0)}
|
||||
/>
|
||||
)}
|
||||
</Bundle>
|
||||
);
|
||||
} else if (mediaAttachments.getIn([0, 'type']) === 'video') {
|
||||
const video = mediaAttachments.get(0);
|
||||
|
||||
return (
|
||||
<Bundle fetchComponent={Video} loading={this.renderLoadingVideoPlayer} >
|
||||
{Component => (
|
||||
<Component
|
||||
preview={video.get('preview_url')}
|
||||
frameRate={video.getIn(['meta', 'original', 'frame_rate'])}
|
||||
blurhash={video.get('blurhash')}
|
||||
src={video.get('url')}
|
||||
alt={video.get('description')}
|
||||
width={width}
|
||||
height={height}
|
||||
inline
|
||||
sensitive={status.get('sensitive')}
|
||||
onOpenVideo={noop}
|
||||
/>
|
||||
)}
|
||||
</Bundle>
|
||||
);
|
||||
} else {
|
||||
return (
|
||||
<Bundle fetchComponent={MediaGallery} loading={this.renderLoadingMediaGallery} >
|
||||
{Component => (
|
||||
<Component
|
||||
media={mediaAttachments}
|
||||
sensitive={status.get('sensitive')}
|
||||
defaultWidth={width}
|
||||
height={height}
|
||||
onOpenMedia={noop}
|
||||
/>
|
||||
)}
|
||||
</Bundle>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -40,7 +40,17 @@ class ColumnSettings extends React.PureComponent {
|
|||
}
|
||||
};
|
||||
|
||||
onSelect = mode => value => this.props.onChange(['tags', mode], value);
|
||||
onSelect = mode => value => {
|
||||
const oldValue = this.tags(mode);
|
||||
|
||||
// Prevent changes that add more than 4 tags, but allow removing
|
||||
// tags that were already added before
|
||||
if ((value.length > 4) && !(value < oldValue)) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.props.onChange(['tags', mode], value);
|
||||
};
|
||||
|
||||
onToggle = () => {
|
||||
if (this.state.open && this.hasTags()) {
|
||||
|
|
|
@ -1,14 +1,12 @@
|
|||
import React from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import ImmutablePropTypes from 'react-immutable-proptypes';
|
||||
import noop from 'lodash/noop';
|
||||
import StatusContent from 'mastodon/components/status_content';
|
||||
import { MediaGallery, Video } from 'mastodon/features/ui/util/async-components';
|
||||
import Bundle from 'mastodon/features/ui/components/bundle';
|
||||
import Avatar from 'mastodon/components/avatar';
|
||||
import DisplayName from 'mastodon/components/display_name';
|
||||
import RelativeTimestamp from 'mastodon/components/relative_timestamp';
|
||||
import Option from './option';
|
||||
import MediaAttachments from 'mastodon/components/media_attachments';
|
||||
|
||||
export default class StatusCheckBox extends React.PureComponent {
|
||||
|
||||
|
@ -27,51 +25,10 @@ export default class StatusCheckBox extends React.PureComponent {
|
|||
render () {
|
||||
const { status, checked } = this.props;
|
||||
|
||||
let media = null;
|
||||
|
||||
if (status.get('reblog')) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (status.get('media_attachments').size > 0) {
|
||||
if (status.get('media_attachments').some(item => item.get('type') === 'unknown')) {
|
||||
|
||||
} else if (status.getIn(['media_attachments', 0, 'type']) === 'video') {
|
||||
const video = status.getIn(['media_attachments', 0]);
|
||||
|
||||
media = (
|
||||
<Bundle fetchComponent={Video} loading={this.renderLoadingVideoPlayer} >
|
||||
{Component => (
|
||||
<Component
|
||||
preview={video.get('preview_url')}
|
||||
blurhash={video.get('blurhash')}
|
||||
src={video.get('url')}
|
||||
alt={video.get('description')}
|
||||
width={239}
|
||||
height={110}
|
||||
inline
|
||||
sensitive={status.get('sensitive')}
|
||||
onOpenVideo={noop}
|
||||
/>
|
||||
)}
|
||||
</Bundle>
|
||||
);
|
||||
} else {
|
||||
media = (
|
||||
<Bundle fetchComponent={MediaGallery} loading={this.renderLoadingMediaGallery} >
|
||||
{Component => (
|
||||
<Component
|
||||
media={status.get('media_attachments')}
|
||||
sensitive={status.get('sensitive')}
|
||||
height={110}
|
||||
onOpenMedia={noop}
|
||||
/>
|
||||
)}
|
||||
</Bundle>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
const labelComponent = (
|
||||
<div className='status-check-box__status poll__option__text'>
|
||||
<div className='detailed-status__display-name'>
|
||||
|
@ -79,12 +36,13 @@ export default class StatusCheckBox extends React.PureComponent {
|
|||
<Avatar account={status.get('account')} size={46} />
|
||||
</div>
|
||||
|
||||
<div><DisplayName account={status.get('account')} /> · <RelativeTimestamp timestamp={status.get('created_at')} /></div>
|
||||
<div>
|
||||
<DisplayName account={status.get('account')} /> · <RelativeTimestamp timestamp={status.get('created_at')} />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<StatusContent status={status} />
|
||||
|
||||
{media}
|
||||
<MediaAttachments status={status} />
|
||||
</div>
|
||||
);
|
||||
|
||||
|
|
|
@ -9,6 +9,7 @@ import escapeTextContentForBrowser from 'escape-html';
|
|||
import InlineAccount from 'mastodon/components/inline_account';
|
||||
import IconButton from 'mastodon/components/icon_button';
|
||||
import RelativeTimestamp from 'mastodon/components/relative_timestamp';
|
||||
import MediaAttachments from 'mastodon/components/media_attachments';
|
||||
|
||||
const mapStateToProps = (state, { statusId }) => ({
|
||||
versions: state.getIn(['history', statusId, 'items']),
|
||||
|
@ -70,6 +71,25 @@ class CompareHistoryModal extends React.PureComponent {
|
|||
)}
|
||||
|
||||
<div className='status__content__text status__content__text--visible translate' dangerouslySetInnerHTML={content} />
|
||||
|
||||
{!!currentVersion.get('poll') && (
|
||||
<div className='poll'>
|
||||
<ul>
|
||||
{currentVersion.getIn(['poll', 'options']).map(option => (
|
||||
<li key={option.get('title')}>
|
||||
<span className='poll__input disabled' />
|
||||
|
||||
<span
|
||||
className='poll__option__text translate'
|
||||
dangerouslySetInnerHTML={{ __html: emojify(escapeTextContentForBrowser(option.get('title')), emojiMap) }}
|
||||
/>
|
||||
</li>
|
||||
))}
|
||||
</ul>
|
||||
</div>
|
||||
)}
|
||||
|
||||
<MediaAttachments status={currentVersion} />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -18,12 +18,12 @@
|
|||
"account.followers": "Followers",
|
||||
"account.followers.empty": "No one follows this user yet.",
|
||||
"account.followers_counter": "{count, plural, one {{counter} Follower} other {{counter} Followers}}",
|
||||
"account.following": "Following",
|
||||
"account.following_counter": "{count, plural, one {{counter} Following} other {{counter} Following}}",
|
||||
"account.follows.empty": "This user doesn't follow anyone yet.",
|
||||
"account.follows_you": "Follows you",
|
||||
"account.hide_reblogs": "Hide boosts from @{name}",
|
||||
"account.joined": "Joined {date}",
|
||||
"account.last_status": "Last active",
|
||||
"account.link_verified_on": "Ownership of this link was checked on {date}",
|
||||
"account.locked_info": "This account privacy status is set to locked. The owner manually reviews who can follow them.",
|
||||
"account.media": "Media",
|
||||
|
@ -32,7 +32,6 @@
|
|||
"account.mute": "Mute @{name}",
|
||||
"account.mute_notifications": "Mute notifications from @{name}",
|
||||
"account.muted": "Muted",
|
||||
"account.never_active": "Never",
|
||||
"account.posts": "Toots",
|
||||
"account.posts_with_replies": "Toots and replies",
|
||||
"account.report": "Report @{name}",
|
||||
|
@ -42,10 +41,12 @@
|
|||
"account.statuses_counter": "{count, plural, one {{counter} Toot} other {{counter} Toots}}",
|
||||
"account.unblock": "Unblock @{name}",
|
||||
"account.unblock_domain": "Unblock domain {domain}",
|
||||
"account.unblock_short": "Unblock",
|
||||
"account.unendorse": "Don't feature on profile",
|
||||
"account.unfollow": "Unfollow",
|
||||
"account.unmute": "Unmute @{name}",
|
||||
"account.unmute_notifications": "Unmute notifications from @{name}",
|
||||
"account.unmute_short": "Unmute",
|
||||
"account_note.placeholder": "Click to add a note",
|
||||
"admin.dashboard.daily_retention": "User retention rate by day after sign-up",
|
||||
"admin.dashboard.monthly_retention": "User retention rate by month after sign-up",
|
||||
|
|
|
@ -18,12 +18,12 @@
|
|||
"account.followers": "المُتابِعون",
|
||||
"account.followers.empty": "لا أحدَ يُتابع هذا المُستخدم حتى الآن.",
|
||||
"account.followers_counter": "{count, plural, zero{لا مُتابع} one {مُتابعٌ واحِد} two{مُتابعانِ اِثنان} few{{counter} مُتابِعين} many{{counter} مُتابِعًا} other {{counter} مُتابع}}",
|
||||
"account.following": "Following",
|
||||
"account.following_counter": "{count, plural, zero{لا يُتابِع} one {يُتابِعُ واحد} two{يُتابِعُ اِثنان} few{يُتابِعُ {counter}} many{يُتابِعُ {counter}} other {يُتابِعُ {counter}}}",
|
||||
"account.follows.empty": "لا يُتابع هذا المُستخدمُ أيَّ أحدٍ حتى الآن.",
|
||||
"account.follows_you": "يُتابِعُك",
|
||||
"account.hide_reblogs": "إخفاء مشاركات @{name}",
|
||||
"account.joined": "انضم في {date}",
|
||||
"account.last_status": "آخر نشاط",
|
||||
"account.link_verified_on": "تمَّ التَّحقق مِن مِلْكيّة هذا الرابط بتاريخ {date}",
|
||||
"account.locked_info": "تمَّ تعيين حالة خصوصية هذا الحساب إلى مُقفَل. يُراجع المالك يدويًا من يمكنه متابعته.",
|
||||
"account.media": "وسائط",
|
||||
|
@ -32,7 +32,6 @@
|
|||
"account.mute": "كَتم @{name}",
|
||||
"account.mute_notifications": "كَتم الإشعارات من @{name}",
|
||||
"account.muted": "مَكتوم",
|
||||
"account.never_active": "أبدًا",
|
||||
"account.posts": "منشورات",
|
||||
"account.posts_with_replies": "المنشورات والرُدود",
|
||||
"account.report": "الإبلاغ عن @{name}",
|
||||
|
@ -42,10 +41,12 @@
|
|||
"account.statuses_counter": "{count, plural, zero {لَا تَبويقات} one {تَبويقةٌ واحدة} two {تَبويقَتانِ اِثنتان} few {{counter} تَبويقات} many {{counter} تَبويقتًا} other {{counter} تَبويقة}}",
|
||||
"account.unblock": "إلغاء الحَظر عن @{name}",
|
||||
"account.unblock_domain": "إلغاء الحَظر عن النِّطاق {domain}",
|
||||
"account.unblock_short": "Unblock",
|
||||
"account.unendorse": "لا تُرَوِّج لهُ في الملف الشخصي",
|
||||
"account.unfollow": "إلغاء المُتابعة",
|
||||
"account.unmute": "إلغاء الكَتم عن @{name}",
|
||||
"account.unmute_notifications": "إلغاء كَتم الإشعارات عن @{name}",
|
||||
"account.unmute_short": "Unmute",
|
||||
"account_note.placeholder": "اضغط لإضافة مُلاحظة",
|
||||
"admin.dashboard.daily_retention": "User retention rate by day after sign-up",
|
||||
"admin.dashboard.monthly_retention": "User retention rate by month after sign-up",
|
||||
|
|
|
@ -18,12 +18,12 @@
|
|||
"account.followers": "Siguidores",
|
||||
"account.followers.empty": "Naide sigue a esti usuariu entá.",
|
||||
"account.followers_counter": "{count, plural, one {{counter} Follower} other {{counter} Followers}}",
|
||||
"account.following": "Following",
|
||||
"account.following_counter": "{count, plural, one {{counter} Following} other {{counter} Following}}",
|
||||
"account.follows.empty": "Esti usuariu entá nun sigue a naide.",
|
||||
"account.follows_you": "Síguete",
|
||||
"account.hide_reblogs": "Anubrir les comparticiones de @{name}",
|
||||
"account.joined": "Joined {date}",
|
||||
"account.last_status": "Cabera actividá",
|
||||
"account.link_verified_on": "La propiedá d'esti enllaz foi comprobada'l {date}",
|
||||
"account.locked_info": "This account privacy status is set to locked. The owner manually reviews who can follow them.",
|
||||
"account.media": "Media",
|
||||
|
@ -32,7 +32,6 @@
|
|||
"account.mute": "Silenciar a @{name}",
|
||||
"account.mute_notifications": "Mute notifications from @{name}",
|
||||
"account.muted": "Muted",
|
||||
"account.never_active": "Enxamás",
|
||||
"account.posts": "Barritos",
|
||||
"account.posts_with_replies": "Barritos y rempuestes",
|
||||
"account.report": "Report @{name}",
|
||||
|
@ -42,10 +41,12 @@
|
|||
"account.statuses_counter": "{count, plural, one {{counter} Toot} other {{counter} Toots}}",
|
||||
"account.unblock": "Desbloquiar a @{name}",
|
||||
"account.unblock_domain": "Amosar {domain}",
|
||||
"account.unblock_short": "Unblock",
|
||||
"account.unendorse": "Nun destacar nel perfil",
|
||||
"account.unfollow": "Dexar de siguir",
|
||||
"account.unmute": "Unmute @{name}",
|
||||
"account.unmute_notifications": "Unmute notifications from @{name}",
|
||||
"account.unmute_short": "Unmute",
|
||||
"account_note.placeholder": "Click to add a note",
|
||||
"admin.dashboard.daily_retention": "User retention rate by day after sign-up",
|
||||
"admin.dashboard.monthly_retention": "User retention rate by month after sign-up",
|
||||
|
|
|
@ -18,12 +18,12 @@
|
|||
"account.followers": "Последователи",
|
||||
"account.followers.empty": "Все още никой не следва този потребител.",
|
||||
"account.followers_counter": "{count, plural, one {{counter} Последовател} other {{counter} Последователи}}",
|
||||
"account.following": "Following",
|
||||
"account.following_counter": "{count, plural, one {{counter} Последван} other {{counter} Последвани}}",
|
||||
"account.follows.empty": "Този потребител все още не следва никого.",
|
||||
"account.follows_you": "Твой последовател",
|
||||
"account.hide_reblogs": "Скриване на споделяния от @{name}",
|
||||
"account.joined": "Joined {date}",
|
||||
"account.last_status": "Последно активен/а",
|
||||
"account.link_verified_on": "Собствеността върху тази връзка е проверена на {date}",
|
||||
"account.locked_info": "Този акаунт е поверително заключен. Собственикът преглежда ръчно кой може да го следва.",
|
||||
"account.media": "Мултимедия",
|
||||
|
@ -32,7 +32,6 @@
|
|||
"account.mute": "Заглушаване на @{name}",
|
||||
"account.mute_notifications": "Заглушаване на известия от @{name}",
|
||||
"account.muted": "Заглушено",
|
||||
"account.never_active": "Никога",
|
||||
"account.posts": "Публикации",
|
||||
"account.posts_with_replies": "Toots with replies",
|
||||
"account.report": "Докладване на @{name}",
|
||||
|
@ -42,10 +41,12 @@
|
|||
"account.statuses_counter": "{count, plural, one {{counter} Публикация} other {{counter} Публикации}}",
|
||||
"account.unblock": "Не блокирай",
|
||||
"account.unblock_domain": "Unhide {domain}",
|
||||
"account.unblock_short": "Unblock",
|
||||
"account.unendorse": "Не включвайте в профила",
|
||||
"account.unfollow": "Не следвай",
|
||||
"account.unmute": "Раззаглушаване на @{name}",
|
||||
"account.unmute_notifications": "Раззаглушаване на известия от @{name}",
|
||||
"account.unmute_short": "Unmute",
|
||||
"account_note.placeholder": "Click to add a note",
|
||||
"admin.dashboard.daily_retention": "User retention rate by day after sign-up",
|
||||
"admin.dashboard.monthly_retention": "User retention rate by month after sign-up",
|
||||
|
|
|
@ -18,12 +18,12 @@
|
|||
"account.followers": "অনুসরণকারী",
|
||||
"account.followers.empty": "এই ব্যক্তিকে এখনো কেউ অনুসরণ করে না।",
|
||||
"account.followers_counter": "{count, plural,one {{counter} জন অনুসরণকারী } other {{counter} জন অনুসরণকারী}}",
|
||||
"account.following": "Following",
|
||||
"account.following_counter": "{count, plural,one {{counter} জনকে অনুসরণ} other {{counter} জনকে অনুসরণ}}",
|
||||
"account.follows.empty": "এই সদস্য কাওকে এখনো অনুসরণ করেন না.",
|
||||
"account.follows_you": "তোমাকে অনুসরণ করে",
|
||||
"account.hide_reblogs": "@{name}'র সমর্থনগুলি লুকিয়ে ফেলুন",
|
||||
"account.joined": "Joined {date}",
|
||||
"account.last_status": "শেষ সক্রিয় ছিল",
|
||||
"account.link_verified_on": "এই লিংকের মালিকানা চেক করা হয়েছে {date} তারিখে",
|
||||
"account.locked_info": "এই নিবন্ধনের গোপনীয়তার ক্ষেত্র তালা দেওয়া আছে। নিবন্ধনকারী অনুসরণ করার অনুমতি যাদেরকে দেবেন, শুধু তারাই অনুসরণ করতে পারবেন।",
|
||||
"account.media": "মিডিয়া",
|
||||
|
@ -32,7 +32,6 @@
|
|||
"account.mute": "@{name} কে নিঃশব্দ করুন",
|
||||
"account.mute_notifications": "@{name} র প্রজ্ঞাপন আপনার কাছে নিঃশব্দ করুন",
|
||||
"account.muted": "নিঃশব্দ",
|
||||
"account.never_active": "কখনও নয়",
|
||||
"account.posts": "টুট",
|
||||
"account.posts_with_replies": "টুট এবং মতামত",
|
||||
"account.report": "@{name} কে রিপোর্ট করুন",
|
||||
|
@ -42,10 +41,12 @@
|
|||
"account.statuses_counter": "{count, plural,one {{counter} টুট} other {{counter} টুট}}",
|
||||
"account.unblock": "@{name} র কার্যকলাপ দেখুন",
|
||||
"account.unblock_domain": "{domain} কে আবার দেখুন",
|
||||
"account.unblock_short": "Unblock",
|
||||
"account.unendorse": "আপনার নিজের পাতায় এটা দেখবেন না",
|
||||
"account.unfollow": "অনুসরণ করো না",
|
||||
"account.unmute": "@{name} র কার্যকলাপ আবার দেখুন",
|
||||
"account.unmute_notifications": "@{name} র প্রজ্ঞাপন দেখুন",
|
||||
"account.unmute_short": "Unmute",
|
||||
"account_note.placeholder": "নোট যোগ করতে ক্লিক করুন",
|
||||
"admin.dashboard.daily_retention": "User retention rate by day after sign-up",
|
||||
"admin.dashboard.monthly_retention": "User retention rate by month after sign-up",
|
||||
|
|
|
@ -18,12 +18,12 @@
|
|||
"account.followers": "Heulier·ezed·ien",
|
||||
"account.followers.empty": "Den na heul an implijer-mañ c'hoazh.",
|
||||
"account.followers_counter": "{count, plural, other{{counter} Heulier}}",
|
||||
"account.following": "Following",
|
||||
"account.following_counter": "{count, plural, other {{counter} Heuliañ}}",
|
||||
"account.follows.empty": "An implijer·ez-mañ na heul den ebet.",
|
||||
"account.follows_you": "Ho heul",
|
||||
"account.hide_reblogs": "Kuzh toudoù rannet gant @{name}",
|
||||
"account.joined": "Amañ abaoe {date}",
|
||||
"account.last_status": "Oberiantiz zivezhañ",
|
||||
"account.link_verified_on": "Gwiriet eo bet perc'hennidigezh al liamm d'an deiziad-mañ : {date}",
|
||||
"account.locked_info": "Prennet eo ar gont-mañ. Dibab a ra ar perc'henn ar re a c'hall heuliañ anezhi pe anezhañ.",
|
||||
"account.media": "Media",
|
||||
|
@ -32,7 +32,6 @@
|
|||
"account.mute": "Kuzhat @{name}",
|
||||
"account.mute_notifications": "Kuzh kemennoù eus @{name}",
|
||||
"account.muted": "Kuzhet",
|
||||
"account.never_active": "Birviken",
|
||||
"account.posts": "a doudoù",
|
||||
"account.posts_with_replies": "Toudoù ha respontoù",
|
||||
"account.report": "Disklêriañ @{name}",
|
||||
|
@ -42,10 +41,12 @@
|
|||
"account.statuses_counter": "{count, plural, one {{counter} Toud} other {{counter} Toud}}",
|
||||
"account.unblock": "Diverzañ @{name}",
|
||||
"account.unblock_domain": "Diverzañ an domani {domain}",
|
||||
"account.unblock_short": "Unblock",
|
||||
"account.unendorse": "Paouez da lakaat war-wel war ar profil",
|
||||
"account.unfollow": "Diheuliañ",
|
||||
"account.unmute": "Diguzhat @{name}",
|
||||
"account.unmute_notifications": "Diguzhat kemennoù a @{name}",
|
||||
"account.unmute_short": "Unmute",
|
||||
"account_note.placeholder": "Klikit evit ouzhpenniñ un notenn",
|
||||
"admin.dashboard.daily_retention": "User retention rate by day after sign-up",
|
||||
"admin.dashboard.monthly_retention": "User retention rate by month after sign-up",
|
||||
|
|
|
@ -18,12 +18,12 @@
|
|||
"account.followers": "Seguidors",
|
||||
"account.followers.empty": "Encara ningú no segueix aquest usuari.",
|
||||
"account.followers_counter": "{count, plural, one {{counter} Seguidor} other {{counter} Seguidors}}",
|
||||
"account.following": "Following",
|
||||
"account.following_counter": "{count, plural, other {{counter} Seguint}}",
|
||||
"account.follows.empty": "Aquest usuari encara no segueix a ningú.",
|
||||
"account.follows_you": "Et segueix",
|
||||
"account.hide_reblogs": "Amaga els impulsos de @{name}",
|
||||
"account.joined": "Unit des de {date}",
|
||||
"account.last_status": "Darrer actiu",
|
||||
"account.link_verified_on": "La propietat d'aquest enllaç es va verificar el dia {date}",
|
||||
"account.locked_info": "Aquest estat de privadesa del compte està definit com a bloquejat. El propietari revisa manualment qui pot seguir-lo.",
|
||||
"account.media": "Mèdia",
|
||||
|
@ -32,7 +32,6 @@
|
|||
"account.mute": "Silencia @{name}",
|
||||
"account.mute_notifications": "Notificacions desactivades de @{name}",
|
||||
"account.muted": "Silenciat",
|
||||
"account.never_active": "Mai",
|
||||
"account.posts": "Tuts",
|
||||
"account.posts_with_replies": "Tuts i respostes",
|
||||
"account.report": "Informar sobre @{name}",
|
||||
|
@ -42,10 +41,12 @@
|
|||
"account.statuses_counter": "{count, plural, one {{counter} Tut} other {{counter} Tuts}}",
|
||||
"account.unblock": "Desbloqueja @{name}",
|
||||
"account.unblock_domain": "Mostra {domain}",
|
||||
"account.unblock_short": "Unblock",
|
||||
"account.unendorse": "No recomanar en el perfil",
|
||||
"account.unfollow": "Deixa de seguir",
|
||||
"account.unmute": "Treure silenci de @{name}",
|
||||
"account.unmute_notifications": "Activar notificacions de @{name}",
|
||||
"account.unmute_short": "Unmute",
|
||||
"account_note.placeholder": "Fes clic per afegir una nota",
|
||||
"admin.dashboard.daily_retention": "Ràtio de retenció per dia després del registre",
|
||||
"admin.dashboard.monthly_retention": "Ràtio de retenció per mes després del registre",
|
||||
|
|
|
@ -18,12 +18,12 @@
|
|||
"account.followers": "Abbunati",
|
||||
"account.followers.empty": "Nisunu hè abbunatu à st'utilizatore.",
|
||||
"account.followers_counter": "{count, plural, one {{counter} Abbunatu} other {{counter} Abbunati}}",
|
||||
"account.following": "Following",
|
||||
"account.following_counter": "{count, plural, one {{counter} Abbunamentu} other {{counter} Abbunamenti}}",
|
||||
"account.follows.empty": "St'utilizatore ùn seguita nisunu.",
|
||||
"account.follows_you": "Vi seguita",
|
||||
"account.hide_reblogs": "Piattà spartere da @{name}",
|
||||
"account.joined": "Quì dapoi {date}",
|
||||
"account.last_status": "Ultima attività",
|
||||
"account.link_verified_on": "A prupietà di stu ligame hè stata verificata u {date}",
|
||||
"account.locked_info": "U statutu di vita privata di u contu hè chjosu. U pruprietariu esamina manualmente e dumande d'abbunamentu.",
|
||||
"account.media": "Media",
|
||||
|
@ -32,7 +32,6 @@
|
|||
"account.mute": "Piattà @{name}",
|
||||
"account.mute_notifications": "Piattà nutificazione da @{name}",
|
||||
"account.muted": "Piattatu",
|
||||
"account.never_active": "Mai",
|
||||
"account.posts": "Statuti",
|
||||
"account.posts_with_replies": "Statuti è risposte",
|
||||
"account.report": "Palisà @{name}",
|
||||
|
@ -42,10 +41,12 @@
|
|||
"account.statuses_counter": "{count, plural, one {{counter} Statutu} other {{counter} Statuti}}",
|
||||
"account.unblock": "Sbluccà @{name}",
|
||||
"account.unblock_domain": "Ùn piattà più {domain}",
|
||||
"account.unblock_short": "Unblock",
|
||||
"account.unendorse": "Ùn fà figurà nant'à u prufilu",
|
||||
"account.unfollow": "Ùn siguità più",
|
||||
"account.unmute": "Ùn piattà più @{name}",
|
||||
"account.unmute_notifications": "Ùn piattà più nutificazione da @{name}",
|
||||
"account.unmute_short": "Unmute",
|
||||
"account_note.placeholder": "Senza cummentariu",
|
||||
"admin.dashboard.daily_retention": "User retention rate by day after sign-up",
|
||||
"admin.dashboard.monthly_retention": "User retention rate by month after sign-up",
|
||||
|
|
|
@ -18,12 +18,12 @@
|
|||
"account.followers": "Sledující",
|
||||
"account.followers.empty": "Tohoto uživatele ještě nikdo nesleduje.",
|
||||
"account.followers_counter": "{count, plural, one {{counter} Sledující} few {{counter} Sledující} many {{counter} Sledujících} other {{counter} Sledujících}}",
|
||||
"account.following": "Following",
|
||||
"account.following_counter": "{count, plural, one {{counter} Sledovaný} few {{counter} Sledovaní} many {{counter} Sledovaných} other {{counter} Sledovaných}}",
|
||||
"account.follows.empty": "Tento uživatel ještě nikoho nesleduje.",
|
||||
"account.follows_you": "Sleduje vás",
|
||||
"account.hide_reblogs": "Skrýt boosty od @{name}",
|
||||
"account.joined": "Založen {date}",
|
||||
"account.last_status": "Naposledy aktivní",
|
||||
"account.link_verified_on": "Vlastnictví tohoto odkazu bylo zkontrolováno {date}",
|
||||
"account.locked_info": "Stav soukromí tohoto účtu je nastaven na zamčeno. Jeho vlastník ručně posuzuje, kdo ho může sledovat.",
|
||||
"account.media": "Média",
|
||||
|
@ -32,7 +32,6 @@
|
|||
"account.mute": "Skrýt @{name}",
|
||||
"account.mute_notifications": "Skrýt oznámení od @{name}",
|
||||
"account.muted": "Skryt",
|
||||
"account.never_active": "Nikdy",
|
||||
"account.posts": "Příspěvky",
|
||||
"account.posts_with_replies": "Příspěvky a odpovědi",
|
||||
"account.report": "Nahlásit @{name}",
|
||||
|
@ -42,10 +41,12 @@
|
|||
"account.statuses_counter": "{count, plural, one {{counter} Příspěvek} few {{counter} Příspěvky} many {{counter} Příspěvků} other {{counter} Příspěvků}}",
|
||||
"account.unblock": "Odblokovat @{name}",
|
||||
"account.unblock_domain": "Odblokovat doménu {domain}",
|
||||
"account.unblock_short": "Unblock",
|
||||
"account.unendorse": "Nezvýrazňovat na profilu",
|
||||
"account.unfollow": "Přestat sledovat",
|
||||
"account.unmute": "Zrušit skrytí @{name}",
|
||||
"account.unmute_notifications": "Zrušit skrytí oznámení od @{name}",
|
||||
"account.unmute_short": "Unmute",
|
||||
"account_note.placeholder": "Klikněte pro přidání poznámky",
|
||||
"admin.dashboard.daily_retention": "User retention rate by day after sign-up",
|
||||
"admin.dashboard.monthly_retention": "User retention rate by month after sign-up",
|
||||
|
|
|
@ -18,12 +18,12 @@
|
|||
"account.followers": "Dilynwyr",
|
||||
"account.followers.empty": "Nid oes neb yn dilyn y defnyddiwr hwn eto.",
|
||||
"account.followers_counter": "{count, plural, one {{counter} Ddilynwr} other {{counter} o Ddilynwyr}}",
|
||||
"account.following": "Following",
|
||||
"account.following_counter": "{count, plural, one {{counter} yn Dilyn} other {{counter} yn Dilyn}}",
|
||||
"account.follows.empty": "Nid yw'r defnyddiwr hwn yn dilyn unrhyw un eto.",
|
||||
"account.follows_you": "Yn eich dilyn chi",
|
||||
"account.hide_reblogs": "Cuddio bwstiau o @{name}",
|
||||
"account.joined": "Joined {date}",
|
||||
"account.last_status": "Gweithredol olaf",
|
||||
"account.link_verified_on": "Gwiriwyd perchnogaeth y ddolen yma ar {date}",
|
||||
"account.locked_info": "Mae'r statws preifatrwydd cyfrif hwn wedi'i osod i gloi. Mae'r perchennog yn adolygu'r sawl sy'n gallu eu dilyn.",
|
||||
"account.media": "Cyfryngau",
|
||||
|
@ -32,7 +32,6 @@
|
|||
"account.mute": "Tawelu @{name}",
|
||||
"account.mute_notifications": "Cuddio hysbysiadau o @{name}",
|
||||
"account.muted": "Distewyd",
|
||||
"account.never_active": "Byth",
|
||||
"account.posts": "Tŵtiau",
|
||||
"account.posts_with_replies": "Tŵtiau ac atebion",
|
||||
"account.report": "Adrodd @{name}",
|
||||
|
@ -42,10 +41,12 @@
|
|||
"account.statuses_counter": "{count, plural, one {{counter} Dŵt} other {{counter} o Dŵtiau}}",
|
||||
"account.unblock": "Dadflocio @{name}",
|
||||
"account.unblock_domain": "Dadguddio {domain}",
|
||||
"account.unblock_short": "Unblock",
|
||||
"account.unendorse": "Peidio a'i arddangos ar fy mhroffil",
|
||||
"account.unfollow": "Dad-ddilyn",
|
||||
"account.unmute": "Dad-dawelu @{name}",
|
||||
"account.unmute_notifications": "Dad-dawelu hysbysiadau o @{name}",
|
||||
"account.unmute_short": "Unmute",
|
||||
"account_note.placeholder": "Clicio i ychwanegu nodyn",
|
||||
"admin.dashboard.daily_retention": "User retention rate by day after sign-up",
|
||||
"admin.dashboard.monthly_retention": "User retention rate by month after sign-up",
|
||||
|
|
|
@ -18,12 +18,12 @@
|
|||
"account.followers": "Følgere",
|
||||
"account.followers.empty": "Ingen følger brugeren endnu.",
|
||||
"account.followers_counter": "{count, plural, one {{counter} Følger} other {{counter} Følgere}}",
|
||||
"account.following": "Following",
|
||||
"account.following_counter": "{count, plural, one {{counter} Følges} other {{counter} Følges}}",
|
||||
"account.follows.empty": "Denne bruger følger ikke nogen endnu.",
|
||||
"account.follows_you": "Følger dig",
|
||||
"account.hide_reblogs": "Skjul fremhævelser fra @{name}",
|
||||
"account.joined": "Tilmeldt {date}",
|
||||
"account.last_status": "Senest aktiv",
|
||||
"account.link_verified_on": "Ejerskab af dette link blev tjekket {date}",
|
||||
"account.locked_info": "Denne kontos fortrolighedsstatus er sat til låst. Ejeren bedømmer manuelt, hvem der kan følge vedkommende.",
|
||||
"account.media": "Medier",
|
||||
|
@ -32,7 +32,6 @@
|
|||
"account.mute": "Skjul @{name}",
|
||||
"account.mute_notifications": "Skjul notifikationer fra @{name}",
|
||||
"account.muted": "Tystnet",
|
||||
"account.never_active": "Aldrig",
|
||||
"account.posts": "Indlæg",
|
||||
"account.posts_with_replies": "Indlæg og svar",
|
||||
"account.report": "Anmeld @{name}",
|
||||
|
@ -42,10 +41,12 @@
|
|||
"account.statuses_counter": "{count, plural, one {{counter} Indlæg} other {{counter} Indlæg}}",
|
||||
"account.unblock": "Fjern blokeringen af @{name}",
|
||||
"account.unblock_domain": "Afblokér domænet {domain}",
|
||||
"account.unblock_short": "Unblock",
|
||||
"account.unendorse": "Fjern visning på din profil",
|
||||
"account.unfollow": "Følg ikke længere",
|
||||
"account.unmute": "Fjern tavsgjort for @{name}",
|
||||
"account.unmute_notifications": "Slå notifikationer om @{name} til igen",
|
||||
"account.unmute_short": "Unmute",
|
||||
"account_note.placeholder": "Klik for at tilføje notat",
|
||||
"admin.dashboard.daily_retention": "Brugerfastholdelsesrate efter dag efter tilmelding",
|
||||
"admin.dashboard.monthly_retention": "User retention rate by month after sign-up",
|
||||
|
|
|
@ -18,12 +18,12 @@
|
|||
"account.followers": "Follower",
|
||||
"account.followers.empty": "Diesem Profil folgt noch niemand.",
|
||||
"account.followers_counter": "{count, plural, one {{counter} Follower} other {{counter} Follower}}",
|
||||
"account.following": "Following",
|
||||
"account.following_counter": "{count, plural, one {{counter} Folgender} other {{counter} Folgende}}",
|
||||
"account.follows.empty": "Dieses Profil folgt noch niemandem.",
|
||||
"account.follows_you": "Folgt dir",
|
||||
"account.hide_reblogs": "Geteilte Beiträge von @{name} verbergen",
|
||||
"account.joined": "Beigetreten am {date}",
|
||||
"account.last_status": "Zuletzt aktiv",
|
||||
"account.link_verified_on": "Besitz dieses Links wurde geprüft am {date}",
|
||||
"account.locked_info": "Der Privatsphärenstatus dieses Accounts wurde auf gesperrt gesetzt. Die Person bestimmt manuell wer ihm/ihr folgen darf.",
|
||||
"account.media": "Medien",
|
||||
|
@ -32,7 +32,6 @@
|
|||
"account.mute": "@{name} stummschalten",
|
||||
"account.mute_notifications": "Benachrichtigungen von @{name} stummschalten",
|
||||
"account.muted": "Stummgeschaltet",
|
||||
"account.never_active": "Nie",
|
||||
"account.posts": "Beiträge",
|
||||
"account.posts_with_replies": "Beiträge und Antworten",
|
||||
"account.report": "@{name} melden",
|
||||
|
@ -42,10 +41,12 @@
|
|||
"account.statuses_counter": "{count, plural, one {{counter} Beitrag} other {{counter} Beiträge}}",
|
||||
"account.unblock": "@{name} entblocken",
|
||||
"account.unblock_domain": "{domain} wieder anzeigen",
|
||||
"account.unblock_short": "Unblock",
|
||||
"account.unendorse": "Nicht auf Profil hervorheben",
|
||||
"account.unfollow": "Entfolgen",
|
||||
"account.unmute": "@{name} nicht mehr stummschalten",
|
||||
"account.unmute_notifications": "Benachrichtigungen von @{name} einschalten",
|
||||
"account.unmute_short": "Unmute",
|
||||
"account_note.placeholder": "Notiz durch Klicken hinzufügen",
|
||||
"admin.dashboard.daily_retention": "Benutzerverbleibrate nach Tag nach Anmeldung",
|
||||
"admin.dashboard.monthly_retention": "Benutzerverbleibrate nach Monat nach Anmeldung",
|
||||
|
|
|
@ -1624,30 +1624,38 @@
|
|||
},
|
||||
{
|
||||
"descriptors": [
|
||||
{
|
||||
"defaultMessage": "Follow",
|
||||
"id": "account.follow"
|
||||
},
|
||||
{
|
||||
"defaultMessage": "Unfollow",
|
||||
"id": "account.unfollow"
|
||||
},
|
||||
{
|
||||
"defaultMessage": "Awaiting approval",
|
||||
"defaultMessage": "Follow",
|
||||
"id": "account.follow"
|
||||
},
|
||||
{
|
||||
"defaultMessage": "Cancel follow request",
|
||||
"id": "account.cancel_follow_request"
|
||||
},
|
||||
{
|
||||
"defaultMessage": "Awaiting approval. Click to cancel follow request",
|
||||
"id": "account.requested"
|
||||
},
|
||||
{
|
||||
"defaultMessage": "Unblock @{name}",
|
||||
"id": "account.unblock"
|
||||
"defaultMessage": "Unblock",
|
||||
"id": "account.unblock_short"
|
||||
},
|
||||
{
|
||||
"defaultMessage": "Unmute @{name}",
|
||||
"id": "account.unmute"
|
||||
"defaultMessage": "Unmute",
|
||||
"id": "account.unmute_short"
|
||||
},
|
||||
{
|
||||
"defaultMessage": "Unfollow",
|
||||
"id": "confirmations.unfollow.confirm"
|
||||
},
|
||||
{
|
||||
"defaultMessage": "Edit profile",
|
||||
"id": "account.edit_profile"
|
||||
},
|
||||
{
|
||||
"defaultMessage": "Are you sure you want to unfollow {name}?",
|
||||
"id": "confirmations.unfollow.message"
|
||||
|
@ -1661,12 +1669,8 @@
|
|||
"id": "account.followers"
|
||||
},
|
||||
{
|
||||
"defaultMessage": "Never",
|
||||
"id": "account.never_active"
|
||||
},
|
||||
{
|
||||
"defaultMessage": "Last active",
|
||||
"id": "account.last_status"
|
||||
"defaultMessage": "Following",
|
||||
"id": "account.following"
|
||||
}
|
||||
],
|
||||
"path": "app/javascript/mastodon/features/directory/components/account_card.json"
|
||||
|
@ -2007,10 +2011,6 @@
|
|||
{
|
||||
"defaultMessage": "Getting started",
|
||||
"id": "getting_started.heading"
|
||||
},
|
||||
{
|
||||
"defaultMessage": "Profile directory",
|
||||
"id": "getting_started.directory"
|
||||
}
|
||||
],
|
||||
"path": "app/javascript/mastodon/features/getting_started/index.json"
|
||||
|
@ -2742,7 +2742,7 @@
|
|||
"id": "report.reasons.spam"
|
||||
},
|
||||
{
|
||||
"defaultMessage": "Malicious links, fake engagement, or repetetive replies",
|
||||
"defaultMessage": "Malicious links, fake engagement, or repetitive replies",
|
||||
"id": "report.reasons.spam_description"
|
||||
},
|
||||
{
|
||||
|
@ -3402,6 +3402,10 @@
|
|||
"defaultMessage": "About this server",
|
||||
"id": "navigation_bar.info"
|
||||
},
|
||||
{
|
||||
"defaultMessage": "Profile directory",
|
||||
"id": "getting_started.directory"
|
||||
},
|
||||
{
|
||||
"defaultMessage": "Mobile apps",
|
||||
"id": "navigation_bar.apps"
|
||||
|
@ -3529,10 +3533,6 @@
|
|||
"defaultMessage": "Lists",
|
||||
"id": "navigation_bar.lists"
|
||||
},
|
||||
{
|
||||
"defaultMessage": "Profile directory",
|
||||
"id": "getting_started.directory"
|
||||
},
|
||||
{
|
||||
"defaultMessage": "Preferences",
|
||||