Merge pull request #1793 from ClearlyClaire/glitch-soc/merge-upstream

Merge upstream changes
This commit is contained in:
Claire 2022-06-03 10:26:09 +02:00 committed by GitHub
commit d2f5760ceb
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
168 changed files with 2077 additions and 4407 deletions

View file

@ -26,13 +26,11 @@ plugins:
bundler-audit:
enabled: true
eslint:
enabled: true
channel: eslint-7
enabled: false
rubocop:
enabled: true
channel: rubocop-1-9-1
enabled: false
sass-lint:
enabled: true
enabled: false
exclude_patterns:
- spec/
- vendor/asset/

View file

@ -12,7 +12,7 @@ module.exports = {
ATTACHMENT_HOST: false,
},
parser: 'babel-eslint',
parser: '@babel/eslint-parser',
plugins: [
'react',
@ -27,7 +27,7 @@ module.exports = {
experimentalObjectRestSpread: true,
jsx: true,
},
ecmaVersion: 2018,
ecmaVersion: 2021,
},
settings: {

71
.github/workflows/linter.yml vendored Normal file
View file

@ -0,0 +1,71 @@
---
#################################
#################################
## Super Linter GitHub Actions ##
#################################
#################################
name: Lint Code Base
#
# Documentation:
# https://docs.github.com/en/actions/learn-github-actions/workflow-syntax-for-github-actions
#
#############################
# Start the job on all push #
#############################
on:
push:
branches-ignore: [main]
# Remove the line above to run when pushing to master
pull_request:
branches: [main]
###############
# Set the Job #
###############
permissions:
checks: write
contents: read
pull-requests: write
statuses: write
jobs:
build:
# Name the Job
name: Lint Code Base
# Set the agent to run on
runs-on: ubuntu-latest
##################
# Load all steps #
##################
steps:
##########################
# Checkout the code base #
##########################
- name: Checkout Code
uses: actions/checkout@v3
with:
# Full git history is needed to get a proper list of changed files within `super-linter`
fetch-depth: 0
- name: Intall dependencies
run: yarn install --frozen-lockfile
################################
# Run Linter against code base #
################################
- name: Lint Code Base
uses: github/super-linter@v4
env:
CSS_FILE_NAME: stylelint.config.js
DEFAULT_BRANCH: main
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
JAVASCRIPT_ES_CONFIG_FILE: .eslintrc.js
LINTER_RULES_PATH: .
RUBY_CONFIG_FILE: .rubocop.yml
VALIDATE_ALL_CODEBASE: false
VALIDATE_CSS: true
VALIDATE_JAVASCRIPT_ES: true
VALIDATE_RUBY: true

View file

@ -1,37 +0,0 @@
# Linter Documentation:
# https://github.com/sasstools/sass-lint/tree/v1.13.1/docs/options
files:
include: app/javascript/styles/**/*.scss
ignore:
- app/javascript/styles/mastodon/reset.scss
rules:
# Disallows
no-color-literals: 0
no-css-comments: 0
no-duplicate-properties: 0
no-ids: 0
no-important: 0
no-mergeable-selectors: 0
no-misspelled-properties: 0
no-qualifying-elements: 0
no-transition-all: 0
no-vendor-prefixes: 0
# Nesting
force-element-nesting: 0
force-attribute-nesting: 0
force-pseudo-nesting: 0
# Name Formats
class-name-format: 0
leading-zero: 0
# Style Guide
attribute-quotes: 0
hex-length: 0
indentation: 0
nesting-depth: 0
property-sort-order: 0
quotes: 0

View file

@ -117,7 +117,7 @@ group :test do
gem 'capybara', '~> 3.37'
gem 'climate_control', '~> 0.2'
gem 'faker', '~> 2.21'
gem 'microformats', '~> 4.2'
gem 'microformats', '~> 4.4'
gem 'rails-controller-testing', '~> 1.0'
gem 'rspec-sidekiq', '~> 3.1'
gem 'simplecov', '~> 0.21', require: false

View file

@ -125,7 +125,7 @@ GEM
bullet (7.0.1)
activesupport (>= 3.0.0)
uniform_notifier (~> 1.11)
bundler-audit (0.9.0.1)
bundler-audit (0.9.1)
bundler (>= 1.2.0, < 3)
thor (~> 1.0)
byebug (11.1.3)
@ -322,7 +322,7 @@ GEM
idn-ruby (0.1.4)
ipaddress (0.8.3)
jmespath (1.6.1)
json (2.5.1)
json (2.6.2)
json-canonicalization (0.3.0)
json-jwt (1.13.0)
activesupport (>= 4.2)
@ -389,7 +389,7 @@ GEM
matrix (0.4.2)
memory_profiler (1.0.0)
method_source (1.0.0)
microformats (4.3.1)
microformats (4.4.1)
json (~> 2.2)
nokogiri (~> 1.10)
mime-types (3.4.1)
@ -414,7 +414,7 @@ GEM
concurrent-ruby (~> 1.0, >= 1.0.2)
sidekiq (>= 3.5)
statsd-ruby (~> 1.4, >= 1.4.0)
oj (3.13.11)
oj (3.13.13)
omniauth (1.9.1)
hashie (>= 3.4.6)
rack (>= 1.6.2, < 3)
@ -476,7 +476,7 @@ GEM
activesupport (>= 3.0.0)
raabro (1.4.0)
racc (1.6.0)
rack (2.2.3)
rack (2.2.3.1)
rack-attack (6.6.1)
rack (>= 1.0, < 3)
rack-cors (1.1.1)
@ -614,7 +614,7 @@ GEM
rufus-scheduler (~> 3.2)
sidekiq (>= 4)
tilt (>= 1.4.0)
sidekiq-unique-jobs (7.1.22)
sidekiq-unique-jobs (7.1.23)
brpoplpush-redis_script (> 0.1.1, <= 2.0.0)
concurrent-ruby (~> 1.0, >= 1.0.5)
sidekiq (>= 5.0, < 8.0)
@ -787,7 +787,7 @@ DEPENDENCIES
makara (~> 0.5)
mario-redis-lock (~> 1.2)
memory_profiler
microformats (~> 4.2)
microformats (~> 4.4)
mime-types (~> 3.4.1)
net-ldap (~> 0.17)
nokogiri (~> 1.13)

View file

@ -0,0 +1,109 @@
# frozen_string_literal: true
class Api::V1::Admin::DomainBlocksController < Api::BaseController
include Authorization
include AccountableConcern
LIMIT = 100
before_action -> { authorize_if_got_token! :'admin:read', :'admin:read:domain_blocks' }, only: [:index, :show]
before_action -> { authorize_if_got_token! :'admin:write', :'admin:write:domain_blocks' }, except: [:index, :show]
before_action :require_staff!
before_action :set_domain_blocks, only: :index
before_action :set_domain_block, only: [:show, :update, :destroy]
after_action :insert_pagination_headers, only: :index
PAGINATION_PARAMS = %i(limit).freeze
def create
authorize :domain_block, :create?
existing_domain_block = resource_params[:domain].present? ? DomainBlock.rule_for(resource_params[:domain]) : nil
return render json: existing_domain_block, serializer: REST::Admin::ExistingDomainBlockErrorSerializer, status: 422 if existing_domain_block.present?
@domain_block = DomainBlock.create!(resource_params)
DomainBlockWorker.perform_async(@domain_block.id)
log_action :create, @domain_block
render json: @domain_block, serializer: REST::Admin::DomainBlockSerializer
end
def index
authorize :domain_block, :index?
render json: @domain_blocks, each_serializer: REST::Admin::DomainBlockSerializer
end
def show
authorize @domain_block, :show?
render json: @domain_block, serializer: REST::Admin::DomainBlockSerializer
end
def update
authorize @domain_block, :update?
@domain_block.update(domain_block_params)
severity_changed = @domain_block.severity_changed?
@domain_block.save!
DomainBlockWorker.perform_async(@domain_block.id, severity_changed)
log_action :update, @domain_block
render json: @domain_block, serializer: REST::Admin::DomainBlockSerializer
end
def destroy
authorize @domain_block, :destroy?
UnblockDomainService.new.call(@domain_block)
log_action :destroy, @domain_block
render json: @domain_block, serializer: REST::Admin::DomainBlockSerializer
end
private
def set_domain_blocks
@domain_blocks = filtered_domain_blocks.order(id: :desc).to_a_paginated_by_id(limit_param(LIMIT), params_slice(:max_id, :since_id, :min_id))
end
def set_domain_block
@domain_block = DomainBlock.find(params[:id])
end
def filtered_domain_blocks
# TODO: no filtering yet
DomainBlock.all
end
def domain_block_params
params.permit(:severity, :reject_media, :reject_reports, :private_comment, :public_comment, :obfuscate)
end
def insert_pagination_headers
set_pagination_headers(next_path, prev_path)
end
def next_path
api_v1_admin_domain_blocks_url(pagination_params(max_id: pagination_max_id)) if records_continue?
end
def prev_path
api_v1_admin_domain_blocks_url(pagination_params(min_id: pagination_since_id)) unless @domain_blocks.empty?
end
def pagination_max_id
@domain_blocks.last.id
end
def pagination_since_id
@domain_blocks.first.id
end
def records_continue?
@domain_blocks.size == limit_param(LIMIT)
end
def pagination_params(core_params)
params.slice(*PAGINATION_PARAMS).permit(*PAGINATION_PARAMS).merge(core_params)
end
def resource_params
params.permit(:domain, :severity, :reject_media, :reject_reports, :private_comment, :public_comment, :obfuscate)
end
end

View file

@ -83,7 +83,8 @@ module ApplicationHelper
end
def provider_sign_in_link(provider)
link_to I18n.t("auth.providers.#{provider}", default: provider.to_s.chomp('_oauth2').capitalize), omniauth_authorize_path(:user, provider), class: "button button-#{provider}", method: :post
label = Devise.omniauth_configs[provider]&.strategy&.display_name.presence || I18n.t("auth.providers.#{provider}", default: provider.to_s.chomp('_oauth2').capitalize)
link_to label, omniauth_authorize_path(:user, provider), class: "button button-#{provider}", method: :post
end
def open_deletion?

View file

@ -67,7 +67,6 @@ class Status extends ImmutablePureComponent {
containerId: PropTypes.string,
id: PropTypes.string,
status: ImmutablePropTypes.map,
otherAccounts: ImmutablePropTypes.list,
account: ImmutablePropTypes.map,
onReply: PropTypes.func,
onFavourite: PropTypes.func,
@ -492,7 +491,6 @@ class Status extends ImmutablePureComponent {
intl,
status,
account,
otherAccounts,
settings,
collapsed,
muted,
@ -745,7 +743,6 @@ class Status extends ImmutablePureComponent {
friend={account}
collapsed={isCollapsed}
parseClick={parseClick}
otherAccounts={otherAccounts}
/>
) : null}
</span>
@ -755,7 +752,6 @@ class Status extends ImmutablePureComponent {
collapsible={settings.getIn(['collapsed', 'enabled'])}
collapsed={isCollapsed}
setCollapsed={setCollapsed}
directMessage={!!otherAccounts}
settings={settings.get('status_icons')}
/>
</header>
@ -776,7 +772,6 @@ class Status extends ImmutablePureComponent {
status={status}
account={status.get('account')}
showReplyCount={settings.get('show_reply_count')}
directMessage={!!otherAccounts}
onFilter={this.handleFilterClick}
/>
) : null}

View file

@ -67,7 +67,6 @@ class StatusActionBar extends ImmutablePureComponent {
onFilter: PropTypes.func,
withDismiss: PropTypes.bool,
showReplyCount: PropTypes.bool,
directMessage: PropTypes.bool,
scrollKey: PropTypes.string,
intl: PropTypes.object.isRequired,
};
@ -197,7 +196,7 @@ class StatusActionBar extends ImmutablePureComponent {
}
render () {
const { status, intl, withDismiss, showReplyCount, directMessage, scrollKey } = this.props;
const { status, intl, withDismiss, showReplyCount, scrollKey } = this.props;
const anonymousAccess = !me;
const mutingConversation = status.get('muted');
@ -311,13 +310,13 @@ class StatusActionBar extends ImmutablePureComponent {
return (
<div className='status__action-bar'>
{replyButton}
{!directMessage && [
<IconButton key='reblog-button' className={classNames('status__action-bar-button', { reblogPrivate })} disabled={!publicStatus && !reblogPrivate} active={status.get('reblogged')} pressed={status.get('reblogged')} title={reblogTitle} icon={reblogIcon} onClick={this.handleReblogClick} />,
<IconButton key='favourite-button' className='status__action-bar-button star-icon' animate active={status.get('favourited')} pressed={status.get('favourited')} title={intl.formatMessage(messages.favourite)} icon='star' onClick={this.handleFavouriteClick} />,
shareButton,
<IconButton key='bookmark-button' className='status__action-bar-button bookmark-icon' disabled={anonymousAccess} active={status.get('bookmarked')} pressed={status.get('bookmarked')} title={intl.formatMessage(messages.bookmark)} icon='bookmark' onClick={this.handleBookmarkClick} />,
filterButton,
<div key='dropdown-button' className='status__action-bar-dropdown'>
<IconButton className={classNames('status__action-bar-button', { reblogPrivate })} disabled={!publicStatus && !reblogPrivate} active={status.get('reblogged')} pressed={status.get('reblogged')} title={reblogTitle} icon={reblogIcon} onClick={this.handleReblogClick} />
<IconButton className='status__action-bar-button star-icon' animate active={status.get('favourited')} pressed={status.get('favourited')} title={intl.formatMessage(messages.favourite)} icon='star' onClick={this.handleFavouriteClick} />
{shareButton}
<IconButton className='status__action-bar-button bookmark-icon' disabled={anonymousAccess} active={status.get('bookmarked')} pressed={status.get('bookmarked')} title={intl.formatMessage(messages.bookmark)} icon='bookmark' onClick={this.handleBookmarkClick} />
{filterButton}
<div className='status__action-bar-dropdown'>
<DropdownMenuContainer
scrollKey={scrollKey}
disabled={anonymousAccess}
@ -328,8 +327,7 @@ class StatusActionBar extends ImmutablePureComponent {
direction='right'
ariaLabel={intl.formatMessage(messages.more)}
/>
</div>,
]}
</div>
<a href={status.get('url')} className='status__relative-time' target='_blank' rel='noopener'>
<RelativeTimestamp timestamp={status.get('created_at')} />{status.get('edited_at') && <abbr title={intl.formatMessage(messages.edited, { date: intl.formatDate(status.get('edited_at'), { hour12: false, year: 'numeric', month: 'short', day: '2-digit', hour: '2-digit', minute: '2-digit' }) })}> *</abbr>}

View file

@ -267,6 +267,7 @@ export default class StatusContent extends React.PureComponent {
const content = { __html: status.get('contentHtml') };
const spoilerContent = { __html: status.get('spoilerHtml') };
const lang = status.get('language');
const classNames = classnames('status__content', {
'status__content--with-action': parseClick && !disabled,
'status__content--with-spoiler': status.get('spoiler_text').length > 0,
@ -327,7 +328,7 @@ export default class StatusContent extends React.PureComponent {
<p
style={{ marginBottom: hidden && status.get('mentions').isEmpty() ? '0px' : null }}
>
<span dangerouslySetInnerHTML={spoilerContent} className='translate' />
<span dangerouslySetInnerHTML={spoilerContent} className='translate' lang={lang} />
{' '}
<button tabIndex='0' className='status__content__spoiler-link' onClick={this.handleSpoilerClick}>
{toggleText}
@ -345,6 +346,7 @@ export default class StatusContent extends React.PureComponent {
className='status__content__text translate'
onMouseEnter={this.handleMouseEnter}
onMouseLeave={this.handleMouseLeave}
lang={lang}
/>
{media}
</div>
@ -367,6 +369,7 @@ export default class StatusContent extends React.PureComponent {
tabIndex='0'
onMouseEnter={this.handleMouseEnter}
onMouseLeave={this.handleMouseLeave}
lang={lang}
/>
{media}
</div>
@ -385,6 +388,7 @@ export default class StatusContent extends React.PureComponent {
tabIndex='0'
onMouseEnter={this.handleMouseEnter}
onMouseLeave={this.handleMouseLeave}
lang={lang}
/>
{media}
</div>

View file

@ -15,7 +15,6 @@ export default class StatusHeader extends React.PureComponent {
status: ImmutablePropTypes.map.isRequired,
friend: ImmutablePropTypes.map,
parseClick: PropTypes.func.isRequired,
otherAccounts: ImmutablePropTypes.list,
};
// Handles clicks on account name/image
@ -34,21 +33,17 @@ export default class StatusHeader extends React.PureComponent {
const {
status,
friend,
otherAccounts,
} = this.props;
const account = status.get('account');
let statusAvatar;
if (otherAccounts && otherAccounts.size > 0) {
statusAvatar = <AvatarComposite accounts={otherAccounts} size={48} onAccountClick={this.handleClick} />;
} else if (friend === undefined || friend === null) {
if (friend === undefined || friend === null) {
statusAvatar = <Avatar account={account} size={48} />;
} else {
statusAvatar = <AvatarOverlay account={account} friend={friend} />;
}
if (!otherAccounts) {
return (
<div className='status__info__account'>
<a
@ -67,24 +62,10 @@ export default class StatusHeader extends React.PureComponent {
onClick={this.handleAccountClick}
rel='noopener noreferrer'
>
<DisplayName account={account} others={otherAccounts} />
<DisplayName account={account} />
</a>
</div>
);
} else {
// This is a DM conversation
return (
<div className='status__info__account'>
<span className='status__avatar'>
{statusAvatar}
</span>
<span className='status__display-name'>
<DisplayName account={account} others={otherAccounts} onAccountClick={this.handleClick} />
</span>
</div>
);
}
}
}

View file

@ -48,7 +48,6 @@ class StatusIcons extends React.PureComponent {
mediaIcons: PropTypes.arrayOf(PropTypes.string),
collapsible: PropTypes.bool,
collapsed: PropTypes.bool,
directMessage: PropTypes.bool,
setCollapsed: PropTypes.func.isRequired,
intl: PropTypes.object.isRequired,
settings: ImmutablePropTypes.map.isRequired,
@ -100,7 +99,6 @@ class StatusIcons extends React.PureComponent {
mediaIcons,
collapsible,
collapsed,
directMessage,
settings,
intl,
} = this.props;
@ -125,7 +123,7 @@ class StatusIcons extends React.PureComponent {
title={intl.formatMessage(messages.localOnly)}
/>}
{settings.get('media') && !!mediaIcons && mediaIcons.map(icon => this.renderIcon(icon))}
{settings.get('visibility') && !directMessage && <VisibilityIcon visibility={status.get('visibility')} />}
{settings.get('visibility') && <VisibilityIcon visibility={status.get('visibility')} />}
{collapsible && (
<IconButton
className='status__collapse-button'

View file

@ -16,7 +16,7 @@ import { maxChars } from 'flavours/glitch/util/initial_state';
// Messages.
const messages = defineMessages({
publish: {
defaultMessage: 'Toot',
defaultMessage: 'Publish',
id: 'compose_form.publish',
},
publishLoud: {

View file

@ -419,6 +419,10 @@ export default function compose(state = initialState, action) {
map.set('preselectDate', new Date());
map.set('idempotencyKey', uuid());
if (action.status.get('language')) {
map.set('language', action.status.get('language'));
}
if (action.status.get('spoiler_text').length > 0) {
let spoiler_text = action.status.get('spoiler_text');
if (action.prependCWRe && !spoiler_text.match(/^re[: ]/i)) {

Binary file not shown.

Before

Width:  |  Height:  |  Size: 34 KiB

View file

@ -1 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 216.41507 232.00976"><path d="M211.80683 139.0875c-3.1825 16.36625-28.4925 34.2775-57.5625 37.74875-15.16 1.80875-30.0825 3.47125-45.99875 2.74125-26.0275-1.1925-46.565-6.2125-46.565-6.2125 0 2.53375.15625 4.94625.46875 7.2025 3.38375 25.68625 25.47 27.225 46.3925 27.9425 21.115.7225 39.91625-5.20625 39.91625-5.20625l.86875 19.09s-14.77 7.93125-41.08125 9.39c-14.50875.7975-32.52375-.365-53.50625-5.91875C9.23183 213.82 1.40558 165.31125.20808 116.09125c-.36375-14.61375-.14-28.39375-.14-39.91875 0-50.33 32.97625-65.0825 32.97625-65.0825C49.67058 3.45375 78.20308.2425 107.86433 0h.72875c29.66125.2425 58.21125 3.45375 74.8375 11.09 0 0 32.97625 14.7525 32.97625 65.0825 0 0 .4125 37.13375-4.6 62.915" fill="#3088d4"/><path d="M65.68743 96.45938c0 9.01375-7.3075 16.32125-16.3225 16.32125-9.01375 0-16.32-7.3075-16.32-16.32125 0-9.01375 7.30625-16.3225 16.32-16.3225 9.015 0 16.3225 7.30875 16.3225 16.3225M124.52893 96.45938c0 9.01375-7.30875 16.32125-16.3225 16.32125-9.01375 0-16.32125-7.3075-16.32125-16.32125 0-9.01375 7.3075-16.3225 16.32125-16.3225 9.01375 0 16.3225 7.30875 16.3225 16.3225M183.36933 96.45938c0 9.01375-7.3075 16.32125-16.32125 16.32125-9.01375 0-16.32125-7.3075-16.32125-16.32125 0-9.01375 7.3075-16.3225 16.32125-16.3225 9.01375 0 16.32125 7.30875 16.32125 16.3225" fill="#fff"/></svg>

Before

Width:  |  Height:  |  Size: 1.3 KiB

View file

@ -1 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 216.4144 232.00976"><path d="M107.86523 0C78.203984.2425 49.672422 3.4535937 33.044922 11.089844c0 0-32.97656262 14.752031-32.97656262 65.082031 0 11.525-.224375 25.306175.140625 39.919925 1.19750002 49.22 9.02375002 97.72843 54.53124962 109.77343 20.9825 5.55375 38.99711 6.71547 53.505856 5.91797 26.31125-1.45875 41.08203-9.38867 41.08203-9.38867l-.86914-19.08984s-18.80171 5.92758-39.91796 5.20508c-20.921254-.7175-43.006879-2.25516-46.390629-27.94141-.3125-2.25625-.46875-4.66938-.46875-7.20313 0 0 20.536953 5.0204 46.564449 6.21289 15.915.73001 30.8393-.93343 45.99805-2.74218 29.07-3.47125 54.38125-21.3818 57.5625-37.74805 5.0125-25.78125 4.59961-62.916015 4.59961-62.916015 0-50.33-32.97461-65.082031-32.97461-65.082031C166.80539 3.4535938 138.255.2425 108.59375 0h-.72852zM74.296875 39.326172c12.355 0 21.710234 4.749297 27.896485 14.248047l6.01367 10.080078 6.01563-10.080078c6.185-9.49875 15.54023-14.248047 27.89648-14.248047 10.6775 0 19.28156 3.753672 25.85156 11.076172 6.36875 7.3225 9.53907 17.218828 9.53907 29.673828v60.941408h-24.14454V81.869141c0-12.46875-5.24453-18.798829-15.73828-18.798829-11.6025 0-17.41797 7.508516-17.41797 22.353516v32.375002H96.207031V85.423828c0-14.845-5.815468-22.353515-17.417969-22.353516-10.49375 0-15.740234 6.330079-15.740234 18.798829v59.148439H38.904297V80.076172c0-12.455 3.171016-22.351328 9.541015-29.673828 6.568751-7.3225 15.172813-11.076172 25.851563-11.076172z" fill="#000"/></svg>

Before

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 12 KiB

File diff suppressed because one or more lines are too long

Before

Width:  |  Height:  |  Size: 37 KiB

File diff suppressed because one or more lines are too long

Before

Width:  |  Height:  |  Size: 8.8 KiB

File diff suppressed because one or more lines are too long

Before

Width:  |  Height:  |  Size: 27 KiB

View file

@ -3,7 +3,6 @@ import ImmutablePropTypes from 'react-immutable-proptypes';
import PropTypes from 'prop-types';
import Avatar from './avatar';
import AvatarOverlay from './avatar_overlay';
import AvatarComposite from './avatar_composite';
import RelativeTimestamp from './relative_timestamp';
import DisplayName from './display_name';
import StatusContent from './status_content';
@ -70,7 +69,6 @@ class Status extends ImmutablePureComponent {
static propTypes = {
status: ImmutablePropTypes.map,
account: ImmutablePropTypes.map,
otherAccounts: ImmutablePropTypes.list,
onClick: PropTypes.func,
onReply: PropTypes.func,
onFavourite: PropTypes.func,
@ -297,7 +295,7 @@ class Status extends ImmutablePureComponent {
let media = null;
let statusAvatar, prepend, rebloggedByText;
const { intl, hidden, featured, otherAccounts, unread, showThread, scrollKey, pictureInPicture } = this.props;
const { intl, hidden, featured, unread, showThread, scrollKey, pictureInPicture } = this.props;
let { status, account, ...other } = this.props;
@ -456,9 +454,7 @@ class Status extends ImmutablePureComponent {
);
}
if (otherAccounts && otherAccounts.size > 0) {
statusAvatar = <AvatarComposite accounts={otherAccounts} size={48} />;
} else if (account === undefined || account === null) {
if (account === undefined || account === null) {
statusAvatar = <Avatar account={status.get('account')} size={48} />;
} else {
statusAvatar = <AvatarOverlay account={status.get('account')} friend={account} />;
@ -492,7 +488,7 @@ class Status extends ImmutablePureComponent {
{statusAvatar}
</div>
<DisplayName account={status.get('account')} others={otherAccounts} />
<DisplayName account={status.get('account')} />
</a>
</div>

View file

@ -176,6 +176,7 @@ export default class StatusContent extends React.PureComponent {
const content = { __html: status.get('contentHtml') };
const spoilerContent = { __html: status.get('spoilerHtml') };
const lang = status.get('language');
const classNames = classnames('status__content', {
'status__content--with-action': this.props.onClick && this.context.router,
'status__content--with-spoiler': status.get('spoiler_text').length > 0,
@ -212,14 +213,14 @@ export default class StatusContent extends React.PureComponent {
return (
<div className={classNames} ref={this.setRef} tabIndex='0' onMouseDown={this.handleMouseDown} onMouseUp={this.handleMouseUp} onMouseEnter={this.handleMouseEnter} onMouseLeave={this.handleMouseLeave}>
<p style={{ marginBottom: hidden && status.get('mentions').isEmpty() ? '0px' : null }}>
<span dangerouslySetInnerHTML={spoilerContent} className='translate' />
<span dangerouslySetInnerHTML={spoilerContent} className='translate' lang={lang} />
{' '}
<button tabIndex='0' className={`status__content__spoiler-link ${hidden ? 'status__content__spoiler-link--show-more' : 'status__content__spoiler-link--show-less'}`} onClick={this.handleSpoilerClick}>{toggleText}</button>
</p>
{mentionsPlaceholder}
<div tabIndex={!hidden ? 0 : null} className={`status__content__text ${!hidden ? 'status__content__text--visible' : ''} translate`} dangerouslySetInnerHTML={content} />
<div tabIndex={!hidden ? 0 : null} className={`status__content__text ${!hidden ? 'status__content__text--visible' : ''} translate`} lang={lang} dangerouslySetInnerHTML={content} />
{!hidden && !!status.get('poll') && <PollContainer pollId={status.get('poll')} />}
@ -229,7 +230,7 @@ export default class StatusContent extends React.PureComponent {
} else if (this.props.onClick) {
const output = [
<div className={classNames} ref={this.setRef} tabIndex='0' onMouseDown={this.handleMouseDown} onMouseUp={this.handleMouseUp} key='status-content' onMouseEnter={this.handleMouseEnter} onMouseLeave={this.handleMouseLeave}>
<div className='status__content__text status__content__text--visible translate' dangerouslySetInnerHTML={content} />
<div className='status__content__text status__content__text--visible translate' lang={lang} dangerouslySetInnerHTML={content} />
{!!status.get('poll') && <PollContainer pollId={status.get('poll')} />}
@ -245,7 +246,7 @@ export default class StatusContent extends React.PureComponent {
} else {
return (
<div className={classNames} ref={this.setRef} tabIndex='0' onMouseEnter={this.handleMouseEnter} onMouseLeave={this.handleMouseLeave}>
<div className='status__content__text status__content__text--visible translate' dangerouslySetInnerHTML={content} />
<div className='status__content__text status__content__text--visible translate' lang={lang} dangerouslySetInnerHTML={content} />
{!!status.get('poll') && <PollContainer pollId={status.get('poll')} />}

View file

@ -28,7 +28,7 @@ const allowedAroundShortCode = '><\u0085\u0020\u00a0\u1680\u2000\u2001\u2002\u20
const messages = defineMessages({
placeholder: { id: 'compose_form.placeholder', defaultMessage: 'What is on your mind?' },
spoiler_placeholder: { id: 'compose_form.spoiler_placeholder', defaultMessage: 'Write your warning here' },
publish: { id: 'compose_form.publish', defaultMessage: 'Toot' },
publish: { id: 'compose_form.publish', defaultMessage: 'Publish' },
publishLoud: { id: 'compose_form.publish_loud', defaultMessage: '{publish}!' },
saveChanges: { id: 'compose_form.save_changes', defaultMessage: 'Save changes' },
});

View file

@ -1,197 +0,0 @@
import React from 'react';
import PropTypes from 'prop-types';
import ReactSwipeableViews from 'react-swipeable-views';
import classNames from 'classnames';
import { connect } from 'react-redux';
import { FormattedMessage } from 'react-intl';
import { closeOnboarding } from '../../actions/onboarding';
import screenHello from '../../../images/screen_hello.svg';
import screenFederation from '../../../images/screen_federation.svg';
import screenInteractions from '../../../images/screen_interactions.svg';
import logoTransparent from '../../../images/logo_transparent.svg';
import { disableSwiping } from 'mastodon/initial_state';
const FrameWelcome = ({ domain, onNext }) => (
<div className='introduction__frame'>
<div className='introduction__illustration' style={{ background: `url(${logoTransparent}) no-repeat center center / auto 80%` }}>
<img src={screenHello} alt='' />
</div>
<div className='introduction__text introduction__text--centered'>
<h3><FormattedMessage id='introduction.welcome.headline' defaultMessage='First steps' /></h3>
<p><FormattedMessage id='introduction.welcome.text' defaultMessage="Welcome to the fediverse! In a few moments, you'll be able to broadcast messages and talk to your friends across a wide variety of servers. But this server, {domain}, is special—it hosts your profile, so remember its name." values={{ domain: <code>{domain}</code> }} /></p>
</div>
<div className='introduction__action'>
<button className='button' onClick={onNext}><FormattedMessage id='introduction.welcome.action' defaultMessage="Let's go!" /></button>
</div>
</div>
);
FrameWelcome.propTypes = {
domain: PropTypes.string.isRequired,
onNext: PropTypes.func.isRequired,
};
const FrameFederation = ({ onNext }) => (
<div className='introduction__frame'>
<div className='introduction__illustration'>
<img src={screenFederation} alt='' />
</div>
<div className='introduction__text introduction__text--columnized'>
<div>
<h3><FormattedMessage id='introduction.federation.home.headline' defaultMessage='Home' /></h3>
<p><FormattedMessage id='introduction.federation.home.text' defaultMessage='Posts from people you follow will appear in your home feed. You can follow anyone on any server!' /></p>
</div>
<div>
<h3><FormattedMessage id='introduction.federation.local.headline' defaultMessage='Local' /></h3>
<p><FormattedMessage id='introduction.federation.local.text' defaultMessage='Public posts from people on the same server as you will appear in the local timeline.' /></p>
</div>
<div>
<h3><FormattedMessage id='introduction.federation.federated.headline' defaultMessage='Federated' /></h3>
<p><FormattedMessage id='introduction.federation.federated.text' defaultMessage='Public posts from other servers of the fediverse will appear in the federated timeline.' /></p>
</div>
</div>
<div className='introduction__action'>
<button className='button' onClick={onNext}><FormattedMessage id='introduction.federation.action' defaultMessage='Next' /></button>
</div>
</div>
);
FrameFederation.propTypes = {
onNext: PropTypes.func.isRequired,
};
const FrameInteractions = ({ onNext }) => (
<div className='introduction__frame'>
<div className='introduction__illustration'>
<img src={screenInteractions} alt='' />
</div>
<div className='introduction__text introduction__text--columnized'>
<div>
<h3><FormattedMessage id='introduction.interactions.reply.headline' defaultMessage='Reply' /></h3>
<p><FormattedMessage id='introduction.interactions.reply.text' defaultMessage="You can reply to other people's and your own toots, which will chain them together in a conversation." /></p>
</div>
<div>
<h3><FormattedMessage id='introduction.interactions.reblog.headline' defaultMessage='Boost' /></h3>
<p><FormattedMessage id='introduction.interactions.reblog.text' defaultMessage="You can share other people's toots with your followers by boosting them." /></p>
</div>
<div>
<h3><FormattedMessage id='introduction.interactions.favourite.headline' defaultMessage='Favourite' /></h3>
<p><FormattedMessage id='introduction.interactions.favourite.text' defaultMessage='You can save a toot for later, and let the author know that you liked it, by favouriting it.' /></p>
</div>
</div>
<div className='introduction__action'>
<button className='button' onClick={onNext}><FormattedMessage id='introduction.interactions.action' defaultMessage='Finish toot-orial!' /></button>
</div>
</div>
);
FrameInteractions.propTypes = {
onNext: PropTypes.func.isRequired,
};
export default @connect(state => ({ domain: state.getIn(['meta', 'domain']) }))
class Introduction extends React.PureComponent {
static propTypes = {
domain: PropTypes.string.isRequired,
dispatch: PropTypes.func.isRequired,
};
state = {
currentIndex: 0,
};
componentWillMount () {
this.pages = [
<FrameWelcome domain={this.props.domain} onNext={this.handleNext} />,
<FrameFederation onNext={this.handleNext} />,
<FrameInteractions onNext={this.handleFinish} />,
];
}
componentDidMount() {
window.addEventListener('keyup', this.handleKeyUp);
}
componentWillUnmount() {
window.addEventListener('keyup', this.handleKeyUp);
}
handleDot = (e) => {
const i = Number(e.currentTarget.getAttribute('data-index'));
e.preventDefault();
this.setState({ currentIndex: i });
}
handlePrev = () => {
this.setState(({ currentIndex }) => ({
currentIndex: Math.max(0, currentIndex - 1),
}));
}
handleNext = () => {
const { pages } = this;
this.setState(({ currentIndex }) => ({
currentIndex: Math.min(currentIndex + 1, pages.length - 1),
}));
}
handleSwipe = (index) => {
this.setState({ currentIndex: index });
}
handleFinish = () => {
this.props.dispatch(closeOnboarding());
}
handleKeyUp = ({ key }) => {
switch (key) {
case 'ArrowLeft':
this.handlePrev();
break;
case 'ArrowRight':
this.handleNext();
break;
}
}
render () {
const { currentIndex } = this.state;
const { pages } = this;
return (
<div className='introduction'>
<ReactSwipeableViews index={currentIndex} onChangeIndex={this.handleSwipe} disabled={disableSwiping} className='introduction__pager'>
{pages.map((page, i) => (
<div key={i} className={classNames('introduction__frame-wrapper', { 'active': i === currentIndex })}>{page}</div>
))}
</ReactSwipeableViews>
<div className='introduction__dots'>
{pages.map((_, i) => (
<div
key={`dot-${i}`}
role='button'
tabIndex='0'
data-index={i}
onClick={this.handleDot}
className={classNames('introduction__dot', { active: i === currentIndex })}
/>
))}
</div>
</div>
);
}
}

View file

@ -95,7 +95,7 @@
"compose.language.change": "Verander taal",
"compose.language.search": "Soek tale...",
"compose_form.direct_message_warning_learn_more": "Leer meer",
"compose_form.encryption_warning": "Plasings op Mastodon het nie end-tot-end enkripsie nie. Moet nie enige gevaarlike inligting oor Mastodon deel nie.",
"compose_form.encryption_warning": "Plasings op Mastodon het nie end-tot-end enkripsie nie. Moet nie enige sensitiewe inligting oor Mastodon deel nie.",
"compose_form.hashtag_warning": "This toot won't be listed under any hashtag as it is unlisted. Only public toots can be searched by hashtag.",
"compose_form.lock_disclaimer": "Your account is not {locked}. Anyone can follow you to view your follower-only posts.",
"compose_form.lock_disclaimer.lock": "gesluit",

View file

@ -95,7 +95,7 @@
"compose.language.change": "تغيير اللغة",
"compose.language.search": "البحث عن لغة…",
"compose_form.direct_message_warning_learn_more": "تَعَلَّم المَزيد",
"compose_form.encryption_warning": "إنّ المنشورات على ماستدون ليست مشفرة من النهاية إلى النهاية. لا تشارك أي معلومات حساسة عبر ماستدون.",
"compose_form.encryption_warning": "Posts on Mastodon are not end-to-end encrypted. Do not share any dangerous information over Mastodon.",
"compose_form.hashtag_warning": "لن يُدرَج هذا المنشور تحت أي وسم بما أنَّه غير مُدرَج. فقط المنشورات العامة يُمكن البحث عنها بواسطة الوسم.",
"compose_form.lock_disclaimer": "حسابُك غير {locked}. يُمكن لأي شخص مُتابعتك لرؤية (منشورات المتابعين فقط).",
"compose_form.lock_disclaimer.lock": "مُقفَل",

View file

@ -95,7 +95,7 @@
"compose.language.change": "Canvia d'idioma",
"compose.language.search": "Cerca idiomes...",
"compose_form.direct_message_warning_learn_more": "Més informació",
"compose_form.encryption_warning": "Les publicacions a Mastodon no estant xifrades punt a punt. No comparteixis informació perillosa mitjançant Mastodon.",
"compose_form.encryption_warning": "Les publicacions a Mastodon no estant xifrades punt a punt. No comparteixis informació sensible mitjançant Mastodon.",
"compose_form.hashtag_warning": "Aquesta publicació no es mostrarà en cap etiqueta, ja que no està llistada. Només les publicacions públiques es poden cercar per etiqueta.",
"compose_form.lock_disclaimer": "El teu compte no està {locked}. Tothom pot seguir-te i veure les publicacions de només per a seguidors.",
"compose_form.lock_disclaimer.lock": "bloquejat",

View file

@ -95,7 +95,7 @@
"compose.language.change": "Změnit jazyk",
"compose.language.search": "Prohledat jazyky...",
"compose_form.direct_message_warning_learn_more": "Zjistit více",
"compose_form.encryption_warning": "Příspěvky na Mastodonu nejsou end-to-end šifrovány. Nesdílejte přes Mastodon žádné nebezpečné informace.",
"compose_form.encryption_warning": "Příspěvky na Mastodonu nejsou end-to-end šifrovány. Nesdílejte přes Mastodon žádné citlivé informace.",
"compose_form.hashtag_warning": "Tento příspěvek nebude zobrazen pod žádným hashtagem, neboť je neuvedený. Pouze veřejné příspěvky mohou být vyhledány podle hashtagu.",
"compose_form.lock_disclaimer": "Váš účet není {locked}. Kdokoliv vás může sledovat a vidět vaše příspěvky učené pouze pro sledující.",
"compose_form.lock_disclaimer.lock": "uzamčen",

View file

@ -95,7 +95,7 @@
"compose.language.change": "Change language",
"compose.language.search": "Search languages...",
"compose_form.direct_message_warning_learn_more": "Dysgu mwy",
"compose_form.encryption_warning": "Dyw postiadau ar Mastodon ddim wedi'u hamgryptio o ben i ben. Peidiwch â rhannu unrhyw wybodaeth beryglus dros Mastodon.",
"compose_form.encryption_warning": "Posts on Mastodon are not end-to-end encrypted. Do not share any dangerous information over Mastodon.",
"compose_form.hashtag_warning": "Ni fydd y post hwn wedi ei restru o dan unrhyw hashnod gan ei fod heb ei restru. Dim ond postiadau cyhoeddus gellid chwilio amdanynt drwy hashnod.",
"compose_form.lock_disclaimer": "Nid yw eich cyfri wedi'i {locked}. Gall unrhyw un eich dilyn i weld eich postiadau dilynwyr-yn-unig.",
"compose_form.lock_disclaimer.lock": "wedi ei gloi",

View file

@ -95,7 +95,7 @@
"compose.language.change": "Change language",
"compose.language.search": "Search languages...",
"compose_form.direct_message_warning_learn_more": "Få mere at vide",
"compose_form.encryption_warning": "Indlæg på Mastodon er ikke ende-til-ende krypteret. Del derfor ikke sensitiv information over Mastodon.",
"compose_form.encryption_warning": "Indlæg på Mastodon er ikke ende-til-ende krypteret. Del derfor ikke sensitiv information via Mastodon.",
"compose_form.hashtag_warning": "Da indlægget ikke er offentligt, vises det ikke under noget hashtag, idet kun offentlige indlæg kan søges via hashtags.",
"compose_form.lock_disclaimer": "Din konto er ikke {locked}. Enhver kan følge dig og se indlæg kun beregnet for følgere.",
"compose_form.lock_disclaimer.lock": "låst",

View file

@ -95,7 +95,7 @@
"compose.language.change": "Sprache ändern",
"compose.language.search": "Sprachen durchsuchen...",
"compose_form.direct_message_warning_learn_more": "Mehr erfahren",
"compose_form.encryption_warning": "Beiträge auf Mastodon sind nicht Ende-zu-Ende-verschlüsselt. Teile keine sensiblen Informationen über Mastodon.",
"compose_form.encryption_warning": "Posts on Mastodon are not end-to-end encrypted. Do not share any dangerous information over Mastodon.",
"compose_form.hashtag_warning": "Dieser Beitrag wird nicht durch Hashtags entdeckbar sein, weil er ungelistet ist. Nur öffentliche Beiträge tauchen in Hashtag-Zeitleisten auf.",
"compose_form.lock_disclaimer": "Dein Profil ist nicht {locked}. Wer dir folgen will, kann das jederzeit tun und dann auch deine privaten Beiträge sehen.",
"compose_form.lock_disclaimer.lock": "gesperrt",

View file

@ -1182,7 +1182,7 @@
"id": "compose_form.spoiler_placeholder"
},
{
"defaultMessage": "Toot",
"defaultMessage": "Publish",
"id": "compose_form.publish"
},
{
@ -1546,7 +1546,7 @@
"id": "compose_form.hashtag_warning"
},
{
"defaultMessage": "Posts on Mastodon are not end-to-end encrypted. Do not share any sensitive information over Mastodon.",
"defaultMessage": "Posts on Mastodon are not end-to-end encrypted. Do not share any dangerous information over Mastodon.",
"id": "compose_form.encryption_warning"
},
{

View file

@ -95,7 +95,7 @@
"compose.language.change": "Αλλαγή γλώσσας",
"compose.language.search": "Αναζήτηση γλωσσών...",
"compose_form.direct_message_warning_learn_more": "Μάθετε περισσότερα",
"compose_form.encryption_warning": "Οι δημοσιεύσεις στο Mastodon δεν είναι κρυπτογραφημένες από άκρο σε άκρο. Μην μοιράζεστε επικίνδυνες πληροφορίες μέσω του Mastodon.",
"compose_form.encryption_warning": "Οι δημοσιεύσεις στο Mastodon δεν είναι κρυπτογραφημένες από άκρο σε άκρο. Μην μοιράζεστε ευαίσθητες πληροφορίες μέσω του Mastodon.",
"compose_form.hashtag_warning": "Αυτό το τουτ δεν θα εμφανίζεται κάτω από κανένα hashtag καθώς είναι αφανές. Μόνο τα δημόσια τουτ μπορούν να αναζητηθούν ανά hashtag.",
"compose_form.lock_disclaimer": "Ο λογαριασμός σου δεν είναι {locked}. Οποιοσδήποτε μπορεί να σε ακολουθήσει για να δει τις δημοσιεύσεις σας προς τους ακολούθους σας.",
"compose_form.lock_disclaimer.lock": "κλειδωμένο",

View file

@ -110,7 +110,7 @@
"compose_form.poll.remove_option": "Remove this choice",
"compose_form.poll.switch_to_multiple": "Change poll to allow multiple choices",
"compose_form.poll.switch_to_single": "Change poll to allow for a single choice",
"compose_form.publish": "Toot",
"compose_form.publish": "Publish",
"compose_form.publish_loud": "{publish}!",
"compose_form.save_changes": "Save changes",
"compose_form.sensitive.hide": "{count, plural, one {Mark media as sensitive} other {Mark media as sensitive}}",

View file

@ -93,7 +93,7 @@
"community.column_settings.media_only": "Nur aŭdovidaĵoj",
"community.column_settings.remote_only": "Nur malproksima",
"compose.language.change": "Ŝanĝi lingvon",
"compose.language.search": "Search languages...",
"compose.language.search": "Serĉi lingvojn...",
"compose_form.direct_message_warning_learn_more": "Lerni pli",
"compose_form.encryption_warning": "Posts on Mastodon are not end-to-end encrypted. Do not share any dangerous information over Mastodon.",
"compose_form.hashtag_warning": "Ĉi tiu mesaĝo ne estos listigita per ajna kradvorto. Nur publikaj mesaĝoj estas serĉeblaj per kradvortoj.",
@ -169,7 +169,7 @@
"empty_column.blocks": "Vi ankoraŭ ne blokis uzanton.",
"empty_column.bookmarked_statuses": "Vi ankoraŭ ne aldonis mesaĝon al viaj legosignoj. Kiam vi aldonos iun, tiu aperos ĉi tie.",
"empty_column.community": "La loka templinio estas malplena. Skribu ion por plenigi ĝin!",
"empty_column.direct": "You don't have any direct messages yet. When you send or receive one, it will show up here.",
"empty_column.direct": "Vi ankoraŭ ne havas rektan mesaĝon. Kiam vi sendos aŭ ricevos iun, ĝi aperos ĉi tie.",
"empty_column.domain_blocks": "Ankoraŭ neniu domajno estas blokita.",
"empty_column.explore_statuses": "Nenio tendencas nun. Rekontrolu poste!",
"empty_column.favourited_statuses": "Vi ankoraŭ ne stelumis mesaĝon. Kiam vi stelumos iun, tiu aperos ĉi tie.",
@ -234,7 +234,7 @@
"keyboard_shortcuts.column": "fokusi mesaĝon en unu el la kolumnoj",
"keyboard_shortcuts.compose": "enfokusigi la tekstujon",
"keyboard_shortcuts.description": "Priskribo",
"keyboard_shortcuts.direct": "to open direct messages column",
"keyboard_shortcuts.direct": "malfermi la kolumnon de rektaj mesaĝoj",
"keyboard_shortcuts.down": "iri suben en la listo",
"keyboard_shortcuts.enter": "malfermi mesaĝon",
"keyboard_shortcuts.favourite": "stelumi",
@ -473,8 +473,8 @@
"status.pin": "Alpingli profile",
"status.pinned": "Alpinglita mesaĝo",
"status.read_more": "Legi pli",
"status.reblog": "Diskonigi",
"status.reblog_private": "Diskonigi al la originala atentaro",
"status.reblog": "Plusendi",
"status.reblog_private": "Plusendi kiel la originala videbleco",
"status.reblogged_by": "{name} diskonigis",
"status.reblogs.empty": "Ankoraŭ neniu diskonigis tiun mesaĝon. Kiam iu faros tion, tiu aperos ĉi tie.",
"status.redraft": "Forigi kaj reskribi",

View file

@ -95,7 +95,7 @@
"compose.language.change": "Cambiar idioma",
"compose.language.search": "Buscar idiomas…",
"compose_form.direct_message_warning_learn_more": "Aprendé más",
"compose_form.encryption_warning": "Los mensajes en Mastodon no están cifrados de extremo a extremo. No comparta ninguna información sensible al usar Mastodon.",
"compose_form.encryption_warning": "Los mensajes en Mastodon no están cifrados de extremo a extremo. No compartas ninguna información sensible al usar Mastodon.",
"compose_form.hashtag_warning": "Este mensaje no se mostrará bajo ninguna etiqueta porque no es público. Sólo los mensajes públicos se pueden buscar por etiquetas.",
"compose_form.lock_disclaimer": "Tu cuenta no es {locked}. Todos pueden seguirte para ver tus mensajes marcados como \"Sólo para seguidores\".",
"compose_form.lock_disclaimer.lock": "privada",

View file

@ -92,10 +92,10 @@
"community.column_settings.local_only": "Solo local",
"community.column_settings.media_only": "Solo media",
"community.column_settings.remote_only": "Solo remoto",
"compose.language.change": "Change language",
"compose.language.search": "Search languages...",
"compose.language.change": "Cambiar idioma",
"compose.language.search": "Buscar idiomas...",
"compose_form.direct_message_warning_learn_more": "Aprender mas",
"compose_form.encryption_warning": "Los mensajes en Mastodon no están cifrados de extremo a extremo. No comparta ninguna información confidencial en Mastodon.",
"compose_form.encryption_warning": "Posts on Mastodon are not end-to-end encrypted. Do not share any dangerous information over Mastodon.",
"compose_form.hashtag_warning": "Este toot no se mostrará bajo hashtags porque no es público. Sólo los toots públicos se pueden buscar por hashtag.",
"compose_form.lock_disclaimer": "Tu cuenta no está bloqueada. Todos pueden seguirte para ver tus toots solo para seguidores.",
"compose_form.lock_disclaimer.lock": "bloqueado",
@ -149,7 +149,7 @@
"embed.instructions": "Añade este toot a tu sitio web con el siguiente código.",
"embed.preview": "Así es como se verá:",
"emoji_button.activity": "Actividad",
"emoji_button.clear": "Clear",
"emoji_button.clear": "Limpiar",
"emoji_button.custom": "Personalizado",
"emoji_button.flags": "Marcas",
"emoji_button.food": "Comida y bebida",
@ -267,8 +267,8 @@
"lightbox.expand": "Expandir cuadro de visualización de imagen",
"lightbox.next": "Siguiente",
"lightbox.previous": "Anterior",
"limited_account_hint.action": "Show profile anyway",
"limited_account_hint.title": "This profile has been hidden by the moderators of your server.",
"limited_account_hint.action": "Mostrar perfil de todos modos",
"limited_account_hint.title": "Este perfil ha sido ocultado por los moderadores de tu servidor.",
"lists.account.add": "Añadir a lista",
"lists.account.remove": "Quitar de lista",
"lists.delete": "Borrar lista",

View file

@ -95,7 +95,7 @@
"compose.language.change": "Cambiar idioma",
"compose.language.search": "Buscar idiomas...",
"compose_form.direct_message_warning_learn_more": "Aprender más",
"compose_form.encryption_warning": "Los mensajes en Mastodon no están cifrados de extremo a extremo. No comparta ninguna información confidencial en Mastodon.",
"compose_form.encryption_warning": "Las publicaciones en Mastodon no están cifradas de extremo a extremo. No comparta ninguna información sensible en Mastodon.",
"compose_form.hashtag_warning": "Esta publicación no se mostrará bajo ningún hashtag porque no está listada. Sólo las publicaciones públicas se pueden buscar por hashtag.",
"compose_form.lock_disclaimer": "Tu cuenta no está {locked}. Todos pueden seguirte para ver tus publicaciones solo para seguidores.",
"compose_form.lock_disclaimer.lock": "bloqueado",

View file

@ -106,7 +106,7 @@
"compose_form.poll.remove_option": "Eemalda see valik",
"compose_form.poll.switch_to_multiple": "Muuda küsitlust lubamaks mitut valikut",
"compose_form.poll.switch_to_single": "Muuda küsitlust lubamaks ainult ühte valikut",
"compose_form.publish": "Tuututa",
"compose_form.publish": "Tuut",
"compose_form.publish_loud": "{publish}!",
"compose_form.save_changes": "Save changes",
"compose_form.sensitive.hide": "Märgista meedia tundlikuks",

View file

@ -95,7 +95,7 @@
"compose.language.change": "Change language",
"compose.language.search": "Search languages...",
"compose_form.direct_message_warning_learn_more": "بیشتر بدانید",
"compose_form.encryption_warning": "فرسته‌های ماستودون رمزگذاری سرتاسری نشده‌اند. هیچ اطّلاعات خطرناکی را روی ماستودون هم‌رسانی نکنید.",
"compose_form.encryption_warning": "Posts on Mastodon are not end-to-end encrypted. Do not share any dangerous information over Mastodon.",
"compose_form.hashtag_warning": "از آن‌جا که این فرسته فهرست نشده است، در نتایج جست‌وجوی هشتگ‌ها پیدا نخواهد شد. تنها فرسته‌های عمومی را می‌توان با جست‌وجوی هشتگ یافت.",
"compose_form.lock_disclaimer": "حسابتان {locked} نیست. هر کسی می‌تواند پی‌گیرتان شده و فرسته‌های ویژهٔ پی‌گیرانتان را ببیند.",
"compose_form.lock_disclaimer.lock": "قفل‌شده",

View file

@ -95,7 +95,7 @@
"compose.language.change": "Changer de langue",
"compose.language.search": "Rechercher des langues …",
"compose_form.direct_message_warning_learn_more": "En savoir plus",
"compose_form.encryption_warning": "Les messages sur Mastodon ne sont pas chiffrés de bout en bout. Ne partagez aucune information confidentielle sur Mastodon.",
"compose_form.encryption_warning": "Les messages sur Mastodon ne sont pas chiffrés de bout en bout. Ne partagez aucune information sensible sur Mastodon.",
"compose_form.hashtag_warning": "Ce pouet ne sera pas listé dans les recherches par hashtag car sa visibilité est réglée sur « non listé ». Seuls les pouets avec une visibilité « publique » peuvent être recherchés par hashtag.",
"compose_form.lock_disclaimer": "Votre compte nest pas {locked}. Tout le monde peut vous suivre et voir vos messages privés.",
"compose_form.lock_disclaimer.lock": "verrouillé",

View file

@ -95,7 +95,7 @@
"compose.language.change": "Atharraich an cànan",
"compose.language.search": "Lorg cànan…",
"compose_form.direct_message_warning_learn_more": "Barrachd fiosrachaidh",
"compose_form.encryption_warning": "Chan eil crioptachadh ceann gu ceann air postaichean Mhastodon. Na co-roinn fiosrachadh cunnartach idir le Mastodon.",
"compose_form.encryption_warning": "Chan eil crioptachadh ceann gu ceann air postaichean Mhastodon. Na co-roinn fiosrachadh dìomhair idir le Mastodon.",
"compose_form.hashtag_warning": "Cha nochd am post seo fon taga hais on a tha e falaichte o liostaichean. Cha ghabh ach postaichean poblach a lorg a-rèir an tagaichean hais.",
"compose_form.lock_disclaimer": "Chan eil an cunntas agad {locked}. S urrainn do dhuine sam bith leantainn ort is na postaichean agad a tha ag amas air an luchd-leantainn agad a-mhàin a shealltainn.",
"compose_form.lock_disclaimer.lock": "glaiste",

View file

@ -135,7 +135,7 @@
"confirmations.redraft.confirm": "Eliminar e reescribir",
"confirmations.redraft.message": "Tes a certeza de querer eliminar esta publicación e reescribila? Perderás os compartidos e favoritos, e as respostas á publicación orixinal ficarán orfas.",
"confirmations.reply.confirm": "Responder",
"confirmations.reply.message": "Responder agora sobrescribirá a mensaxe que estás a compor. Tes a certeza de que queres continuar?",
"confirmations.reply.message": "Ao responder sobrescribirás a mensaxe que estás a compor. Tes a certeza de que queres continuar?",
"confirmations.unfollow.confirm": "Deixar de seguir",
"confirmations.unfollow.message": "Desexas deixar de seguir a {name}?",
"conversation.delete": "Eliminar conversa",
@ -480,7 +480,7 @@
"status.redraft": "Eliminar e reescribir",
"status.remove_bookmark": "Eliminar marcador",
"status.reply": "Responder",
"status.replyAll": "Responder ó fío",
"status.replyAll": "Responder ao tema",
"status.report": "Denunciar @{name}",
"status.sensitive_warning": "Contido sensíbel",
"status.share": "Compartir",

View file

@ -95,7 +95,7 @@
"compose.language.change": "Change language",
"compose.language.search": "Search languages...",
"compose_form.direct_message_warning_learn_more": "מידע נוסף",
"compose_form.encryption_warning": "חצרוצים במסטודון אינם מוצפנים מקצה לקצה. לעולם אל תחלקו מידע רגיש דרך מסטודון.",
"compose_form.encryption_warning": "Posts on Mastodon are not end-to-end encrypted. Do not share any dangerous information over Mastodon.",
"compose_form.hashtag_warning": "This toot won't be listed under any hashtag as it is unlisted. Only public toots can be searched by hashtag.",
"compose_form.lock_disclaimer": "חשבונך אינו {locked}. כל אחד יוכל לעקוב אחריך כדי לקרוא את הודעותיך המיועדות לעוקבים בלבד.",
"compose_form.lock_disclaimer.lock": "נעול",

View file

@ -95,7 +95,7 @@
"compose.language.change": "Change language",
"compose.language.search": "Search languages...",
"compose_form.direct_message_warning_learn_more": "और जानें",
"compose_form.encryption_warning": "मास्टोडॉन पर पोस्ट एन्ड-टू-एन्ड एन्क्रिप्टेड नहीं है",
"compose_form.encryption_warning": "Posts on Mastodon are not end-to-end encrypted. Do not share any dangerous information over Mastodon.",
"compose_form.hashtag_warning": "यह टूट् किसी भी हैशटैग के तहत सूचीबद्ध नहीं होगा क्योंकि यह अनलिस्टेड है। हैशटैग द्वारा केवल सार्वजनिक टूट्स खोजे जा सकते हैं।",
"compose_form.lock_disclaimer": "आपका खाता {locked} नहीं है। आपको केवल फॉलोवर्स को दिखाई दिए जाने वाले पोस्ट देखने के लिए कोई भी फॉलो कर सकता है।",
"compose_form.lock_disclaimer.lock": "लॉक्ड",

View file

@ -95,7 +95,7 @@
"compose.language.change": "Nyelv megváltoztatása",
"compose.language.search": "Nyelv keresése...",
"compose_form.direct_message_warning_learn_more": "Tudj meg többet",
"compose_form.encryption_warning": "A bejegyzések a Mastodonon nem használnak végpontok közötti titkosítást. Ne ossz meg érzékeny információt Mastodonon.",
"compose_form.encryption_warning": "A bejegyzések Mastodonon nem használnak végpontok közötti titkosítást. Ne ossz meg semmilyen érzékeny információt Mastodonon.",
"compose_form.hashtag_warning": "Ez a bejegyzésed nem fog megjelenni semmilyen hashtag alatt, mivel listázatlan. Csak a nyilvános bejegyzések kereshetők hashtaggel.",
"compose_form.lock_disclaimer": "A fiókod nincs {locked}. Bárki követni tud, hogy megtekintse a kizárólag követőknek szánt bejegyzéseket.",
"compose_form.lock_disclaimer.lock": "lezárva",

View file

@ -95,7 +95,7 @@
"compose.language.change": "Change language",
"compose.language.search": "Search languages...",
"compose_form.direct_message_warning_learn_more": "Իմանալ աւելին",
"compose_form.encryption_warning": "Մաստոդոնում գրառումները ծայրից-ծայր գաղտնագրուող չեն։ Գաղտնիք պարունակող նամակներ մի ուղարկէք։",
"compose_form.encryption_warning": "Posts on Mastodon are not end-to-end encrypted. Do not share any dangerous information over Mastodon.",
"compose_form.hashtag_warning": "Այս գրառումը չի հաշուառուի որեւէ պիտակի տակ, քանզի այն ծածուկ է։ Միայն հրապարակային թթերը հնարաւոր է որոնել պիտակներով։",
"compose_form.lock_disclaimer": "Քո հաշիւը {locked} չէ։ Իւրաքանչիւրութիւն ոք կարող է հետեւել քեզ եւ տեսնել միայն հետեւողների համար նախատեսուած գրառումները։",
"compose_form.lock_disclaimer.lock": "փակ",

View file

@ -95,7 +95,7 @@
"compose.language.change": "Ganti bahasa",
"compose.language.search": "Telusuri bahasa...",
"compose_form.direct_message_warning_learn_more": "Pelajari selengkapnya",
"compose_form.encryption_warning": "Kiriman di Mastodon tidak dienkripsi end-to-end. Jangan bagikan informasi rahasial melalui Mastodon.",
"compose_form.encryption_warning": "Posts on Mastodon are not end-to-end encrypted. Do not share any dangerous information over Mastodon.",
"compose_form.hashtag_warning": "Toot ini tidak akan ada dalam daftar tagar manapun karena telah diatur sebagai tidak terdaftar. Hanya postingan publik yang bisa dicari dengan tagar.",
"compose_form.lock_disclaimer": "Akun anda tidak {locked}. Semua orang dapat mengikuti anda untuk melihat postingan khusus untuk pengikut anda.",
"compose_form.lock_disclaimer.lock": "terkunci",

View file

@ -95,7 +95,7 @@
"compose.language.change": "Chanjez linguo",
"compose.language.search": "Trovez linguo...",
"compose_form.direct_message_warning_learn_more": "Lernez pluse",
"compose_form.encryption_warning": "Posti di Mastodon ne intersequante chifrigesas. Ne partigez irga danjera informo che Mastodon.",
"compose_form.encryption_warning": "Posti en Mastodon ne intersequante chifrigesas. Ne partigez irga privata informo che Mastodon.",
"compose_form.hashtag_warning": "This toot won't be listed under any hashtag as it is unlisted. Only public toots can be searched by hashtag.",
"compose_form.lock_disclaimer": "Vua konto ne esas {locked}. Irgu povas sequar vu por vidar vua sequanto-nura posti.",
"compose_form.lock_disclaimer.lock": "klefagesas",
@ -177,7 +177,7 @@
"empty_column.follow_recommendations": "Semblas tale nula sugestato povas facesar por vu. Vu povas probar trovar personi quon vu forsan konocas o exploras tendenca hashtagi.",
"empty_column.follow_requests": "Vu ne havas irga sequodemandi til nun. Kande vu ganas talo, ol montresos hike.",
"empty_column.hashtag": "Esas ankore nulo en ta gretovorto.",
"empty_column.home": "Tu sequas ankore nulu. Vizitez {public} od uzez la serchilo por komencar e renkontrar altra uzeri.",
"empty_column.home": "Vua hemtempolineo esas vakua! Sequez plu multa personi por plenigar lu. {suggestions}",
"empty_column.home.suggestions": "Videz ula sugestati",
"empty_column.list": "There is nothing in this list yet.",
"empty_column.lists": "Vu ne havas irga listi til nun. Kande vu kreas talo, ol montresos hike.",
@ -209,7 +209,7 @@
"getting_started.heading": "Debuto",
"getting_started.invite": "Invitez personi",
"getting_started.open_source_notice": "Mastodon esas programaro kun apertita kodexo. Tu povas kontributar o signalar problemi en GitHub ye {github}.",
"getting_started.security": "Security",
"getting_started.security": "Kontoopcioni",
"getting_started.terms": "Servkondicioni",
"hashtag.column_header.tag_mode.all": "e {additional}",
"hashtag.column_header.tag_mode.any": "o {additional}",
@ -305,7 +305,7 @@
"navigation_bar.follow_requests": "Demandi di sequado",
"navigation_bar.follows_and_followers": "Sequati e sequanti",
"navigation_bar.info": "Detaloza informi",
"navigation_bar.keyboard_shortcuts": "Keyboard shortcuts",
"navigation_bar.keyboard_shortcuts": "Rapidklavi",
"navigation_bar.lists": "Listi",
"navigation_bar.logout": "Ekirar",
"navigation_bar.mutes": "Celita uzeri",

View file

@ -95,7 +95,7 @@
"compose.language.change": "Cambia lingua",
"compose.language.search": "Ricerca lingue...",
"compose_form.direct_message_warning_learn_more": "Scopri di più",
"compose_form.encryption_warning": "I messaggi su Mastodon non sono crittografati end-to-end. Non condividere alcuna informazione sensibile su Mastodon.",
"compose_form.encryption_warning": "I messaggi su Mastodon non sono crittografati end-to-end. Non condividere dati sensibili su Mastodon.",
"compose_form.hashtag_warning": "Questo post non sarà elencato sotto alcun hashtag poiché senza elenco. Solo i toot pubblici possono essere ricercati per hashtag.",
"compose_form.lock_disclaimer": "Il tuo profilo non è {locked}. Chiunque può seguirti e vedere le tue pubblicazioni visibili solo dai follower.",
"compose_form.lock_disclaimer.lock": "bloccato",

View file

@ -99,7 +99,7 @@
"compose.language.change": "言語を変更",
"compose.language.search": "言語を検索...",
"compose_form.direct_message_warning_learn_more": "もっと詳しく",
"compose_form.encryption_warning": "Mastodonの投稿はエンドツーエンド暗号化に対応していません。安全に送受信されるべき情報をMastodonで共有しないでください。",
"compose_form.encryption_warning": "Posts on Mastodon are not end-to-end encrypted. Do not share any dangerous information over Mastodon.",
"compose_form.hashtag_warning": "この投稿は公開設定ではないのでハッシュタグの一覧に表示されません。公開投稿だけがハッシュタグで検索できます。",
"compose_form.lock_disclaimer": "あなたのアカウントは{locked}になっていません。誰でもあなたをフォローすることができ、フォロワー限定の投稿を見ることができます。",
"compose_form.lock_disclaimer.lock": "承認制",

View file

@ -95,7 +95,7 @@
"compose.language.change": "언어 변경",
"compose.language.search": "언어 검색...",
"compose_form.direct_message_warning_learn_more": "더 알아보기",
"compose_form.encryption_warning": "마스토돈의 게시물들은 종단간 암호화가 되지 않습니다. 위험한 정보를 마스토돈을 통해 전달하지 마세요.",
"compose_form.encryption_warning": "마스토돈의 게시물들은 종단간 암호화가 되지 않습니다. 민감한 정보를 마스토돈을 통해 전달하지 마세요.",
"compose_form.hashtag_warning": "이 게시물은 어떤 해시태그로도 검색 되지 않습니다. 전체공개로 게시 된 게시물만이 해시태그로 검색 될 수 있습니다.",
"compose_form.lock_disclaimer": "이 계정은 {locked}로 설정 되어 있지 않습니다. 누구나 이 계정을 팔로우 할 수 있으며, 팔로워 공개의 포스팅을 볼 수 있습니다.",
"compose_form.lock_disclaimer.lock": "비공개",
@ -268,7 +268,7 @@
"lightbox.next": "다음",
"lightbox.previous": "이전",
"limited_account_hint.action": "그래도 프로필 보기",
"limited_account_hint.title": "이 프로필은 서버 운영진에 의해 숨겨진 상태입니다.",
"limited_account_hint.title": "이 프로필은 이 서버의 중재자에 의해 숨겨진 상태입니다.",
"lists.account.add": "리스트에 추가",
"lists.account.remove": "리스트에서 제거",
"lists.delete": "리스트 삭제",

View file

@ -11,7 +11,7 @@
"account.direct": "Peyamekê bişîne @{name}",
"account.disable_notifications": "Êdî min agahdar neke gava @{name} diweşîne",
"account.domain_blocked": "Navper hate astengkirin",
"account.edit_profile": "Profîl serrast bike",
"account.edit_profile": "Profîlê serrast bike",
"account.enable_notifications": "Min agahdar bike gava @{name} diweşîne",
"account.endorse": "Taybetiyên li ser profîl",
"account.follow": "Bişopîne",
@ -81,7 +81,7 @@
"column.notifications": "Agahdarî",
"column.pins": "Şandiya derzîkirî",
"column.public": "Demnameyê federalîkirî",
"column_back_button.label": "Veger",
"column_back_button.label": "Vegere",
"column_header.hide_settings": "Sazkariyan veşêre",
"column_header.moveLeft_settings": "Stûnê bilivîne bo çepê",
"column_header.moveRight_settings": "Stûnê bilivîne bo rastê",
@ -95,7 +95,7 @@
"compose.language.change": "Ziman biguherîne",
"compose.language.search": "Li zimanan bigere...",
"compose_form.direct_message_warning_learn_more": "Bêtir fêr bibe",
"compose_form.encryption_warning": "Şandiyên li ser Mastodon dawî-bi-dawî ne şîfrekirî ne. Li ser Mastodon zanyariyên talûke parve neke.",
"compose_form.encryption_warning": "Şandiyên li ser Mastodon dawî-bi-dawî ne şîfrekirî ne. Li ser Mastodon zanyariyên hestyar parve neke.",
"compose_form.hashtag_warning": "Ev şandî ji ber ku nehatiye tomarkirin dê di binê hashtagê de neyê tomar kirin. Tenê peyamên gelemperî dikarin bi hashtagê werin lêgerîn.",
"compose_form.lock_disclaimer": "Ajimêrê te {locked} nîne. Herkes dikare te bişopîne da ku şandiyên te yên tenê şopînerên te ra xûya dibin bibînin.",
"compose_form.lock_disclaimer.lock": "girtî ye",
@ -207,7 +207,7 @@
"getting_started.directory": "Rêgeha profîlê",
"getting_started.documentation": "Pelbend",
"getting_started.heading": "Destpêkirin",
"getting_started.invite": "Mirovan Vexwîne",
"getting_started.invite": "Kesan vexwîne",
"getting_started.open_source_notice": "Mastodon nermalava çavkaniya vekirî ye. Tu dikarî pirsgirêkan li ser GitHub-ê ragihînî di {github} de an jî dikarî tevkariyê bikî.",
"getting_started.security": "Sazkariyên ajimêr",
"getting_started.terms": "Mercên karûberan",
@ -298,7 +298,7 @@
"navigation_bar.direct": "Peyamên rasterast",
"navigation_bar.discover": "Vekolê",
"navigation_bar.domain_blocks": "Navparên astengkirî",
"navigation_bar.edit_profile": "Profîl serrast bike",
"navigation_bar.edit_profile": "Profîlê serrast bike",
"navigation_bar.explore": "Vekole",
"navigation_bar.favourites": "Bijarte",
"navigation_bar.filters": "Peyvên bêdengkirî",

View file

@ -95,7 +95,7 @@
"compose.language.change": "Mainīt valodu",
"compose.language.search": "Meklēt valodas...",
"compose_form.direct_message_warning_learn_more": "Uzzināt vairāk",
"compose_form.encryption_warning": "Ziņas vietnē Mastodon nav pilnībā šifrētas. Nedalies ar bīstamu informāciju caur Mastodon.",
"compose_form.encryption_warning": "Ziņas vietnē Mastodon nav pilnībā šifrētas. Nedalies ar sensitīvu informāciju caur Mastodon.",
"compose_form.hashtag_warning": "Ziņojumu nebūs iespējams atrast zem haštagiem jo tas nav publisks. Tikai publiskos ziņojumus ir iespējams meklēt pēc tiem.",
"compose_form.lock_disclaimer": "Tavs konts nav {locked}. Ikviens var Tev sekot lai apskatītu tikai sekotājiem paredzētos ziņojumus.",
"compose_form.lock_disclaimer.lock": "slēgts",

View file

@ -48,8 +48,8 @@
"account.unmute_notifications": "Meldingen van @{name} niet langer negeren",
"account.unmute_short": "Niet langer negeren",
"account_note.placeholder": "Klik om een opmerking toe te voegen",
"admin.dashboard.daily_retention": "User retention rate by day after sign-up",
"admin.dashboard.monthly_retention": "User retention rate by month after sign-up",
"admin.dashboard.daily_retention": "Retentiegraad van gebruikers per dag, vanaf registratie",
"admin.dashboard.monthly_retention": "Retentiegraad van gebruikers per maand, vanaf registratie",
"admin.dashboard.retention.average": "Gemiddelde",
"admin.dashboard.retention.cohort": "Aanmeldingsmaand",
"admin.dashboard.retention.cohort_size": "Nieuwe gebruikers",
@ -70,7 +70,7 @@
"column.blocks": "Geblokkeerde gebruikers",
"column.bookmarks": "Bladwijzers",
"column.community": "Lokale tijdlijn",
"column.direct": "Direct messages",
"column.direct": "Directe berichten",
"column.directory": "Gebruikersgids",
"column.domain_blocks": "Geblokkeerde domeinen",
"column.favourites": "Favorieten",
@ -92,10 +92,10 @@
"community.column_settings.local_only": "Alleen lokaal",
"community.column_settings.media_only": "Alleen media",
"community.column_settings.remote_only": "Alleen andere servers",
"compose.language.change": "Change language",
"compose.language.search": "Search languages...",
"compose.language.change": "Taal veranderen",
"compose.language.search": "Talen zoeken...",
"compose_form.direct_message_warning_learn_more": "Meer leren",
"compose_form.encryption_warning": "Posts on Mastodon are not end-to-end encrypted. Do not share any dangerous information over Mastodon.",
"compose_form.encryption_warning": "Berichten op Mastodon worden, net zoals op andere social media, niet end-to-end versleuteld. Deel daarom geen gevoelige informatie via Mastodon.",
"compose_form.hashtag_warning": "Dit bericht valt niet onder een hashtag te bekijken, omdat deze niet op openbare tijdlijnen wordt getoond. Alleen openbare berichten kunnen via hashtags gevonden worden.",
"compose_form.lock_disclaimer": "Jouw account is niet {locked}. Iedereen kan jou volgen en kan de berichten zien die je alleen aan jouw volgers hebt gericht.",
"compose_form.lock_disclaimer.lock": "besloten",
@ -149,7 +149,7 @@
"embed.instructions": "Embed dit bericht op jouw website door de onderstaande code te kopiëren.",
"embed.preview": "Zo komt het eruit te zien:",
"emoji_button.activity": "Activiteiten",
"emoji_button.clear": "Clear",
"emoji_button.clear": "Leegmaken",
"emoji_button.custom": "Lokale emojis",
"emoji_button.flags": "Vlaggen",
"emoji_button.food": "Eten en drinken",
@ -169,7 +169,7 @@
"empty_column.blocks": "Jij hebt nog geen enkele gebruiker geblokkeerd.",
"empty_column.bookmarked_statuses": "Jij hebt nog geen berichten aan je bladwijzers toegevoegd. Wanneer je er een aan jouw bladwijzers toevoegt, valt deze hier te zien.",
"empty_column.community": "De lokale tijdlijn is nog leeg. Plaats een openbaar bericht om de spits af te bijten!",
"empty_column.direct": "You don't have any direct messages yet. When you send or receive one, it will show up here.",
"empty_column.direct": "Je hebt nog geen directe berichten. Wanneer je er een verzend of ontvangt, komt deze hier te staan.",
"empty_column.domain_blocks": "Er zijn nog geen geblokkeerde domeinen.",
"empty_column.explore_statuses": "Momenteel zijn er geen trends. Kom later terug!",
"empty_column.favourited_statuses": "Jij hebt nog geen favoriete berichten. Wanneer je er een aan jouw favorieten toevoegt, valt deze hier te zien.",
@ -234,7 +234,7 @@
"keyboard_shortcuts.column": "Op één van de kolommen focussen",
"keyboard_shortcuts.compose": "Tekstveld om een bericht te schrijven focussen",
"keyboard_shortcuts.description": "Omschrijving",
"keyboard_shortcuts.direct": "to open direct messages column",
"keyboard_shortcuts.direct": "Directe berichten tonen",
"keyboard_shortcuts.down": "Naar beneden in de lijst bewegen",
"keyboard_shortcuts.enter": "Volledig bericht tonen",
"keyboard_shortcuts.favourite": "Aan jouw favorieten toevoegen",
@ -267,8 +267,8 @@
"lightbox.expand": "Afbeelding groot weergeven",
"lightbox.next": "Volgende",
"lightbox.previous": "Vorige",
"limited_account_hint.action": "Show profile anyway",
"limited_account_hint.title": "This profile has been hidden by the moderators of your server.",
"limited_account_hint.action": "Alsnog het profiel tonen",
"limited_account_hint.title": "Dit profiel is door de moderatoren van jouw server verborgen.",
"lists.account.add": "Aan lijst toevoegen",
"lists.account.remove": "Uit lijst verwijderen",
"lists.delete": "Lijst verwijderen",
@ -295,7 +295,7 @@
"navigation_bar.bookmarks": "Bladwijzers",
"navigation_bar.community_timeline": "Lokale tijdlijn",
"navigation_bar.compose": "Nieuw bericht schrijven",
"navigation_bar.direct": "Direct messages",
"navigation_bar.direct": "Directe berichten",
"navigation_bar.discover": "Ontdekken",
"navigation_bar.domain_blocks": "Geblokkeerde domeinen",
"navigation_bar.edit_profile": "Profiel bewerken",
@ -372,12 +372,12 @@
"poll_button.remove_poll": "Poll verwijderen",
"privacy.change": "Zichtbaarheid van bericht aanpassen",
"privacy.direct.long": "Alleen aan vermelde gebruikers tonen",
"privacy.direct.short": "Direct",
"privacy.direct.short": "Alleen aan vermelde gebruikers tonen",
"privacy.private.long": "Alleen aan volgers tonen",
"privacy.private.short": "Alleen volgers",
"privacy.public.long": "Voor iedereen zichtbaar",
"privacy.public.short": "Openbaar",
"privacy.unlisted.long": "Visible for all, but opted-out of discovery features",
"privacy.unlisted.long": "Voor iedereen zichtbaar, maar niet onder trends, hashtags en op openbare tijdlijnen",
"privacy.unlisted.short": "Minder openbaar",
"refresh": "Vernieuwen",
"regeneration_indicator.label": "Aan het laden…",

View file

@ -18,7 +18,7 @@
"account.followers": "Seguidors",
"account.followers.empty": "Degun sèc pas aqueste utilizaire pel moment.",
"account.followers_counter": "{count, plural, one {{counter} Seguidor} other {{counter} Seguidors}}",
"account.following": "Following",
"account.following": "Abonat",
"account.following_counter": "{count, plural, one {{counter} Abonaments} other {{counter} Abonaments}}",
"account.follows.empty": "Aqueste utilizaire sèc pas degun pel moment.",
"account.follows_you": "Vos sèc",
@ -41,12 +41,12 @@
"account.statuses_counter": "{count, plural, one {{counter} Tut} other {{counter} Tuts}}",
"account.unblock": "Desblocar @{name}",
"account.unblock_domain": "Desblocar {domain}",
"account.unblock_short": "Unblock",
"account.unblock_short": "Desblocat",
"account.unendorse": "Mostrar pas pel perfil",
"account.unfollow": "Quitar de sègre",
"account.unmute": "Quitar de rescondre @{name}",
"account.unmute_notifications": "Mostrar las notificacions de @{name}",
"account.unmute_short": "Unmute",
"account.unmute_short": "Tornar afichar",
"account_note.placeholder": "Clicar per ajustar una nòta",
"admin.dashboard.daily_retention": "User retention rate by day after sign-up",
"admin.dashboard.monthly_retention": "User retention rate by month after sign-up",
@ -70,7 +70,7 @@
"column.blocks": "Personas blocadas",
"column.bookmarks": "Marcadors",
"column.community": "Flux public local",
"column.direct": "Direct messages",
"column.direct": "Messatges dirèctes",
"column.directory": "Percórrer los perfils",
"column.domain_blocks": "Domenis resconduts",
"column.favourites": "Favorits",
@ -92,10 +92,10 @@
"community.column_settings.local_only": "Sonque local",
"community.column_settings.media_only": "Solament los mèdias",
"community.column_settings.remote_only": "Sonque alonhat",
"compose.language.change": "Change language",
"compose.language.search": "Search languages...",
"compose.language.change": "Cambiar de lenga",
"compose.language.search": "Recercar de lengas...",
"compose_form.direct_message_warning_learn_more": "Ne saber mai",
"compose_form.encryption_warning": "Posts on Mastodon are not end-to-end encrypted. Do not share any dangerous information over Mastodon.",
"compose_form.encryption_warning": "Las pubicacions sus Mastodon son pas chifradas del cap a la fin. Partegetz pas dinformacions sensiblas sus Mastodon.",
"compose_form.hashtag_warning": "Aqueste tut serà pas ligat a cap detiqueta estant ques pas listat. Òm pòt pas cercar que los tuts publics per etiqueta.",
"compose_form.lock_disclaimer": "Vòstre compte es pas {locked}. Tot lo mond pòt vos sègre e veire los estatuts reservats als seguidors.",
"compose_form.lock_disclaimer.lock": "clavat",
@ -149,7 +149,7 @@
"embed.instructions": "Embarcar aqueste estatut per lo far veire sus un site Internet en copiar lo còdi çai-jos.",
"embed.preview": "Semblarà aquò:",
"emoji_button.activity": "Activitats",
"emoji_button.clear": "Clear",
"emoji_button.clear": "Escafar",
"emoji_button.custom": "Personalizats",
"emoji_button.flags": "Drapèus",
"emoji_button.food": "Beure e manjar",
@ -169,7 +169,7 @@
"empty_column.blocks": "Avètz pas blocat degun pel moment.",
"empty_column.bookmarked_statuses": "Avètz pas cap de tuts marcats pel moment. Quand ne marquetz un, serà mostrat aquí.",
"empty_column.community": "Lo flux public local es void. Escrivètz quicòm per lo garnir!",
"empty_column.direct": "You don't have any direct messages yet. When you send or receive one, it will show up here.",
"empty_column.direct": "Avètz pas encara cap de messatges. Quand ne mandatz un o que ne recebètz un, serà mostrat aquí.",
"empty_column.domain_blocks": "I a pas encara cap de domeni amagat.",
"empty_column.explore_statuses": "Nothing is trending right now. Check back later!",
"empty_column.favourited_statuses": "Avètz pas encara cap de tut favorit. Quand nauretz un, apareisserà aquí.",
@ -191,11 +191,11 @@
"errors.unexpected_crash.copy_stacktrace": "Copiar las traças al quichapapièrs",
"errors.unexpected_crash.report_issue": "Senhalar un problèma",
"explore.search_results": "Resultats de recèrca",
"explore.suggested_follows": "For you",
"explore.suggested_follows": "Per vos",
"explore.title": "Explorar",
"explore.trending_links": "News",
"explore.trending_statuses": "Posts",
"explore.trending_tags": "Hashtags",
"explore.trending_links": "Novèlas",
"explore.trending_statuses": "Publicacions",
"explore.trending_tags": "Etiquetas",
"follow_recommendations.done": "Acabat",
"follow_recommendations.heading": "Follow people you'd like to see posts from! Here are some suggestions.",
"follow_recommendations.lead": "Posts from people you follow will show up in chronological order on your home feed. Don't be afraid to make mistakes, you can unfollow people just as easily any time!",
@ -295,11 +295,11 @@
"navigation_bar.bookmarks": "Marcadors",
"navigation_bar.community_timeline": "Flux public local",
"navigation_bar.compose": "Escriure un nòu tut",
"navigation_bar.direct": "Direct messages",
"navigation_bar.direct": "Messatges dirèctes",
"navigation_bar.discover": "Trobar",
"navigation_bar.domain_blocks": "Domenis resconduts",
"navigation_bar.edit_profile": "Modificar lo perfil",
"navigation_bar.explore": "Explore",
"navigation_bar.explore": "Explorar",
"navigation_bar.favourites": "Favorits",
"navigation_bar.filters": "Mots ignorats",
"navigation_bar.follow_requests": "Demandas dabonament",
@ -314,7 +314,7 @@
"navigation_bar.preferences": "Preferéncias",
"navigation_bar.public_timeline": "Flux public global",
"navigation_bar.security": "Seguretat",
"notification.admin.sign_up": "{name} signed up",
"notification.admin.sign_up": "{name} se marquèt",
"notification.favourite": "{name} a ajustat a sos favorits",
"notification.follow": "{name} vos sèc",
"notification.follow_request": "{name} a demandat a vos sègre",
@ -323,7 +323,7 @@
"notification.poll": "Avètz participat a un sondatge que ven de sacabar",
"notification.reblog": "{name} a partejat vòstre estatut",
"notification.status": "{name} ven de publicar",
"notification.update": "{name} edited a post",
"notification.update": "{name} modiquè sa publicacion",
"notifications.clear": "Escafar",
"notifications.clear_confirmation": "Volètz vertadièrament escafar totas vòstras las notificacions?",
"notifications.column_settings.admin.sign_up": "New sign-ups:",
@ -372,10 +372,10 @@
"poll_button.remove_poll": "Levar lo sondatge",
"privacy.change": "Ajustar la confidencialitat del messatge",
"privacy.direct.long": "Mostrar pas qua las personas mencionadas",
"privacy.direct.short": "Direct",
"privacy.direct.short": "Sonque per las personas mencionadas",
"privacy.private.long": "Mostrar pas qua vòstres seguidors",
"privacy.private.short": "Followers-only",
"privacy.public.long": "Visible for all",
"privacy.private.short": "Sonque pels seguidors",
"privacy.public.long": "Visiblas per totes",
"privacy.public.short": "Public",
"privacy.unlisted.long": "Visible for all, but opted-out of discovery features",
"privacy.unlisted.short": "Pas-listat",

View file

@ -271,8 +271,8 @@
"lightbox.expand": "Rozwiń pole widoku obrazu",
"lightbox.next": "Następne",
"lightbox.previous": "Poprzednie",
"limited_account_hint.action": "Show profile anyway",
"limited_account_hint.title": "This profile has been hidden by the moderators of your server.",
"limited_account_hint.action": "Pokaż profil mimo wszystko",
"limited_account_hint.title": "Ten profil został ukryty przez moderatorów Twojego serwera.",
"lists.account.add": "Dodaj do listy",
"lists.account.remove": "Usunąć z listy",
"lists.delete": "Usuń listę",

View file

@ -95,7 +95,7 @@
"compose.language.change": "Alterar idioma",
"compose.language.search": "Pesquisar idiomas...",
"compose_form.direct_message_warning_learn_more": "Saiba mais",
"compose_form.encryption_warning": "Postagens no Mastodon não são criptografados de ponta a ponta. Não compartilhe nenhuma informação perigosa sobre o Mastodon.",
"compose_form.encryption_warning": "Posts on Mastodon are not end-to-end encrypted. Do not share any dangerous information over Mastodon.",
"compose_form.hashtag_warning": "Este toot não aparecerá em nenhuma hashtag porque está como não-listado. Somente toots públicos podem ser pesquisados por hashtag.",
"compose_form.lock_disclaimer": "Seu perfil não está {locked}. Qualquer um pode te seguir e ver os toots privados.",
"compose_form.lock_disclaimer.lock": "trancado",

View file

@ -95,7 +95,7 @@
"compose.language.change": "Alterar idioma",
"compose.language.search": "Pesquisar idiomas...",
"compose_form.direct_message_warning_learn_more": "Conhecer mais",
"compose_form.encryption_warning": "As publicações no Mastodon não são criptografadas de ponta a ponta. Não partilhe nenhuma informação sensível através do Mastodon.",
"compose_form.encryption_warning": "As publicações no Mastodon não são encriptadas ponta a ponta. Não partilhe nenhuma informação sensível através do Mastodon.",
"compose_form.hashtag_warning": "Este toot não será listado em nenhuma hashtag por ser não listado. Apenas toots públics podem ser pesquisados por hashtag.",
"compose_form.lock_disclaimer": "A sua conta não é {locked}. Qualquer pessoa pode segui-lo e ver as publicações direcionadas apenas a seguidores.",
"compose_form.lock_disclaimer.lock": "bloqueado",

View file

@ -95,7 +95,7 @@
"compose.language.change": "Изменить язык",
"compose.language.search": "Поиск языков...",
"compose_form.direct_message_warning_learn_more": "Подробнее",
"compose_form.encryption_warning": "Посты в Mastodon не защищены сквозным шифрованием. Не делитесь потенциально опасной информацией.",
"compose_form.encryption_warning": "Посты в Mastodon не защищены сквозным шифрованием. Не делитесь конфиденциальной информацией через Mastodon.",
"compose_form.hashtag_warning": "Так как этот пост не публичный, он не отобразится в поиске по хэштегам.",
"compose_form.lock_disclaimer": "Ваша учётная запись {locked}. Любой пользователь сможет подписаться на вас и просматривать посты для подписчиков.",
"compose_form.lock_disclaimer.lock": "не закрыта",

View file

@ -92,7 +92,7 @@
"community.column_settings.local_only": "Iba miestna",
"community.column_settings.media_only": "Iba médiá",
"community.column_settings.remote_only": "Iba odľahlé",
"compose.language.change": "Change language",
"compose.language.change": "Zmeň jazyk",
"compose.language.search": "Search languages...",
"compose_form.direct_message_warning_learn_more": "Zisti viac",
"compose_form.encryption_warning": "Posts on Mastodon are not end-to-end encrypted. Do not share any dangerous information over Mastodon.",

View file

@ -95,7 +95,7 @@
"compose.language.change": "Change language",
"compose.language.search": "Search languages...",
"compose_form.direct_message_warning_learn_more": "Mësoni më tepër",
"compose_form.encryption_warning": "Postimet në Mastodon nuk fshehtëzohen skaj-më-skaj. Mos ndani me të tjerë gjëra me spec në Mastodon.",
"compose_form.encryption_warning": "Posts on Mastodon are not end-to-end encrypted. Do not share any dangerous information over Mastodon.",
"compose_form.hashtag_warning": "Ky mesazh sdo të paraqitet nën ndonjë hashtag, ngaqë si është caktuar ndonjë. Vetëm mesazhet publike mund të kërkohen sipas hashtagësh.",
"compose_form.lock_disclaimer": "Llogaria juaj sështë {locked}. Mund ta ndjekë cilido, për të parë postimet tuaja vetëm për ndjekësit.",
"compose_form.lock_disclaimer.lock": "e kyçur",

View file

@ -95,7 +95,7 @@
"compose.language.change": "Change language",
"compose.language.search": "Search languages...",
"compose_form.direct_message_warning_learn_more": "Lär dig mer",
"compose_form.encryption_warning": "Inlägg på Mastodon är inte end-to-end-krypterade. Dela inte någon känslig information över Mastodon.",
"compose_form.encryption_warning": "Posts on Mastodon are not end-to-end encrypted. Do not share any dangerous information over Mastodon.",
"compose_form.hashtag_warning": "Denna toot kommer inte att visas under någon hashtag eftersom den är onoterad. Endast offentliga toots kan sökas med hashtag.",
"compose_form.lock_disclaimer": "Ditt konto är inte {locked}. Vem som helst kan följa dig för att se dina inlägg som endast är för följare.",
"compose_form.lock_disclaimer.lock": "låst",

View file

@ -95,7 +95,7 @@
"compose.language.change": "เปลี่ยนภาษา",
"compose.language.search": "ค้นหาภาษา...",
"compose_form.direct_message_warning_learn_more": "เรียนรู้เพิ่มเติม",
"compose_form.encryption_warning": "โพสต์ใน Mastodon ไม่ได้เข้ารหัสแบบต้นทางถึงปลายทาง อย่าแบ่งปันข้อมูลที่เป็นอันตรายใด ๆ ผ่าน Mastodon",
"compose_form.encryption_warning": "โพสต์ใน Mastodon ไม่ได้เข้ารหัสแบบต้นทางถึงปลายทาง อย่าแบ่งปันข้อมูลที่ละเอียดอ่อนใด ๆ ผ่าน Mastodon",
"compose_form.hashtag_warning": "จะไม่แสดงรายการโพสต์นี้ภายใต้แฮชแท็กใด ๆ เนื่องจากไม่อยู่ในรายการ เฉพาะโพสต์สาธารณะเท่านั้นที่สามารถค้นหาได้โดยแฮชแท็ก",
"compose_form.lock_disclaimer": "บัญชีของคุณไม่ได้ {locked} ใครก็ตามสามารถติดตามคุณเพื่อดูโพสต์สำหรับผู้ติดตามเท่านั้นของคุณ",
"compose_form.lock_disclaimer.lock": "ล็อคอยู่",

View file

@ -95,7 +95,7 @@
"compose.language.change": "Змінити мову",
"compose.language.search": "Шукати мови...",
"compose_form.direct_message_warning_learn_more": "Дізнатися більше",
"compose_form.encryption_warning": "Дописи на Mastodon не захищені шифруванням. Не поширюйте жодну потенційно небезпечну інформацію.",
"compose_form.encryption_warning": "Дописи на Mastodon не захищені шифруванням. Не поширюйте жодну делікатну інформацію.",
"compose_form.hashtag_warning": "Цей допис не буде зображений у жодній стрічці гештеґу, оскільки він прихований. Тільки публічні дописи можуть бути знайдені за гештеґом.",
"compose_form.lock_disclaimer": "Ваш обліковий запис не {locked}. Будь-який користувач може підписатися на вас та переглядати ваші дописи для підписників.",
"compose_form.lock_disclaimer.lock": "приватний",

View file

@ -106,7 +106,7 @@
"compose_form.poll.remove_option": "移除此选项",
"compose_form.poll.switch_to_multiple": "将投票改为多选",
"compose_form.poll.switch_to_single": "将投票改为单选",
"compose_form.publish": "嘟嘟",
"compose_form.publish": "Toot!",
"compose_form.publish_loud": "{publish}",
"compose_form.save_changes": "保存更改",
"compose_form.sensitive.hide": "{count, plural, one {将媒体标记为敏感内容} other {将媒体标记为敏感内容}}",
@ -321,7 +321,7 @@
"notification.mention": "{name} 提及了你",
"notification.own_poll": "你的投票已经结束",
"notification.poll": "你参与的一个投票已经结束",
"notification.reblog": "{name} 转了你的嘟文",
"notification.reblog": "{name} 转了你的嘟文",
"notification.status": "{name} 刚刚发嘟",
"notification.update": "{name} 编辑了嘟文",
"notifications.clear": "清空通知列表",
@ -373,8 +373,8 @@
"privacy.change": "设置嘟文的可见范围",
"privacy.direct.long": "只有被提及的用户能看到",
"privacy.direct.short": "仅提到的人",
"privacy.private.long": "仅关注者可见",
"privacy.private.short": "仅关注者可见",
"privacy.private.long": "仅关注者可见",
"privacy.private.short": "仅关注者",
"privacy.public.long": "所有人可见",
"privacy.public.short": "公开",
"privacy.unlisted.long": "对所有人可见,但不加入探索功能",

View file

@ -328,6 +328,10 @@ export default function compose(state = initialState, action) {
map.set('preselectDate', new Date());
map.set('idempotencyKey', uuid());
if (action.status.get('language')) {
map.set('language', action.status.get('language'));
}
if (action.status.get('spoiler_text').length > 0) {
map.set('spoiler', true);
map.set('spoiler_text', action.status.get('spoiler_text'));

View file

@ -109,7 +109,7 @@ const loadImage = inputFile => new Promise((resolve, reject) => {
});
const getOrientation = (img, type = 'image/png') => new Promise(resolve => {
if (type !== 'image/jpeg') {
if (!['image/jpeg', 'image/webp'].includes(type)) {
resolve(1);
return;
}

View file

@ -17,7 +17,6 @@
@import 'mastodon/boost';
@import 'mastodon/components';
@import 'mastodon/polls';
@import 'mastodon/introduction';
@import 'mastodon/modal';
@import 'mastodon/emoji_picker';
@import 'mastodon/about';

View file

@ -1,6 +1,7 @@
@font-face {
font-family: 'mastodon-font-display';
src: local('Montserrat'),
font-family: mastodon-font-display;
src:
local('Montserrat'),
url('~fonts/montserrat/Montserrat-Regular.woff2') format('woff2'),
url('~fonts/montserrat/Montserrat-Regular.woff') format('woff'),
url('~fonts/montserrat/Montserrat-Regular.ttf') format('truetype');
@ -10,8 +11,9 @@
}
@font-face {
font-family: 'mastodon-font-display';
src: local('Montserrat Medium'),
font-family: mastodon-font-display;
src:
local('Montserrat Medium'),
url('~fonts/montserrat/Montserrat-Medium.ttf') format('truetype');
font-weight: 500;
font-display: swap;

View file

@ -1,6 +1,7 @@
@font-face {
font-family: 'mastodon-font-monospace';
src: local('Roboto Mono'),
font-family: mastodon-font-monospace;
src:
local('Roboto Mono'),
url('~fonts/roboto-mono/robotomono-regular-webfont.woff2') format('woff2'),
url('~fonts/roboto-mono/robotomono-regular-webfont.woff') format('woff'),
url('~fonts/roboto-mono/robotomono-regular-webfont.ttf') format('truetype'),

View file

@ -1,6 +1,7 @@
@font-face {
font-family: 'mastodon-font-sans-serif';
src: local('Roboto Italic'),
font-family: mastodon-font-sans-serif;
src:
local('Roboto Italic'),
url('~fonts/roboto/roboto-italic-webfont.woff2') format('woff2'),
url('~fonts/roboto/roboto-italic-webfont.woff') format('woff'),
url('~fonts/roboto/roboto-italic-webfont.ttf') format('truetype'),
@ -11,8 +12,9 @@
}
@font-face {
font-family: 'mastodon-font-sans-serif';
src: local('Roboto Bold'),
font-family: mastodon-font-sans-serif;
src:
local('Roboto Bold'),
url('~fonts/roboto/roboto-bold-webfont.woff2') format('woff2'),
url('~fonts/roboto/roboto-bold-webfont.woff') format('woff'),
url('~fonts/roboto/roboto-bold-webfont.ttf') format('truetype'),
@ -23,8 +25,9 @@
}
@font-face {
font-family: 'mastodon-font-sans-serif';
src: local('Roboto Medium'),
font-family: mastodon-font-sans-serif;
src:
local('Roboto Medium'),
url('~fonts/roboto/roboto-medium-webfont.woff2') format('woff2'),
url('~fonts/roboto/roboto-medium-webfont.woff') format('woff'),
url('~fonts/roboto/roboto-medium-webfont.ttf') format('truetype'),
@ -35,8 +38,9 @@
}
@font-face {
font-family: 'mastodon-font-sans-serif';
src: local('Roboto'),
font-family: mastodon-font-sans-serif;
src:
local('Roboto'),
url('~fonts/roboto/roboto-regular-webfont.woff2') format('woff2'),
url('~fonts/roboto/roboto-regular-webfont.woff') format('woff'),
url('~fonts/roboto/roboto-regular-webfont.ttf') format('truetype'),

View file

@ -542,10 +542,10 @@ html {
}
.simple_form {
input[type=text],
input[type=number],
input[type=email],
input[type=password],
input[type="text"],
input[type="number"],
input[type="email"],
input[type="password"],
textarea {
&:hover {
border-color: lighten($ui-base-color, 12%);

View file

@ -28,10 +28,10 @@ $inverted-text-color: $black !default;
$lighter-text-color: $classic-base-color !default;
$light-text-color: #444b5d;
//Newly added colors
// Newly added colors
$account-background-color: $white !default;
//Invert darkened and lightened colors
// Invert darkened and lightened colors
@function darken($color, $amount) {
@return hsl(hue($color), saturation($color), lightness($color) + $amount);
}

View file

@ -41,7 +41,7 @@ $small-breakpoint: 960px;
p {
margin-top: 0;
margin-bottom: .85em;
margin-bottom: 0.85em;
&:last-child {
margin-bottom: 0;
@ -73,7 +73,7 @@ $small-breakpoint: 960px;
h6 {
font-family: $font-display, sans-serif;
margin-top: 1.275em;
margin-bottom: .85em;
margin-bottom: 0.85em;
font-weight: 500;
color: $secondary-text-color;
}
@ -436,7 +436,7 @@ $small-breakpoint: 960px;
width: 100%;
height: 0;
border: 0;
border-bottom: 1px solid rgba($ui-base-lighter-color, .6);
border-bottom: 1px solid rgba($ui-base-lighter-color, 0.6);
margin: 20px 0;
&.spacer {

View file

@ -183,12 +183,9 @@ $content-width: 840px;
&-heading {
display: flex;
padding-bottom: 36px;
border-bottom: 1px solid lighten($ui-base-color, 8%);
margin: -15px -15px 40px 0;
flex-wrap: wrap;
align-items: center;
justify-content: space-between;
@ -294,7 +291,7 @@ $content-width: 840px;
width: 100%;
height: 0;
border: 0;
border-bottom: 1px solid rgba($ui-base-lighter-color, .6);
border-bottom: 1px solid rgba($ui-base-lighter-color, 0.6);
margin: 20px 0;
&.spacer {

View file

@ -16,7 +16,7 @@ body {
text-rendering: optimizelegibility;
font-feature-settings: "kern";
text-size-adjust: none;
-webkit-tap-highlight-color: rgba(0, 0, 0, 0);
-webkit-tap-highlight-color: rgba(0, 0, 0, 0%);
-webkit-tap-highlight-color: transparent;
&.system-font {
@ -31,7 +31,7 @@ body {
// Droid Sans => Older Androids (<4.0)
// Helvetica Neue => Older macOS <10.11
// $font-sans-serif => web-font (Roboto) fallback and newer Androids (>=4.0)
font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", "Oxygen", "Ubuntu", "Cantarell", "Fira Sans", "Droid Sans", "Helvetica Neue", $font-sans-serif, sans-serif;
font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Oxygen, Ubuntu, Cantarell, "Fira Sans", "Droid Sans", "Helvetica Neue", $font-sans-serif, sans-serif;
}
&.app-body {
@ -202,7 +202,7 @@ button {
}
p {
margin-bottom: .85em;
margin-bottom: 0.85em;
&:last-child {
margin-bottom: 0;

View file

@ -341,7 +341,6 @@
&__sensitive-button {
padding: 10px;
padding-top: 0;
font-size: 14px;
font-weight: 500;
@ -349,7 +348,7 @@
color: $highlight-text-color;
}
input[type=checkbox] {
input[type="checkbox"] {
display: none;
}
@ -709,7 +708,7 @@
font-size: inherit;
vertical-align: middle;
object-fit: contain;
margin: -.2ex .15em .2ex;
margin: -0.2ex 0.15em 0.2ex;
width: 16px;
height: 16px;
@ -1313,9 +1312,9 @@
.account__avatar {
@include avatar-radius;
display: block;
position: relative;
width: 36px;
height: 36px;
background-size: 36px 36px;
@ -1328,6 +1327,7 @@
&-composite {
@include avatar-radius;
border-radius: 50%;
overflow: hidden;
position: relative;
@ -1365,6 +1365,7 @@ a .account__avatar {
img {
@include avatar-radius;
width: 100%;
height: 100%;
}
@ -1381,6 +1382,7 @@ a .account__avatar {
img {
@include avatar-radius;
width: 100%;
height: 100%;
}
@ -2328,7 +2330,7 @@ a.account__display-name {
.scrollable {
overflow: visible;
@supports(display: grid) {
@supports (display: grid) {
contain: content;
}
}
@ -2751,7 +2753,7 @@ a.account__display-name {
overflow-y: auto;
}
@supports(display: grid) { // hack to fix Chrome <57
@supports (display: grid) { // hack to fix Chrome <57
contain: strict;
}
@ -2772,7 +2774,7 @@ a.account__display-name {
}
.scrollable.fullscreen {
@supports(display: grid) { // hack to fix Chrome <57
@supports (display: grid) { // hack to fix Chrome <57
contain: none;
}
}
@ -3980,6 +3982,7 @@ a.status-card.compact:hover {
&__menu {
@include search-popout;
padding: 0;
background: $ui-secondary-color;
}
@ -4061,7 +4064,7 @@ a.status-card.compact:hover {
align-items: center;
justify-content: center;
@supports(display: grid) { // hack to fix Chrome <57
@supports (display: grid) { // hack to fix Chrome <57
contain: strict;
}
@ -4878,7 +4881,7 @@ a.status-card.compact:hover {
padding: 0;
border: 0;
font-size: 0;
transition: opacity .2s ease-in-out;
transition: opacity 0.2s ease-in-out;
&.active {
opacity: 1;
@ -4933,7 +4936,6 @@ a.status-card.compact:hover {
height: 100%;
box-sizing: border-box;
padding: 25px;
display: none;
flex-direction: column;
align-items: center;
justify-content: center;
@ -5274,7 +5276,6 @@ a.status-card.compact:hover {
display: block;
box-sizing: border-box;
width: 100%;
margin: 0;
color: $inverted-text-color;
background: $simple-background-color;
padding: 10px;
@ -5406,7 +5407,6 @@ a.status-card.compact:hover {
font-family: inherit;
font-size: 14px;
resize: none;
border: 0;
outline: 0;
border-radius: 4px;
border: 1px solid $ui-secondary-color;
@ -5857,6 +5857,7 @@ a.status-card.compact:hover {
overflow: hidden;
position: absolute;
}
/* End Media Gallery */
.detailed,
@ -5869,7 +5870,6 @@ a.status-card.compact:hover {
.video-player__volume__handle {
bottom: 23px;
}
}
.audio-player {
@ -5991,7 +5991,7 @@ a.status-card.compact:hover {
background: linear-gradient(0deg, rgba($base-shadow-color, 0.85) 0, rgba($base-shadow-color, 0.45) 60%, transparent);
padding: 0 15px;
opacity: 0;
transition: opacity .1s ease;
transition: opacity 0.1s ease;
&.active {
opacity: 1;
@ -6066,7 +6066,6 @@ a.status-card.compact:hover {
.player-button {
display: inline-block;
outline: 0;
flex: 0 0 auto;
background: transparent;
padding: 5px;
@ -6237,7 +6236,7 @@ a.status-card.compact:hover {
box-shadow: 1px 2px 6px rgba($base-shadow-color, 0.2);
.no-reduce-motion & {
transition: opacity .1s ease;
transition: opacity 0.1s ease;
}
&.active {
@ -6405,14 +6404,13 @@ a.status-card.compact:hover {
display: inline-block;
padding: 6px 0;
line-height: 18px;
cursor: default;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
cursor: pointer;
input[type=radio],
input[type=checkbox] {
input[type="radio"],
input[type="checkbox"] {
display: none;
}
@ -6505,13 +6503,15 @@ noscript {
.navigation-bar__actions {
& > .icon-button.close {
will-change: opacity transform;
transition: opacity $duration * 0.5 $delay,
transition:
opacity $duration * 0.5 $delay,
transform $duration $delay;
}
& > .compose__action-bar .icon-button {
will-change: opacity transform;
transition: opacity $duration * 0.5 $delay + $duration * 0.5,
transition:
opacity $duration * 0.5 $delay + $duration * 0.5,
transform $duration $delay;
}
}
@ -7286,7 +7286,7 @@ noscript {
border-radius: 50%;
width: 0.625rem;
height: 0.625rem;
margin: -.1ex .15em .1ex;
margin: -0.1ex 0.15em 0.1ex;
}
&__content {
@ -7549,7 +7549,6 @@ noscript {
position: absolute;
top: 0;
left: 0;
pointer-events: 0;
width: 100%;
height: 100%;
border-left: 2px solid $highlight-text-color;

View file

@ -37,7 +37,6 @@
text-align: center;
font-weight: 500;
font-size: 24px;
line-height: 21px;
color: $primary-text-color;
font-family: $font-display, sans-serif;
margin-bottom: 20px;

View file

@ -46,7 +46,7 @@
text-align: center;
padding: 12px 4px;
overflow: hidden;
transition: color .1s ease-out;
transition: color 0.1s ease-out;
cursor: pointer;
background: transparent;
border: 0;
@ -243,7 +243,7 @@
padding-top: 70px;
.emoji-mart-no-results-label {
margin-top: .2em;
margin-top: 0.2em;
}
.emoji-mart-emoji:hover::before {

View file

@ -352,7 +352,7 @@ code {
flex: 1 1 auto;
}
input[type=checkbox] {
input[type="checkbox"] {
position: absolute;
left: 0;
top: 5px;
@ -368,11 +368,11 @@ code {
border-radius: 4px;
}
input[type=text],
input[type=number],
input[type=email],
input[type=password],
input[type=url],
input[type="text"],
input[type="number"],
input[type="email"],
input[type="password"],
input[type="url"],
textarea {
box-sizing: border-box;
font-size: 16px;
@ -410,10 +410,10 @@ code {
}
}
input[type=text],
input[type=number],
input[type=email],
input[type=password] {
input[type="text"],
input[type="number"],
input[type="email"],
input[type="password"] {
&:focus:invalid:not(:placeholder-shown),
&:required:invalid:not(:placeholder-shown) {
border-color: lighten($error-red, 12%);
@ -425,10 +425,10 @@ code {
color: lighten($error-red, 12%);
}
input[type=text],
input[type=number],
input[type=email],
input[type=password],
input[type="text"],
input[type="number"],
input[type="email"],
input[type="password"],
textarea,
select {
border-color: lighten($error-red, 12%);
@ -1000,7 +1000,7 @@ code {
flex: 1 1 auto;
}
input[type=text] {
input[type="text"] {
background: transparent;
border: 0;
padding: 10px;

View file

@ -1,154 +0,0 @@
.introduction {
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
height: 100vh;
background: $ui-base-color;
@media screen and (max-width: 920px) {
display: block !important;
}
&__pager {
background: darken($ui-base-color, 8%);
box-shadow: 0 0 15px rgba($base-shadow-color, 0.2);
overflow: hidden;
}
&__pager,
&__frame {
border-radius: 10px;
width: 50vw;
min-width: 920px;
@media screen and (max-width: 920px) {
min-width: 0;
width: 100%;
border-radius: 0;
box-shadow: none;
}
}
&__frame-wrapper {
opacity: 0;
transition: opacity 500ms linear;
&.active {
opacity: 1;
transition: opacity 50ms linear;
}
}
&__frame {
overflow: hidden;
}
&__illustration {
height: 50vh;
@media screen and (max-width: 630px) {
height: auto;
}
img {
object-fit: cover;
display: block;
margin: 0;
width: 100%;
height: 100%;
}
}
&__text {
border-top: 2px solid $ui-highlight-color;
&--columnized {
display: flex;
& > div {
flex: 1 1 33.33%;
text-align: center;
padding: 25px;
padding-bottom: 30px;
}
@media screen and (max-width: 630px) {
display: block;
padding: 15px 0;
padding-bottom: 20px;
& > div {
padding: 10px 25px;
}
}
}
h3 {
font-size: 24px;
line-height: 1.5;
font-weight: 700;
margin-bottom: 10px;
}
p {
font-size: 16px;
line-height: 24px;
font-weight: 400;
color: $darker-text-color;
code {
display: inline-block;
background: darken($ui-base-color, 8%);
font-size: 15px;
border: 1px solid lighten($ui-base-color, 8%);
border-radius: 2px;
padding: 1px 3px;
}
}
&--centered {
padding: 25px;
padding-bottom: 30px;
text-align: center;
}
}
&__dots {
display: flex;
align-items: center;
justify-content: center;
padding: 25px;
@media screen and (max-width: 630px) {
display: none;
}
}
&__dot {
width: 14px;
height: 14px;
border-radius: 14px;
border: 1px solid $ui-highlight-color;
background: transparent;
margin: 0 3px;
cursor: pointer;
&:hover {
background: lighten($ui-base-color, 8%);
}
&.active {
cursor: default;
background: $ui-highlight-color;
}
}
&__action {
padding: 25px;
padding-top: 0;
display: flex;
align-items: center;
justify-content: center;
}
}

View file

@ -64,8 +64,8 @@
max-width: calc(100% - 45px - 25px);
}
input[type=radio],
input[type=checkbox] {
input[type="radio"],
input[type="checkbox"] {
display: none;
}
@ -73,7 +73,7 @@
flex: 1 1 auto;
}
input[type=text] {
input[type="text"] {
display: block;
box-sizing: border-box;
width: 100%;
@ -109,7 +109,6 @@
box-sizing: border-box;
width: 18px;
height: 18px;
flex: 0 0 auto;
margin-right: 10px;
top: -1px;
border-radius: 50%;
@ -198,7 +197,7 @@
&:active,
&:focus {
background-color: rgba($dark-text-color, .1);
background-color: rgba($dark-text-color, 0.1);
}
}

View file

@ -139,7 +139,7 @@ a.button.logo-button {
.embed,
.public-layout {
.status__content[data-spoiler=folded] {
.status__content[data-spoiler="folded"] {
.e-content {
display: none;
}

View file

@ -38,6 +38,7 @@ $highlight-text-color: $ui-highlight-color !default;
$action-button-color: $ui-base-lighter-color !default;
$passive-text-color: $gold-star !default;
$active-passive-text-color: $success-green !default;
// For texts on inverted backgrounds
$inverted-text-color: $ui-base-color !default;
$lighter-text-color: $ui-base-lighter-color !default;
@ -48,6 +49,7 @@ $cjk-langs: ja, ko, zh-CN, zh-HK, zh-TW;
// Variables for components
$media-modal-media-max-width: 100%;
// put margins on top and bottom of image to avoid the screen covered by image.
$media-modal-media-max-height: 80%;

View file

@ -18,7 +18,7 @@ class UserMailer < Devise::Mailer
return unless @resource.active_for_authentication?
I18n.with_locale(@resource.locale || I18n.default_locale) do
I18n.with_locale(locale) do
mail to: @resource.unconfirmed_email.presence || @resource.email,
subject: I18n.t(@resource.pending_reconfirmation? ? 'devise.mailer.reconfirmation_instructions.subject' : 'devise.mailer.confirmation_instructions.subject', instance: @instance),
template_name: @resource.pending_reconfirmation? ? 'reconfirmation_instructions' : 'confirmation_instructions'
@ -32,7 +32,7 @@ class UserMailer < Devise::Mailer
return unless @resource.active_for_authentication?
I18n.with_locale(@resource.locale || I18n.default_locale) do
I18n.with_locale(locale) do
mail to: @resource.email, subject: I18n.t('devise.mailer.reset_password_instructions.subject')
end
end
@ -43,7 +43,7 @@ class UserMailer < Devise::Mailer
return unless @resource.active_for_authentication?
I18n.with_locale(@resource.locale || I18n.default_locale) do
I18n.with_locale(locale) do
mail to: @resource.email, subject: I18n.t('devise.mailer.password_change.subject')
end
end
@ -54,7 +54,7 @@ class UserMailer < Devise::Mailer
return unless @resource.active_for_authentication?
I18n.with_locale(@resource.locale || I18n.default_locale) do
I18n.with_locale(locale) do
mail to: @resource.email, subject: I18n.t('devise.mailer.email_changed.subject')
end
end
@ -65,7 +65,7 @@ class UserMailer < Devise::Mailer
return unless @resource.active_for_authentication?
I18n.with_locale(@resource.locale || I18n.default_locale) do
I18n.with_locale(locale) do
mail to: @resource.email, subject: I18n.t('devise.mailer.two_factor_enabled.subject')
end
end
@ -76,7 +76,7 @@ class UserMailer < Devise::Mailer
return unless @resource.active_for_authentication?
I18n.with_locale(@resource.locale || I18n.default_locale) do
I18n.with_locale(locale) do
mail to: @resource.email, subject: I18n.t('devise.mailer.two_factor_disabled.subject')
end
end
@ -87,7 +87,7 @@ class UserMailer < Devise::Mailer
return unless @resource.active_for_authentication?
I18n.with_locale(@resource.locale || I18n.default_locale) do
I18n.with_locale(locale) do
mail to: @resource.email, subject: I18n.t('devise.mailer.two_factor_recovery_codes_changed.subject')
end
end
@ -98,7 +98,7 @@ class UserMailer < Devise::Mailer
return unless @resource.active_for_authentication?
I18n.with_locale(@resource.locale || I18n.default_locale) do
I18n.with_locale(locale) do
mail to: @resource.email, subject: I18n.t('devise.mailer.webauthn_enabled.subject')
end
end
@ -109,7 +109,7 @@ class UserMailer < Devise::Mailer
return unless @resource.active_for_authentication?
I18n.with_locale(@resource.locale || I18n.default_locale) do
I18n.with_locale(locale) do
mail to: @resource.email, subject: I18n.t('devise.mailer.webauthn_disabled.subject')
end
end
@ -121,7 +121,7 @@ class UserMailer < Devise::Mailer
return unless @resource.active_for_authentication?
I18n.with_locale(@resource.locale || I18n.default_locale) do
I18n.with_locale(locale) do
mail to: @resource.email, subject: I18n.t('devise.mailer.webauthn_credential.added.subject')
end
end
@ -133,7 +133,7 @@ class UserMailer < Devise::Mailer
return unless @resource.active_for_authentication?
I18n.with_locale(@resource.locale || I18n.default_locale) do
I18n.with_locale(locale) do
mail to: @resource.email, subject: I18n.t('devise.mailer.webauthn_credential.deleted.subject')
end
end
@ -144,7 +144,7 @@ class UserMailer < Devise::Mailer
return unless @resource.active_for_authentication?
I18n.with_locale(@resource.locale || I18n.default_locale) do
I18n.with_locale(locale) do
mail to: @resource.email, subject: I18n.t('user_mailer.welcome.subject')
end
end
@ -156,7 +156,7 @@ class UserMailer < Devise::Mailer
return unless @resource.active_for_authentication?
I18n.with_locale(@resource.locale || I18n.default_locale) do
I18n.with_locale(locale) do
mail to: @resource.email, subject: I18n.t('user_mailer.backup_ready.subject')
end
end
@ -167,7 +167,7 @@ class UserMailer < Devise::Mailer
@instance = Rails.configuration.x.local_domain
@statuses = @warning.statuses.includes(:account, :preloadable_poll, :media_attachments, active_mentions: [:account])
I18n.with_locale(@resource.locale || I18n.default_locale) do
I18n.with_locale(locale) do
mail to: @resource.email, subject: I18n.t("user_mailer.warning.subject.#{@warning.action}", acct: "@#{user.account.local_username_and_domain}")
end
end
@ -177,7 +177,7 @@ class UserMailer < Devise::Mailer
@instance = Rails.configuration.x.local_domain
@appeal = appeal
I18n.with_locale(@resource.locale || I18n.default_locale) do
I18n.with_locale(locale) do
mail to: @resource.email, subject: I18n.t('user_mailer.appeal_approved.subject', date: l(@appeal.created_at))
end
end
@ -187,7 +187,7 @@ class UserMailer < Devise::Mailer
@instance = Rails.configuration.x.local_domain
@appeal = appeal
I18n.with_locale(@resource.locale || I18n.default_locale) do
I18n.with_locale(locale) do
mail to: @resource.email, subject: I18n.t('user_mailer.appeal_rejected.subject', date: l(@appeal.created_at))
end
end
@ -200,8 +200,14 @@ class UserMailer < Devise::Mailer
@detection = Browser.new(user_agent)
@timestamp = timestamp.to_time.utc
I18n.with_locale(@resource.locale || I18n.default_locale) do
I18n.with_locale(locale) do
mail to: @resource.email, subject: I18n.t('user_mailer.suspicious_sign_in.subject')
end
end
private
def locale
@resource.locale.presence || I18n.default_locale
end
end

View file

@ -92,7 +92,7 @@ class Account < ApplicationRecord
# Local user validations
validates :username, format: { with: /\A[a-z0-9_]+\z/i }, length: { maximum: 30 }, if: -> { local? && will_save_change_to_username? && actor_type != 'Application' }
validates_with UnreservedUsernameValidator, if: -> { local? && will_save_change_to_username? }
validates_with UnreservedUsernameValidator, if: -> { local? && will_save_change_to_username? && actor_type != 'Application' }
validates :display_name, length: { maximum: MAX_DISPLAY_NAME_LENGTH }, if: -> { local? && will_save_change_to_display_name? }
validates :note, note_length: { maximum: MAX_NOTE_LENGTH }, if: -> { local? && will_save_change_to_note? }
validates :fields, length: { maximum: DEFAULT_FIELDS_SIZE }, if: -> { local? && will_save_change_to_fields? }

View file

@ -3,7 +3,7 @@
module AccountAvatar
extend ActiveSupport::Concern
IMAGE_MIME_TYPES = ['image/jpeg', 'image/png', 'image/gif'].freeze
IMAGE_MIME_TYPES = ['image/jpeg', 'image/png', 'image/gif', 'image/webp'].freeze
LIMIT = 2.megabytes
class_methods do

View file

@ -3,7 +3,7 @@
module AccountHeader
extend ActiveSupport::Concern
IMAGE_MIME_TYPES = ['image/jpeg', 'image/png', 'image/gif'].freeze
IMAGE_MIME_TYPES = ['image/jpeg', 'image/png', 'image/gif', 'image/webp'].freeze
LIMIT = 2.megabytes
MAX_PIXELS = 750_000 # 1500x500px

View file

@ -32,7 +32,7 @@ class CustomEmoji < ApplicationRecord
:(#{SHORTCODE_RE_FRAGMENT}):
(?=[^[:alnum:]:]|$)/x
IMAGE_MIME_TYPES = %w(image/png image/gif).freeze
IMAGE_MIME_TYPES = %w(image/png image/gif image/webp).freeze
belongs_to :category, class_name: 'CustomEmojiCategory', optional: true
has_one :local_counterpart, -> { where(domain: nil) }, class_name: 'CustomEmoji', primary_key: :shortcode, foreign_key: :shortcode

View file

@ -16,6 +16,7 @@
#
class DomainBlock < ApplicationRecord
include Paginable
include DomainNormalizable
include DomainMaterializable

View file

@ -44,7 +44,7 @@ class MediaAttachment < ApplicationRecord
MAX_VIDEO_MATRIX_LIMIT = 2_304_000 # 1920x1200px
MAX_VIDEO_FRAME_RATE = 60
IMAGE_FILE_EXTENSIONS = %w(.jpg .jpeg .png .gif).freeze
IMAGE_FILE_EXTENSIONS = %w(.jpg .jpeg .png .gif .webp).freeze
VIDEO_FILE_EXTENSIONS = %w(.webm .mp4 .m4v .mov).freeze
AUDIO_FILE_EXTENSIONS = %w(.ogg .oga .mp3 .wav .flac .opus .aac .m4a .3gp .wma).freeze
@ -55,7 +55,7 @@ class MediaAttachment < ApplicationRecord
small
).freeze
IMAGE_MIME_TYPES = %w(image/jpeg image/png image/gif).freeze
IMAGE_MIME_TYPES = %w(image/jpeg image/png image/gif image/webp).freeze
VIDEO_MIME_TYPES = %w(video/webm video/mp4 video/quicktime video/ogg).freeze
VIDEO_CONVERTIBLE_MIME_TYPES = %w(video/webm video/quicktime).freeze
AUDIO_MIME_TYPES = %w(audio/wave audio/wav audio/x-wav audio/x-pn-wave audio/ogg audio/vorbis audio/mpeg audio/mp3 audio/webm audio/flac audio/aac audio/m4a audio/x-m4a audio/mp4 audio/3gpp video/x-ms-asf).freeze

View file

@ -34,7 +34,7 @@
class PreviewCard < ApplicationRecord
include Attachmentable
IMAGE_MIME_TYPES = ['image/jpeg', 'image/png', 'image/gif'].freeze
IMAGE_MIME_TYPES = ['image/jpeg', 'image/png', 'image/gif', 'image/webp'].freeze
LIMIT = 1.megabytes
BLURHASH_OPTIONS = {

View file

@ -26,7 +26,6 @@
# otp_required_for_login :boolean default(FALSE), not null
# last_emailed_at :datetime
# otp_backup_codes :string is an Array
# filtered_languages :string default([]), not null, is an Array
# account_id :bigint(8) not null
# disabled :boolean default(FALSE), not null
# moderator :boolean default(FALSE), not null
@ -48,6 +47,7 @@ class User < ApplicationRecord
current_sign_in_ip
last_sign_in_ip
skip_sign_in_token
filtered_languages
)
include Settings::Extend

View file

@ -3,7 +3,7 @@
class NodeInfo::Serializer < ActiveModel::Serializer
include RoutingHelper
attributes :version, :software, :protocols, :usage, :open_registrations
attributes :version, :software, :protocols, :services, :usage, :open_registrations, :metadata
def version
'2.0'
@ -37,6 +37,10 @@ class NodeInfo::Serializer < ActiveModel::Serializer
Setting.registrations_mode != 'none' && !Rails.configuration.x.single_user_mode
end
def metadata
[]
end
private
def instance_presenter

View file

@ -0,0 +1,11 @@
# frozen_string_literal: true
class REST::Admin::DomainBlockSerializer < ActiveModel::Serializer
attributes :id, :domain, :created_at, :severity,
:reject_media, :reject_reports,
:private_comment, :public_comment, :obfuscate
def id
object.id.to_s
end
end

View file

@ -0,0 +1,15 @@
# frozen_string_literal: true
class REST::Admin::ExistingDomainBlockErrorSerializer < ActiveModel::Serializer
attributes :error
has_one :existing_domain_block, serializer: REST::Admin::DomainBlockSerializer
def error
I18n.t('admin.domain_blocks.existing_domain_block', name: existing_domain_block.domain)
end
def existing_domain_block
object
end
end

View file

@ -20,7 +20,7 @@
%p<
%span.p-summary> #{prerender_custom_emojis(h(status.spoiler_text), status.emojis)}&nbsp;
%button.status__content__spoiler-link= t('statuses.show_more')
.e-content
.e-content{ :lang => status.language }
= prerender_custom_emojis(status_content_format(status), status.emojis)
- if status.preloadable_poll

Some files were not shown because too many files have changed in this diff Show more