Merge pull request #739 from ThibG/glitch-soc/merge-upstream

Merge upstream changes
main
ThibG 6 years ago committed by GitHub
commit 17464c10ad
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -1,66 +0,0 @@
{
"presets": [
"react",
[
"env",
{
"exclude": ["transform-async-to-generator", "transform-regenerator"],
"loose": true,
"modules": false,
"targets": {
"browsers": ["last 2 versions", "IE >= 11", "iOS >= 9"]
}
}
]
],
"plugins": [
"syntax-dynamic-import",
["transform-object-rest-spread", { "useBuiltIns": true }],
"transform-decorators-legacy",
"transform-class-properties",
[
"react-intl",
{
"messagesDir": "./build/messages"
}
],
"preval"
],
"env": {
"development": {
"plugins": [
"transform-react-jsx-source",
"transform-react-jsx-self"
]
},
"production": {
"plugins": [
"lodash",
[
"transform-react-remove-prop-types",
{
"mode": "remove",
"removeImport": true,
"additionalLibraries": [
"react-immutable-proptypes"
]
}
],
"transform-react-inline-elements",
[
"transform-runtime",
{
"helpers": true,
"polyfill": false,
"regenerator": false
}
]
]
},
"test": {
"plugins": [
"transform-es2015-modules-commonjs"
]
}
}
}

@ -1,2 +1,2 @@
VAGRANT=true VAGRANT=true
LOCAL_DOMAIN=mastodon.dev LOCAL_DOMAIN=mastodon.local

@ -77,6 +77,11 @@ Rails/SkipsModelValidations:
Rails/HttpStatus: Rails/HttpStatus:
Enabled: false Enabled: false
Rails/Exit:
Exclude:
- 'lib/mastodon/*'
- 'lib/cli'
Style/ClassAndModuleChildren: Style/ClassAndModuleChildren:
Enabled: false Enabled: false

@ -34,7 +34,7 @@ gem 'devise', '~> 4.4'
gem 'devise-two-factor', '~> 3.0' gem 'devise-two-factor', '~> 3.0'
group :pam_authentication, optional: true do group :pam_authentication, optional: true do
gem 'devise_pam_authenticatable2', '~> 9.1' gem 'devise_pam_authenticatable2', '~> 9.2'
end end
gem 'net-ldap', '~> 0.10' gem 'net-ldap', '~> 0.10'
@ -88,7 +88,7 @@ gem 'tty-command', '~> 0.8', require: false
gem 'tty-prompt', '~> 0.16', require: false gem 'tty-prompt', '~> 0.16', require: false
gem 'twitter-text', '~> 1.14' gem 'twitter-text', '~> 1.14'
gem 'tzinfo-data', '~> 1.2018' gem 'tzinfo-data', '~> 1.2018'
gem 'webpacker', '~> 3.4' gem 'webpacker', '~> 3.5'
gem 'webpush' gem 'webpush'
gem 'json-ld', '~> 2.2' gem 'json-ld', '~> 2.2'

@ -174,7 +174,7 @@ GEM
devise (~> 4.0) devise (~> 4.0)
railties (< 5.3) railties (< 5.3)
rotp (~> 2.0) rotp (~> 2.0)
devise_pam_authenticatable2 (9.1.1) devise_pam_authenticatable2 (9.2.0)
devise (>= 4.0.0) devise (>= 4.0.0)
rpam2 (~> 4.0) rpam2 (~> 4.0)
diff-lcs (1.3) diff-lcs (1.3)
@ -629,7 +629,7 @@ GEM
addressable (>= 2.3.6) addressable (>= 2.3.6)
crack (>= 0.3.2) crack (>= 0.3.2)
hashdiff hashdiff
webpacker (3.4.3) webpacker (3.5.5)
activesupport (>= 4.2) activesupport (>= 4.2)
rack-proxy (>= 0.6.1) rack-proxy (>= 0.6.1)
railties (>= 4.2) railties (>= 4.2)
@ -671,7 +671,7 @@ DEPENDENCIES
derailed_benchmarks derailed_benchmarks
devise (~> 4.4) devise (~> 4.4)
devise-two-factor (~> 3.0) devise-two-factor (~> 3.0)
devise_pam_authenticatable2 (~> 9.1) devise_pam_authenticatable2 (~> 9.2)
doorkeeper (~> 5.0) doorkeeper (~> 5.0)
dotenv-rails (~> 2.2, < 2.3) dotenv-rails (~> 2.2, < 2.3)
fabrication (~> 2.20) fabrication (~> 2.20)
@ -761,7 +761,7 @@ DEPENDENCIES
twitter-text (~> 1.14) twitter-text (~> 1.14)
tzinfo-data (~> 1.2018) tzinfo-data (~> 1.2018)
webmock (~> 3.3) webmock (~> 3.3)
webpacker (~> 3.4) webpacker (~> 3.5)
webpush webpush
RUBY VERSION RUBY VERSION

14
Vagrantfile vendored

@ -85,6 +85,9 @@ Vagrant.configure(VAGRANTFILE_API_VERSION) do |config|
config.vm.provider :virtualbox do |vb| config.vm.provider :virtualbox do |vb|
vb.name = "mastodon" vb.name = "mastodon"
vb.customize ["modifyvm", :id, "--memory", "4096"] vb.customize ["modifyvm", :id, "--memory", "4096"]
# Increase the number of CPUs. Uncomment and adjust to
# increase performance
# vb.customize ["modifyvm", :id, "--cpus", "3"]
# Disable VirtualBox DNS proxy to skip long-delay IPv6 resolutions. # Disable VirtualBox DNS proxy to skip long-delay IPv6 resolutions.
# https://github.com/mitchellh/vagrant/issues/1172 # https://github.com/mitchellh/vagrant/issues/1172
@ -97,19 +100,22 @@ Vagrant.configure(VAGRANTFILE_API_VERSION) do |config|
end end
config.vm.hostname = "mastodon.dev"
# This uses the vagrant-hostsupdater plugin, and lets you # This uses the vagrant-hostsupdater plugin, and lets you
# access the development site at http://mastodon.dev. # access the development site at http://mastodon.local.
# If you change it, also change it in .env.vagrant before provisioning
# the vagrant server to update the development build.
#
# To install: # To install:
# $ vagrant plugin install vagrant-hostsupdater # $ vagrant plugin install vagrant-hostsupdater
config.vm.hostname = "mastodon.local"
if defined?(VagrantPlugins::HostsUpdater) if defined?(VagrantPlugins::HostsUpdater)
config.vm.network :private_network, ip: "192.168.42.42", nictype: "virtio" config.vm.network :private_network, ip: "192.168.42.42", nictype: "virtio"
config.hostsupdater.remove_on_suspend = false config.hostsupdater.remove_on_suspend = false
end end
if config.vm.networks.any? { |type, options| type == :private_network } if config.vm.networks.any? { |type, options| type == :private_network }
config.vm.synced_folder ".", "/vagrant", type: "nfs", mount_options: ['rw', 'vers=3', 'tcp'] config.vm.synced_folder ".", "/vagrant", type: "nfs", mount_options: ['rw', 'vers=3', 'tcp', 'actimeo=1']
else else
config.vm.synced_folder ".", "/vagrant" config.vm.synced_folder ".", "/vagrant"
end end

@ -133,7 +133,7 @@ class Auth::SessionsController < Devise::SessionsController
def clear_site_data def clear_site_data
return if continue_after? return if continue_after?
# Should be '"*"' but that doen't work in Chrome (neither does '"executionContexts"') # Should be '"*"' but that doesn't work in Chrome (neither does '"executionContexts"')
# https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Clear-Site-Data # https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Clear-Site-Data
response.headers['Clear-Site-Data'] = '"cache", "cookies"' response.headers['Clear-Site-Data'] = '"cache", "cookies"'
end end

@ -4,7 +4,7 @@ module Admin::AccountModerationNotesHelper
def admin_account_link_to(account) def admin_account_link_to(account)
return if account.nil? return if account.nil?
link_to admin_account_path(account.id), class: name_tag_classes(account) do link_to admin_account_path(account.id), class: name_tag_classes(account), title: account.acct do
safe_join([ safe_join([
image_tag(account.avatar.url, width: 15, height: 15, alt: display_name(account), class: 'avatar'), image_tag(account.avatar.url, width: 15, height: 15, alt: display_name(account), class: 'avatar'),
content_tag(:span, account.acct, class: 'username'), content_tag(:span, account.acct, class: 'username'),
@ -15,7 +15,7 @@ module Admin::AccountModerationNotesHelper
def admin_account_inline_link_to(account) def admin_account_inline_link_to(account)
return if account.nil? return if account.nil?
link_to admin_account_path(account.id), class: name_tag_classes(account, true) do link_to admin_account_path(account.id), class: name_tag_classes(account, true), title: account.acct do
content_tag(:span, account.acct, class: 'username') content_tag(:span, account.acct, class: 'username')
end end
end end

@ -7,13 +7,13 @@ module HomeHelper
} }
end end
def account_link_to(account, button = '') def account_link_to(account, button = '', size: 36, path: nil)
content_tag(:div, class: 'account') do content_tag(:div, class: 'account') do
content_tag(:div, class: 'account__wrapper') do content_tag(:div, class: 'account__wrapper') do
section = if account.nil? section = if account.nil?
content_tag(:div, class: 'account__display-name') do content_tag(:div, class: 'account__display-name') do
content_tag(:div, class: 'account__avatar-wrapper') do content_tag(:div, class: 'account__avatar-wrapper') do
content_tag(:div, '', class: 'account__avatar', style: "background-image: url(#{full_asset_url('avatars/original/missing.png', skip_pipeline: true)})") content_tag(:div, '', class: 'account__avatar', style: "width: #{size}px; height: #{size}px; background-size: #{size}px #{size}px; background-image: url(#{full_asset_url('avatars/original/missing.png', skip_pipeline: true)})")
end + end +
content_tag(:span, class: 'display-name') do content_tag(:span, class: 'display-name') do
content_tag(:strong, t('about.contact_missing')) + content_tag(:strong, t('about.contact_missing')) +
@ -21,9 +21,9 @@ module HomeHelper
end end
end end
else else
link_to(TagManager.instance.url_for(account), class: 'account__display-name') do link_to(path || TagManager.instance.url_for(account), class: 'account__display-name') do
content_tag(:div, class: 'account__avatar-wrapper') do content_tag(:div, class: 'account__avatar-wrapper') do
content_tag(:div, '', class: 'account__avatar', style: "background-image: url(#{account.avatar.url})") content_tag(:div, '', class: 'account__avatar', style: "width: #{size}px; height: #{size}px; background-size: #{size}px #{size}px; background-image: url(#{account.avatar.url})")
end + end +
content_tag(:span, class: 'display-name') do content_tag(:span, class: 'display-name') do
content_tag(:bdi) do content_tag(:bdi) do
@ -48,4 +48,12 @@ module HomeHelper
'1+' '1+'
end end
end end
def custom_field_classes(field)
if field.verified?
'verified'
else
'emojify'
end
end
end end

@ -50,3 +50,27 @@ delegate(document, '#account_locked', 'change', ({ target }) => {
lock.style.display = 'none'; lock.style.display = 'none';
} }
}); });
delegate(document, '.input-copy input', 'click', ({ target }) => {
target.select();
});
delegate(document, '.input-copy button', 'click', ({ target }) => {
const input = target.parentNode.querySelector('input');
input.focus();
input.select();
try {
if (document.execCommand('copy')) {
input.blur();
target.parentNode.classList.add('copied');
setTimeout(() => {
target.parentNode.classList.remove('copied');
}, 700);
}
} catch (err) {
console.error(err);
}
});

@ -267,6 +267,20 @@
} }
} }
.verified {
border: 1px solid rgba($valid-value-color, 0.5);
background: rgba($valid-value-color, 0.25);
a {
color: $valid-value-color;
font-weight: 500;
}
&__mark {
color: $valid-value-color;
}
}
dl:last-child { dl:last-child {
border-bottom: 0; border-bottom: 0;
} }

@ -1,3 +1,5 @@
$no-columns-breakpoint: 600px;
.admin-wrapper { .admin-wrapper {
display: flex; display: flex;
justify-content: center; justify-content: center;
@ -24,12 +26,22 @@
height: 100px; height: 100px;
} }
@media screen and (max-width: $no-columns-breakpoint) {
& > a:first-child {
display: none;
}
}
ul { ul {
list-style: none; list-style: none;
border-radius: 4px 0 0 4px; border-radius: 4px 0 0 4px;
overflow: hidden; overflow: hidden;
margin-bottom: 20px; margin-bottom: 20px;
@media screen and (max-width: $no-columns-breakpoint) {
margin-bottom: 0;
}
a { a {
display: block; display: block;
padding: 15px; padding: 15px;
@ -62,20 +74,24 @@
a { a {
border: 0; border: 0;
padding: 15px 35px; padding: 15px 35px;
}
}
&.selected { .simple-navigation-active-leaf a {
color: $primary-text-color; color: $primary-text-color;
background-color: $ui-highlight-color; background-color: $ui-highlight-color;
border-bottom: 0; border-bottom: 0;
border-radius: 0; border-radius: 0;
&:hover { &:hover {
background-color: lighten($ui-highlight-color, 5%); background-color: lighten($ui-highlight-color, 5%);
}
}
} }
} }
} }
& > ul > .simple-navigation-active-leaf a {
border-radius: 4px 0 0 4px;
}
} }
.content-wrapper { .content-wrapper {
@ -89,11 +105,19 @@
padding-top: 60px; padding-top: 60px;
padding-left: 25px; padding-left: 25px;
@media screen and (max-width: $no-columns-breakpoint) {
max-width: none;
padding: 15px;
padding-top: 30px;
}
h2 { h2 {
color: $secondary-text-color; color: $secondary-text-color;
font-size: 24px; font-size: 24px;
line-height: 28px; line-height: 28px;
font-weight: 400; font-weight: 400;
padding-bottom: 40px;
border-bottom: 1px solid lighten($ui-base-color, 8%);
margin-bottom: 40px; margin-bottom: 40px;
} }
@ -108,7 +132,7 @@
h4 { h4 {
text-transform: uppercase; text-transform: uppercase;
font-size: 13px; font-size: 13px;
font-weight: 500; font-weight: 700;
color: $darker-text-color; color: $darker-text-color;
padding-bottom: 8px; padding-bottom: 8px;
margin-bottom: 8px; margin-bottom: 8px;
@ -122,6 +146,11 @@
font-weight: 400; font-weight: 400;
} }
.fields-group h6 {
color: $primary-text-color;
font-weight: 500;
}
& > p { & > p {
font-size: 14px; font-size: 14px;
line-height: 18px; line-height: 18px;
@ -167,30 +196,7 @@
} }
} }
.simple_form { @media screen and (max-width: $no-columns-breakpoint) {
max-width: 400px;
&.edit_user,
&.new_form_admin_settings,
&.new_form_two_factor_confirmation,
&.new_form_delete_confirmation,
&.new_import,
&.new_domain_block,
&.edit_domain_block {
max-width: none;
}
.form_two_factor_confirmation_code,
.form_delete_confirmation_password {
max-width: 400px;
}
.actions {
max-width: 400px;
}
}
@media screen and (max-width: 600px) {
display: block; display: block;
overflow-y: auto; overflow-y: auto;
-webkit-overflow-scrolling: touch; -webkit-overflow-scrolling: touch;
@ -204,16 +210,8 @@
.sidebar { .sidebar {
width: 100%; width: 100%;
padding: 10px 0; padding: 0;
height: auto; height: auto;
.logo {
margin: 20px auto;
}
}
.content {
padding-top: 20px;
} }
} }
} }
@ -578,3 +576,102 @@ a.name-tag,
color: $dark-text-color; color: $dark-text-color;
} }
} }
.report-card {
background: $ui-base-color;
border-radius: 4px;
margin-bottom: 20px;
&__profile {
display: flex;
justify-content: space-between;
align-items: center;
padding: 15px;
.account {
padding: 0;
border: 0;
&__avatar-wrapper {
margin-left: 0;
}
}
&__stats {
flex: 0 0 auto;
font-weight: 500;
color: $darker-text-color;
text-transform: uppercase;
text-align: right;
a {
color: inherit;
text-decoration: none;
&:focus,
&:hover,
&:active {
color: lighten($darker-text-color, 8%);
}
}
.red {
color: $error-value-color;
}
}
}
&__summary {
&__item {
display: flex;
justify-content: flex-start;
border-top: 1px solid darken($ui-base-color, 4%);
&:hover {
background: lighten($ui-base-color, 2%);
}
&__reported-by,
&__assigned {
padding: 15px;
flex: 0 0 auto;
box-sizing: border-box;
width: 150px;
color: $darker-text-color;
&,
.username {
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
}
&__content {
flex: 1 1 auto;
max-width: calc(100% - 300px);
&__icon {
color: $dark-text-color;
margin-right: 4px;
font-weight: 500;
}
}
&__content a {
display: block;
box-sizing: border-box;
width: 100%;
padding: 15px;
text-decoration: none;
color: $darker-text-color;
}
}
}
}
.one-line {
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}

@ -1,3 +1,10 @@
@function hex-color($color) {
@if type-of($color) == 'color' {
$color: str-slice(ie-hex-str($color), 4);
}
@return '%23' + unquote($color)
}
body { body {
font-family: 'mastodon-font-sans-serif', sans-serif; font-family: 'mastodon-font-sans-serif', sans-serif;
background: darken($ui-base-color, 8%); background: darken($ui-base-color, 8%);

File diff suppressed because one or more lines are too long

@ -724,6 +724,14 @@
a { a {
color: lighten($ui-highlight-color, 8%); color: lighten($ui-highlight-color, 8%);
} }
dl:first-child .verified {
border-radius: 0 4px 0 0;
}
.verified a {
color: $valid-value-color;
}
} }
.account__header__content { .account__header__content {

@ -1,3 +1,5 @@
$no-columns-breakpoint: 600px;
code { code {
font-family: 'mastodon-font-monospace', monospace; font-family: 'mastodon-font-monospace', monospace;
font-weight: 400; font-weight: 400;
@ -13,6 +15,60 @@ code {
.input { .input {
margin-bottom: 15px; margin-bottom: 15px;
overflow: hidden; overflow: hidden;
&.hidden {
margin: 0;
}
&.radio_buttons {
.radio {
margin-bottom: 15px;
&:last-child {
margin-bottom: 0;
}
}
.radio > label {
position: relative;
padding-left: 28px;
input {
position: absolute;
top: -2px;
left: 0;
}
}
}
&.boolean {
position: relative;
margin-bottom: 0;
.label_input > label {
font-family: inherit;
font-size: 14px;
padding-top: 5px;
color: $primary-text-color;
display: block;
width: auto;
}
.label_input,
.hint {
padding-left: 28px;
}
.label_input__wrapper {
position: static;
}
label.checkbox {
position: absolute;
top: 2px;
left: 0;
}
}
} }
.row { .row {
@ -27,9 +83,22 @@ code {
} }
} }
.hint {
color: $darker-text-color;
a {
color: $highlight-text-color;
}
code {
border-radius: 3px;
padding: 0.2em 0.4em;
background: darken($ui-base-color, 12%);
}
}
span.hint { span.hint {
display: block; display: block;
color: $darker-text-color;
font-size: 12px; font-size: 12px;
margin-top: 4px; margin-top: 4px;
} }
@ -44,11 +113,6 @@ code {
line-height: 18px; line-height: 18px;
margin-top: 15px; margin-top: 15px;
margin-bottom: 0; margin-bottom: 0;
color: $darker-text-color;
a {
color: $highlight-text-color;
}
} }
} }
@ -66,81 +130,60 @@ code {
} }
} }
.label_input { .input.with_floating_label {
display: flex; .label_input {
display: flex;
label { & > label {
flex: 0 0 auto; font-family: inherit;
font-size: 14px;
color: $primary-text-color;
font-weight: 500;
min-width: 150px;
flex: 0 0 auto;
}
input,
select {
flex: 1 1 auto;
}
} }
input { &.select .hint {
flex: 1 1 auto; margin-top: 6px;
margin-left: 150px;
} }
} }
.input.with_label { .input.with_label {
padding: 15px 0;
margin-bottom: 0;
.label_input {
flex-wrap: wrap;
align-items: flex-start;
}
&.select .label_input {
align-items: initial;
}
.label_input > label { .label_input > label {
font-family: inherit; font-family: inherit;
font-size: 16px; font-size: 14px;
color: $primary-text-color; color: $primary-text-color;
display: block; display: block;
padding-top: 5px; margin-bottom: 8px;
margin-bottom: 5px;
flex: 1;
min-width: 150px;
word-wrap: break-word; word-wrap: break-word;
font-weight: 500;
}
&.select { .hint {
flex: 0; margin-top: 6px;
}
& ~ * {
margin-left: 10px;
}
} }
ul { ul {
flex: 390px; flex: 390px;
} }
&.boolean {
padding: initial;
margin-bottom: initial;
.label_input > label {
font-family: inherit;
font-size: 14px;
color: $primary-text-color;
display: block;
width: auto;
}
label.checkbox {
position: relative;
padding-left: 25px;
flex: 1 1 auto;
}
}
} }
.input.with_block_label { .input.with_block_label {
max-width: none;
& > label { & > label {
font-family: inherit; font-family: inherit;
font-size: 16px; font-size: 16px;
color: $primary-text-color; color: $primary-text-color;
display: block; display: block;
font-weight: 500;
padding-top: 5px; padding-top: 5px;
} }
@ -148,55 +191,75 @@ code {
margin-bottom: 15px; margin-bottom: 15px;
} }
li { ul {
float: left; columns: 2;
width: 50%;
} }
} }
.required abbr {
text-decoration: none;
color: lighten($error-value-color, 12%);
}
.fields-group { .fields-group {
margin-bottom: 25px; margin-bottom: 25px;
}
.input.radio_buttons .radio label { .input:last-child {
margin-bottom: 5px; margin-bottom: 0;
font-family: inherit; }
font-size: 14px;
color: $primary-text-color;
display: block;
width: auto;
} }
.input.boolean { .fields-row {
margin-bottom: 5px; display: flex;
margin: 0 -10px;
padding-top: 5px;
margin-bottom: 25px;
label { .input {
font-family: inherit; max-width: none;
font-size: 14px;
color: $primary-text-color;
display: block;
width: auto;
} }
label.checkbox { &__column {
position: relative; box-sizing: border-box;
padding-left: 25px; padding: 0 10px;
flex: 1 1 auto; flex: 1 1 auto;
min-height: 1px;
&-6 {
max-width: 50%;
}
} }
input[type=checkbox] { .fields-group:last-child,
position: absolute; .fields-row__column.fields-group {
left: 0; margin-bottom: 0;
top: 5px;
margin: 0;
} }
.hint { @media screen and (max-width: $no-columns-breakpoint) {
padding-left: 25px; display: block;
margin-left: 0; margin-bottom: 0;
&__column {
max-width: none;
}
.fields-group:last-child,
.fields-row__column.fields-group,
.fields-row__column {
margin-bottom: 25px;
}
} }
} }
.input.radio_buttons .radio label {
margin-bottom: 5px;
font-family: inherit;
font-size: 14px;
color: $primary-text-color;
display: block;
width: auto;
}
.check_boxes { .check_boxes {
.checkbox { .checkbox {
label { label {
@ -225,12 +288,7 @@ code {
input[type=email], input[type=email],
input[type=password], input[type=password],
textarea { textarea {
background: transparent;
box-sizing: border-box; box-sizing: border-box;
border: 0;
border-bottom: 2px solid $ui-primary-color;
border-radius: 2px 2px 0 0;
padding: 7px 4px;
font-size: 16px; font-size: 16px;
color: $primary-text-color; color: $primary-text-color;
display: block; display: block;
@ -238,23 +296,31 @@ code {
outline: 0; outline: 0;
font-family: inherit; font-family: inherit;
resize: vertical; resize: vertical;
background: darken($ui-base-color, 10%);
border: 1px solid darken($ui-base-color, 14%);
border-radius: 4px;
padding: 10px;
&:invalid { &:invalid {
box-shadow: none; box-shadow: none;
} }
&:focus:invalid { &:focus:invalid {
border-bottom-color: lighten($error-red, 12%); border-color: lighten($error-red, 12%);
} }
&:required:valid { &:required:valid {
border-bottom-color: $valid-value-color; border-color: $valid-value-color;
}
&:hover {
border-color: darken($ui-base-color, 20%);
} }
&:active, &:active,
&:focus { &:focus {
border-bottom-color: $highlight-text-color; border-color: $highlight-text-color;
background: rgba($base-overlay-background, 0.1); background: darken($ui-base-color, 8%);
} }
} }
@ -338,28 +404,52 @@ code {
} }
select { select {
appearance: none;
box-sizing: border-box;
font-size: 16px; font-size: 16px;
max-height: 29px; color: $primary-text-color;
display: block;
width: 100%;
outline: 0;
font-family: inherit;
resize: vertical;
background: darken($ui-base-color, 10%) url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 14.933 18.467' height='19.698' width='15.929'><path d='M3.467 14.967l-3.393-3.5H14.86l-3.392 3.5c-1.866 1.925-3.666 3.5-4 3.5-.335 0-2.135-1.575-4-3.5zm.266-11.234L7.467 0 11.2 3.733l3.733 3.734H0l3.733-3.734z' fill='#{hex-color(lighten($ui-base-color, 12%))}'/></svg>") no-repeat right 8px center / auto 16px;
border: 1px solid darken($ui-base-color, 14%);
border-radius: 4px;
padding: 10px;
height: 41px;
} }
.input-with-append { .label_input {
position: relative; &__wrapper {
position: relative;
.input input {
padding-right: 127px;
} }
.append { &__append {
position: absolute; position: absolute;
right: 0; right: 1px;
top: 0; top: 1px;
padding: 7px 4px; padding: 10px;
padding-bottom: 9px; padding-bottom: 9px;
font-size: 16px; font-size: 16px;
color: $dark-text-color; color: $dark-text-color;
font-family: inherit; font-family: inherit;
pointer-events: none; pointer-events: none;
cursor: default; cursor: default;
max-width: 140px;
white-space: nowrap;
overflow: hidden;
&::after {
content: '';
display: block;
position: absolute;
top: 0;
right: 0;
bottom: 1px;
width: 5px;
background-image: linear-gradient(to right, rgba(darken($ui-base-color, 10%), 0), darken($ui-base-color, 10%));
}
} }
} }
} }
@ -434,6 +524,30 @@ code {
} }
} }
.quick-nav {
list-style: none;
margin-bottom: 25px;
font-size: 14px;
li {
display: inline-block;
margin-right: 10px;
}
a {
color: $highlight-text-color;
text-transform: uppercase;
text-decoration: none;
font-weight: 700;
&:hover,
&:focus,
&:active {
color: lighten($highlight-text-color, 8%);
}
}
}
.oauth-prompt, .oauth-prompt,
.follow-prompt { .follow-prompt {
margin-bottom: 30px; margin-bottom: 30px;
@ -592,3 +706,64 @@ code {
display: block; display: block;
} }
} }
.scope-danger {
color: $warning-red;
}
.form_admin_settings_site_short_description,
.form_admin_settings_site_description,
.form_admin_settings_site_extended_description,
.form_admin_settings_site_terms,
.form_admin_settings_custom_css,
.form_admin_settings_closed_registrations_message {
textarea {
font-family: 'mastodon-font-monospace', monospace;
}
}
.input-copy {
background: darken($ui-base-color, 10%);
border: 1px solid darken($ui-base-color, 14%);
border-radius: 4px;
display: flex;
align-items: center;
padding-right: 4px;
position: relative;
top: 1px;
transition: border-color 300ms linear;
&__wrapper {
flex: 1 1 auto;
}
input[type=text] {
background: transparent;
border: 0;
padding: 10px;
font-size: 14px;
font-family: 'mastodon-font-monospace', monospace;
}
button {
flex: 0 0 auto;
margin: 4px;
text-transform: none;
font-weight: 400;
font-size: 14px;
padding: 7px 18px;
padding-bottom: 6px;
width: auto;
transition: background 300ms linear;
}
&.copied {
border-color: $valid-value-color;
transition: none;
button {
background: $valid-value-color;
transition: none;
}
}
}

@ -206,13 +206,19 @@ body.rtl {
} }
.simple_form .input-with-append .input input { .simple_form .input-with-append .input input {
padding-left: 127px; padding-left: 142px;
padding-right: 0; padding-right: 0;
} }
.simple_form .input-with-append .append { .simple_form .input-with-append .append {
right: auto; right: auto;
left: 0; left: 0;
&::after {
right: auto;
left: 0;
background-image: linear-gradient(to left, rgba($ui-base-color, 0), $ui-base-color);
}
} }
.table th, .table th,

@ -1,8 +1,8 @@
export const DROPDOWN_MENU_OPEN = 'DROPDOWN_MENU_OPEN'; export const DROPDOWN_MENU_OPEN = 'DROPDOWN_MENU_OPEN';
export const DROPDOWN_MENU_CLOSE = 'DROPDOWN_MENU_CLOSE'; export const DROPDOWN_MENU_CLOSE = 'DROPDOWN_MENU_CLOSE';
export function openDropdownMenu(id, placement) { export function openDropdownMenu(id, placement, keyboard) {
return { type: DROPDOWN_MENU_OPEN, id, placement }; return { type: DROPDOWN_MENU_OPEN, id, placement, keyboard };
} }
export function closeDropdownMenu(id) { export function closeDropdownMenu(id) {

@ -3,7 +3,6 @@
exports[`<Button /> adds class "button-secondary" if props.secondary given 1`] = ` exports[`<Button /> adds class "button-secondary" if props.secondary given 1`] = `
<button <button
className="button button-secondary" className="button button-secondary"
disabled={undefined}
onClick={[Function]} onClick={[Function]}
style={ style={
Object { Object {
@ -18,7 +17,6 @@ exports[`<Button /> adds class "button-secondary" if props.secondary given 1`] =
exports[`<Button /> renders a button element 1`] = ` exports[`<Button /> renders a button element 1`] = `
<button <button
className="button" className="button"
disabled={undefined}
onClick={[Function]} onClick={[Function]}
style={ style={
Object { Object {
@ -48,7 +46,6 @@ exports[`<Button /> renders a disabled attribute if props.disabled given 1`] = `
exports[`<Button /> renders class="button--block" if props.block given 1`] = ` exports[`<Button /> renders class="button--block" if props.block given 1`] = `
<button <button
className="button button--block" className="button button--block"
disabled={undefined}
onClick={[Function]} onClick={[Function]}
style={ style={
Object { Object {
@ -63,7 +60,6 @@ exports[`<Button /> renders class="button--block" if props.block given 1`] = `
exports[`<Button /> renders the children 1`] = ` exports[`<Button /> renders the children 1`] = `
<button <button
className="button" className="button"
disabled={undefined}
onClick={[Function]} onClick={[Function]}
style={ style={
Object { Object {
@ -82,7 +78,6 @@ exports[`<Button /> renders the children 1`] = `
exports[`<Button /> renders the given text 1`] = ` exports[`<Button /> renders the given text 1`] = `
<button <button
className="button" className="button"
disabled={undefined}
onClick={[Function]} onClick={[Function]}
style={ style={
Object { Object {
@ -99,7 +94,6 @@ exports[`<Button /> renders the given text 1`] = `
exports[`<Button /> renders the props.text instead of children 1`] = ` exports[`<Button /> renders the props.text instead of children 1`] = `
<button <button
className="button" className="button"
disabled={undefined}
onClick={[Function]} onClick={[Function]}
style={ style={
Object { Object {

@ -19,8 +19,8 @@ const messages = defineMessages({
unmute_notifications: { id: 'account.unmute_notifications', defaultMessage: 'Unmute notifications from @{name}' }, unmute_notifications: { id: 'account.unmute_notifications', defaultMessage: 'Unmute notifications from @{name}' },
}); });
@injectIntl export default @injectIntl
export default class Account extends ImmutablePureComponent { class Account extends ImmutablePureComponent {
static propTypes = { static propTypes = {
account: ImmutablePropTypes.map.isRequired, account: ImmutablePropTypes.map.isRequired,

@ -10,8 +10,8 @@ const messages = defineMessages({
moveRight: { id: 'column_header.moveRight_settings', defaultMessage: 'Move column to the right' }, moveRight: { id: 'column_header.moveRight_settings', defaultMessage: 'Move column to the right' },
}); });
@injectIntl export default @injectIntl
export default class ColumnHeader extends React.PureComponent { class ColumnHeader extends React.PureComponent {
static contextTypes = { static contextTypes = {
router: PropTypes.object, router: PropTypes.object,

@ -8,8 +8,8 @@ const messages = defineMessages({
unblockDomain: { id: 'account.unblock_domain', defaultMessage: 'Unhide {domain}' }, unblockDomain: { id: 'account.unblock_domain', defaultMessage: 'Unhide {domain}' },
}); });
@injectIntl export default @injectIntl
export default class Account extends ImmutablePureComponent { class Account extends ImmutablePureComponent {
static propTypes = { static propTypes = {
domain: PropTypes.string, domain: PropTypes.string,

@ -23,6 +23,7 @@ class DropdownMenu extends React.PureComponent {
placement: PropTypes.string, placement: PropTypes.string,
arrowOffsetLeft: PropTypes.string, arrowOffsetLeft: PropTypes.string,
arrowOffsetTop: PropTypes.string, arrowOffsetTop: PropTypes.string,
openedViaKeyboard: PropTypes.bool,
}; };
static defaultProps = { static defaultProps = {
@ -42,13 +43,15 @@ class DropdownMenu extends React.PureComponent {
componentDidMount () { componentDidMount () {
document.addEventListener('click', this.handleDocumentClick, false); document.addEventListener('click', this.handleDocumentClick, false);
document.addEventListener('keydown', this.handleKeyDown, false);
document.addEventListener('touchend', this.handleDocumentClick, listenerOptions); document.addEventListener('touchend', this.handleDocumentClick, listenerOptions);
if (this.focusedItem) this.focusedItem.focus(); if (this.focusedItem && this.props.openedViaKeyboard) this.focusedItem.focus();
this.setState({ mounted: true }); this.setState({ mounted: true });
} }
componentWillUnmount () { componentWillUnmount () {
document.removeEventListener('click', this.handleDocumentClick, false); document.removeEventListener('click', this.handleDocumentClick, false);
document.removeEventListener('keydown', this.handleKeyDown, false);
document.removeEventListener('touchend', this.handleDocumentClick, listenerOptions); document.removeEventListener('touchend', this.handleDocumentClick, listenerOptions);
} }
@ -62,13 +65,10 @@ class DropdownMenu extends React.PureComponent {
handleKeyDown = e => { handleKeyDown = e => {
const items = Array.from(this.node.getElementsByTagName('a')); const items = Array.from(this.node.getElementsByTagName('a'));
const index = items.indexOf(e.currentTarget); const index = items.indexOf(document.activeElement);
let element; let element;
switch(e.key) { switch(e.key) {
case 'Enter':
this.handleClick(e);
break;
case 'ArrowDown': case 'ArrowDown':
element = items[index+1]; element = items[index+1];
if (element) { if (element) {
@ -96,6 +96,12 @@ class DropdownMenu extends React.PureComponent {
} }
} }
handleItemKeyDown = e => {
if (e.key === 'Enter') {
this.handleClick(e);
}
}
handleClick = e => { handleClick = e => {
const i = Number(e.currentTarget.getAttribute('data-index')); const i = Number(e.currentTarget.getAttribute('data-index'));
const { action, to } = this.props.items[i]; const { action, to } = this.props.items[i];
@ -120,7 +126,7 @@ class DropdownMenu extends React.PureComponent {
return ( return (
<li className='dropdown-menu__item' key={`${text}-${i}`}> <li className='dropdown-menu__item' key={`${text}-${i}`}>
<a href={href} target='_blank' rel='noopener' role='button' tabIndex='0' ref={i === 0 ? this.setFocusRef : null} onClick={this.handleClick} onKeyDown={this.handleKeyDown} data-index={i}> <a href={href} target='_blank' rel='noopener' role='button' tabIndex='0' ref={i === 0 ? this.setFocusRef : null} onClick={this.handleClick} onKeyDown={this.handleItemKeyDown} data-index={i}>
{text} {text}
</a> </a>
</li> </li>
@ -170,6 +176,7 @@ export default class Dropdown extends React.PureComponent {
onClose: PropTypes.func.isRequired, onClose: PropTypes.func.isRequired,
dropdownPlacement: PropTypes.string, dropdownPlacement: PropTypes.string,
openDropdownId: PropTypes.number, openDropdownId: PropTypes.number,
openedViaKeyboard: PropTypes.bool,
}; };
static defaultProps = { static defaultProps = {
@ -180,14 +187,14 @@ export default class Dropdown extends React.PureComponent {
id: id++, id: id++,
}; };
handleClick = ({ target }) => { handleClick = ({ target, type }) => {
if (this.state.id === this.props.openDropdownId) { if (this.state.id === this.props.openDropdownId) {
this.handleClose(); this.handleClose();
} else { } else {
const { top } = target.getBoundingClientRect(); const { top } = target.getBoundingClientRect();
const placement = top * 2 < innerHeight ? 'bottom' : 'top'; const placement = top * 2 < innerHeight ? 'bottom' : 'top';
this.props.onOpen(this.state.id, this.handleItemClick, placement); this.props.onOpen(this.state.id, this.handleItemClick, placement, type !== 'click');
} }
} }
@ -197,6 +204,11 @@ export default class Dropdown extends React.PureComponent {
handleKeyDown = e => { handleKeyDown = e => {
switch(e.key) { switch(e.key) {
case ' ':
case 'Enter':
this.handleClick(e);
e.preventDefault();
break;
case 'Escape': case 'Escape':
this.handleClose(); this.handleClose();
break; break;
@ -233,7 +245,7 @@ export default class Dropdown extends React.PureComponent {
} }
render () { render () {
const { icon, items, size, title, disabled, dropdownPlacement, openDropdownId } = this.props; const { icon, items, size, title, disabled, dropdownPlacement, openDropdownId, openedViaKeyboard } = this.props;
const open = this.state.id === openDropdownId; const open = this.state.id === openDropdownId;
return ( return (
@ -249,7 +261,7 @@ export default class Dropdown extends React.PureComponent {
/> />
<Overlay show={open} placement={dropdownPlacement} target={this.findTarget}> <Overlay show={open} placement={dropdownPlacement} target={this.findTarget}>
<DropdownMenu items={items} onClose={this.handleClose} /> <DropdownMenu items={items} onClose={this.handleClose} openedViaKeyboard={openedViaKeyboard} />
</Overlay> </Overlay>
</div> </div>
); );

@ -6,8 +6,8 @@ const messages = defineMessages({
load_more: { id: 'status.load_more', defaultMessage: 'Load more' }, load_more: { id: 'status.load_more', defaultMessage: 'Load more' },
}); });
@injectIntl export default @injectIntl
export default class LoadGap extends React.PureComponent { class LoadGap extends React.PureComponent {
static propTypes = { static propTypes = {
disabled: PropTypes.bool, disabled: PropTypes.bool,

@ -179,8 +179,8 @@ class Item extends React.PureComponent {
} }
@injectIntl export default @injectIntl
export default class MediaGallery extends React.PureComponent { class MediaGallery extends React.PureComponent {
static propTypes = { static propTypes = {
sensitive: PropTypes.bool, sensitive: PropTypes.bool,

@ -86,8 +86,8 @@ export const timeAgoString = (intl, date, now, year) => {
return relativeTime; return relativeTime;
}; };
@injectIntl export default @injectIntl
export default class RelativeTimestamp extends React.Component { class RelativeTimestamp extends React.Component {
static propTypes = { static propTypes = {
intl: PropTypes.object.isRequired, intl: PropTypes.object.isRequired,

@ -35,8 +35,8 @@ export const textForScreenReader = (intl, status, rebloggedByText = false) => {
return values.join(', '); return values.join(', ');
}; };
@injectIntl export default @injectIntl
export default class Status extends ImmutablePureComponent { class Status extends ImmutablePureComponent {
static contextTypes = { static contextTypes = {
router: PropTypes.object, router: PropTypes.object,

@ -42,8 +42,8 @@ const obfuscatedCount = count => {
} }
}; };
@injectIntl export default @injectIntl
export default class StatusActionBar extends ImmutablePureComponent { class StatusActionBar extends ImmutablePureComponent {
static contextTypes = { static contextTypes = {
router: PropTypes.object, router: PropTypes.object,

@ -8,15 +8,16 @@ const mapStateToProps = state => ({
isModalOpen: state.get('modal').modalType === 'ACTIONS', isModalOpen: state.get('modal').modalType === 'ACTIONS',
dropdownPlacement: state.getIn(['dropdown_menu', 'placement']), dropdownPlacement: state.getIn(['dropdown_menu', 'placement']),
openDropdownId: state.getIn(['dropdown_menu', 'openId']), openDropdownId: state.getIn(['dropdown_menu', 'openId']),
openedViaKeyboard: state.getIn(['dropdown_menu', 'keyboard']),
}); });
const mapDispatchToProps = (dispatch, { status, items }) => ({ const mapDispatchToProps = (dispatch, { status, items }) => ({
onOpen(id, onItemClick, dropdownPlacement) { onOpen(id, onItemClick, dropdownPlacement, keyboard) {
dispatch(isUserTouching() ? openModal('ACTIONS', { dispatch(isUserTouching() ? openModal('ACTIONS', {
status, status,
actions: items, actions: items,
onClick: onItemClick, onClick: onItemClick,
}) : openDropdownMenu(id, dropdownPlacement)); }) : openDropdownMenu(id, dropdownPlacement, keyboard));
}, },
onClose(id) { onClose(id) {
dispatch(closeModal()); dispatch(closeModal());

@ -2,7 +2,7 @@ import React from 'react';
import ImmutablePropTypes from 'react-immutable-proptypes'; import ImmutablePropTypes from 'react-immutable-proptypes';
import PropTypes from 'prop-types'; import PropTypes from 'prop-types';
import DropdownMenuContainer from '../../../containers/dropdown_menu_container'; import DropdownMenuContainer from '../../../containers/dropdown_menu_container';
import { Link } from 'react-router-dom'; import { NavLink } from 'react-router-dom';
import { defineMessages, injectIntl, FormattedMessage } from 'react-intl'; import { defineMessages, injectIntl, FormattedMessage } from 'react-intl';
import { me } from '../../../initial_state'; import { me } from '../../../initial_state';
import { shortNumberFormat } from '../../../utils/numbers'; import { shortNumberFormat } from '../../../utils/numbers';
@ -36,8 +36,8 @@ const messages = defineMessages({
unendorse: { id: 'account.unendorse', defaultMessage: 'Don\'t feature on profile' }, unendorse: { id: 'account.unendorse', defaultMessage: 'Don\'t feature on profile' },
}); });
@injectIntl export default @injectIntl
export default class ActionBar extends React.PureComponent { class ActionBar extends React.PureComponent {
static propTypes = { static propTypes = {
account: ImmutablePropTypes.map.isRequired, account: ImmutablePropTypes.map.isRequired,
@ -60,6 +60,13 @@ export default class ActionBar extends React.PureComponent {
}); });
} }
isStatusesPageActive = (match, location) => {
if (!match) {
return false;
}
return !location.pathname.match(/\/(followers|following)\/?$/);
}
render () { render () {
const { account, intl } = this.props; const { account, intl } = this.props;
@ -147,20 +154,20 @@ export default class ActionBar extends React.PureComponent {
<div className='account__action-bar'> <div className='account__action-bar'>
<div className='account__action-bar-links'> <div className='account__action-bar-links'>
<Link className='account__action-bar__tab' to={`/accounts/${account.get('id')}`} title={intl.formatNumber(account.get('statuses_count'))}> <NavLink isActive={this.isStatusesPageActive} activeClassName='active' className='account__action-bar__tab' to={`/accounts/${account.get('id')}`} title={intl.formatNumber(account.get('statuses_count'))}>
<FormattedMessage id='account.posts' defaultMessage='Toots' /> <FormattedMessage id='account.posts' defaultMessage='Toots' />
<strong>{shortNumberFormat(account.get('statuses_count'))}</strong> <strong>{shortNumberFormat(account.get('statuses_count'))}</strong>
</Link> </NavLink>
<Link className='account__action-bar__tab' to={`/accounts/${account.get('id')}/following`} title={intl.formatNumber(account.get('following_count'))}> <NavLink exact activeClassName='active' className='account__action-bar__tab' to={`/accounts/${account.get('id')}/following`} title={intl.formatNumber(account.get('following_count'))}>
<FormattedMessage id='account.follows' defaultMessage='Follows' /> <FormattedMessage id='account.follows' defaultMessage='Follows' />
<strong>{shortNumberFormat(account.get('following_count'))}</strong> <strong>{shortNumberFormat(account.get('following_count'))}</strong>
</Link> </NavLink>
<Link className='account__action-bar__tab' to={`/accounts/${account.get('id')}/followers`} title={intl.formatNumber(account.get('followers_count'))}> <NavLink exact activeClassName='active' className='account__action-bar__tab' to={`/accounts/${account.get('id')}/followers`} title={intl.formatNumber(account.get('followers_count'))}>
<FormattedMessage id='account.followers' defaultMessage='Followers' /> <FormattedMessage id='account.followers' defaultMessage='Followers' />
<strong>{shortNumberFormat(account.get('followers_count'))}</strong> <strong>{shortNumberFormat(account.get('followers_count'))}</strong>
</Link> </NavLink>
</div> </div>
<div className='account__action-bar-dropdown'> <div className='account__action-bar-dropdown'>

@ -15,8 +15,18 @@ const messages = defineMessages({
requested: { id: 'account.requested', defaultMessage: 'Awaiting approval. Click to cancel follow request' }, requested: { id: 'account.requested', defaultMessage: 'Awaiting approval. Click to cancel follow request' },
unblock: { id: 'account.unblock', defaultMessage: 'Unblock @{name}' }, unblock: { id: 'account.unblock', defaultMessage: 'Unblock @{name}' },
edit_profile: { id: 'account.edit_profile', defaultMessage: 'Edit profile' }, edit_profile: { id: 'account.edit_profile', defaultMessage: 'Edit profile' },
linkVerifiedOn: { id: 'account.link_verified_on', defaultMessage: 'Ownership of this link was checked on {date}' },
}); });
const dateFormatOptions = {
month: 'short',
day: 'numeric',
year: 'numeric',
hour12: false,
hour: '2-digit',
minute: '2-digit',
};
class Avatar extends ImmutablePureComponent { class Avatar extends ImmutablePureComponent {
static propTypes = { static propTypes = {
@ -65,8 +75,8 @@ class Avatar extends ImmutablePureComponent {
} }
@injectIntl export default @injectIntl
export default class Header extends ImmutablePureComponent { class Header extends ImmutablePureComponent {
static propTypes = { static propTypes = {
account: ImmutablePropTypes.map, account: ImmutablePropTypes.map,
@ -163,7 +173,10 @@ export default class Header extends ImmutablePureComponent {
{fields.map((pair, i) => ( {fields.map((pair, i) => (
<dl key={i}> <dl key={i}>
<dt dangerouslySetInnerHTML={{ __html: pair.get('name_emojified') }} title={pair.get('name')} /> <dt dangerouslySetInnerHTML={{ __html: pair.get('name_emojified') }} title={pair.get('name')} />
<dd dangerouslySetInnerHTML={{ __html: pair.get('value_emojified') }} title={pair.get('value_plain')} />
<dd className={pair.get('verified_at') && 'verified'} title={pair.get('value_plain')}>
{pair.get('verified_at') && <span title={intl.formatMessage(messages.linkVerifiedOn, { date: intl.formatDate(pair.get('verified_at'), dateFormatOptions) })}><i className='fa fa-check verified__mark' /></span>} <span dangerouslySetInnerHTML={{ __html: pair.get('value_emojified') }} />
</dd>
</dl> </dl>
))} ))}
</div> </div>

@ -43,8 +43,8 @@ class LoadMoreMedia extends ImmutablePureComponent {
} }
@connect(mapStateToProps) export default @connect(mapStateToProps)
export default class AccountGallery extends ImmutablePureComponent { class AccountGallery extends ImmutablePureComponent {
static propTypes = { static propTypes = {
params: PropTypes.object.isRequired, params: PropTypes.object.isRequired,

@ -23,8 +23,8 @@ const mapStateToProps = (state, { params: { accountId }, withReplies = false })
}; };
}; };
@connect(mapStateToProps) export default @connect(mapStateToProps)
export default class AccountTimeline extends ImmutablePureComponent { class AccountTimeline extends ImmutablePureComponent {
static propTypes = { static propTypes = {
params: PropTypes.object.isRequired, params: PropTypes.object.isRequired,

@ -20,9 +20,9 @@ const mapStateToProps = state => ({
accountIds: state.getIn(['user_lists', 'blocks', 'items']), accountIds: state.getIn(['user_lists', 'blocks', 'items']),
}); });
@connect(mapStateToProps) export default @connect(mapStateToProps)
@injectIntl @injectIntl
export default class Blocks extends ImmutablePureComponent { class Blocks extends ImmutablePureComponent {
static propTypes = { static propTypes = {
params: PropTypes.object.isRequired, params: PropTypes.object.isRequired,

@ -4,8 +4,8 @@ import ImmutablePropTypes from 'react-immutable-proptypes';
import { injectIntl, FormattedMessage } from 'react-intl'; import { injectIntl, FormattedMessage } from 'react-intl';
import SettingToggle from '../../notifications/components/setting_toggle'; import SettingToggle from '../../notifications/components/setting_toggle';
@injectIntl export default @injectIntl
export default class ColumnSettings extends React.PureComponent { class ColumnSettings extends React.PureComponent {
static propTypes = { static propTypes = {
settings: ImmutablePropTypes.map.isRequired, settings: ImmutablePropTypes.map.isRequired,

@ -25,9 +25,9 @@ const mapStateToProps = (state, { onlyMedia, columnId }) => {
}; };
}; };
@connect(mapStateToProps) export default @connect(mapStateToProps)
@injectIntl @injectIntl
export default class CommunityTimeline extends React.PureComponent { class CommunityTimeline extends React.PureComponent {
static contextTypes = { static contextTypes = {
router: PropTypes.object, router: PropTypes.object,

@ -17,8 +17,8 @@ const messages = defineMessages({
filters: { id: 'navigation_bar.filters', defaultMessage: 'Muted words' }, filters: { id: 'navigation_bar.filters', defaultMessage: 'Muted words' },
}); });
@injectIntl export default @injectIntl
export default class ActionBar extends React.PureComponent { class ActionBar extends React.PureComponent {
static propTypes = { static propTypes = {
account: ImmutablePropTypes.map.isRequired, account: ImmutablePropTypes.map.isRequired,

@ -28,8 +28,8 @@ const messages = defineMessages({
publishLoud: { id: 'compose_form.publish_loud', defaultMessage: '{publish}!' }, publishLoud: { id: 'compose_form.publish_loud', defaultMessage: '{publish}!' },
}); });
@injectIntl export default @injectIntl
export default class ComposeForm extends ImmutablePureComponent { class ComposeForm extends ImmutablePureComponent {
static propTypes = { static propTypes = {
intl: PropTypes.object.isRequired, intl: PropTypes.object.isRequired,

@ -261,6 +261,7 @@ class EmojiPickerMenu extends React.PureComponent {
skin={skinTone} skin={skinTone}
showPreview={false} showPreview={false}
backgroundImageFn={backgroundImageFn} backgroundImageFn={backgroundImageFn}
autoFocus
emojiTooltip emojiTooltip
/> />
@ -277,8 +278,8 @@ class EmojiPickerMenu extends React.PureComponent {
} }
@injectIntl export default @injectIntl
export default class EmojiPickerDropdown extends React.PureComponent { class EmojiPickerDropdown extends React.PureComponent {
static propTypes = { static propTypes = {
custom_emojis: ImmutablePropTypes.list, custom_emojis: ImmutablePropTypes.list,

@ -149,8 +149,8 @@ class PrivacyDropdownMenu extends React.PureComponent {
} }
@injectIntl export default @injectIntl
export default class PrivacyDropdown extends React.PureComponent { class PrivacyDropdown extends React.PureComponent {
static propTypes = { static propTypes = {
isUserTouching: PropTypes.func, isUserTouching: PropTypes.func,

@ -12,8 +12,8 @@ const messages = defineMessages({
cancel: { id: 'reply_indicator.cancel', defaultMessage: 'Cancel' }, cancel: { id: 'reply_indicator.cancel', defaultMessage: 'Cancel' },
}); });
@injectIntl export default @injectIntl
export default class ReplyIndicator extends ImmutablePureComponent { class ReplyIndicator extends ImmutablePureComponent {
static contextTypes = { static contextTypes = {
router: PropTypes.object, router: PropTypes.object,

@ -43,8 +43,8 @@ class SearchPopout extends React.PureComponent {
} }
@injectIntl export default @injectIntl
export default class Search extends React.PureComponent { class Search extends React.PureComponent {
static propTypes = { static propTypes = {
value: PropTypes.string.isRequired, value: PropTypes.string.isRequired,

@ -11,8 +11,8 @@ const messages = defineMessages({
description: { id: 'upload_form.description', defaultMessage: 'Describe for the visually impaired' }, description: { id: 'upload_form.description', defaultMessage: 'Describe for the visually impaired' },
}); });
@injectIntl export default @injectIntl
export default class Upload extends ImmutablePureComponent { class Upload extends ImmutablePureComponent {
static propTypes = { static propTypes = {
media: ImmutablePropTypes.map.isRequired, media: ImmutablePropTypes.map.isRequired,

@ -23,9 +23,9 @@ const iconStyle = {
lineHeight: '27px', lineHeight: '27px',
}; };
@connect(makeMapStateToProps) export default @connect(makeMapStateToProps)
@injectIntl @injectIntl
export default class UploadButton extends ImmutablePureComponent { class UploadButton extends ImmutablePureComponent {
static propTypes = { static propTypes = {
disabled: PropTypes.bool, disabled: PropTypes.bool,

@ -30,9 +30,9 @@ const mapStateToProps = (state, ownProps) => ({
showSearch: ownProps.multiColumn ? state.getIn(['search', 'submitted']) && !state.getIn(['search', 'hidden']) : ownProps.isSearchPage, showSearch: ownProps.multiColumn ? state.getIn(['search', 'submitted']) && !state.getIn(['search', 'hidden']) : ownProps.isSearchPage,
}); });
@connect(mapStateToProps) export default @connect(mapStateToProps)
@injectIntl @injectIntl
export default class Compose extends React.PureComponent { class Compose extends React.PureComponent {
static propTypes = { static propTypes = {
dispatch: PropTypes.func.isRequired, dispatch: PropTypes.func.isRequired,

@ -170,7 +170,7 @@ export const urlRegex = (function() {
')' + ')' +
'\\)', '\\)',
'i'); 'i');
// Valid end-of-path chracters (so /foo. does not gobble the period). // Valid end-of-path characters (so /foo. does not gobble the period).
// 1. Allow =&# for empty URL parameters and other URL-join artifacts // 1. Allow =&# for empty URL parameters and other URL-join artifacts
regexen.validUrlPathEndingChars = regexSupplant(/[^#{spaces_group}\(\)\?!\*';:=\,\.\$%\[\]#{pd}~&\|@]|(?:#{validUrlBalancedParens})/i); regexen.validUrlPathEndingChars = regexSupplant(/[^#{spaces_group}\(\)\?!\*';:=\,\.\$%\[\]#{pd}~&\|@]|(?:#{validUrlBalancedParens})/i);
// Allow @ in a url, but only in the middle. Catch things like http://example.com/@user/ // Allow @ in a url, but only in the middle. Catch things like http://example.com/@user/

@ -9,8 +9,8 @@ const messages = defineMessages({
settings: { id: 'home.settings', defaultMessage: 'Column settings' }, settings: { id: 'home.settings', defaultMessage: 'Column settings' },
}); });
@injectIntl export default @injectIntl
export default class ColumnSettings extends React.PureComponent { class ColumnSettings extends React.PureComponent {
static propTypes = { static propTypes = {
settings: ImmutablePropTypes.map.isRequired, settings: ImmutablePropTypes.map.isRequired,

@ -17,9 +17,9 @@ const mapStateToProps = state => ({
hasUnread: state.getIn(['timelines', 'direct', 'unread']) > 0, hasUnread: state.getIn(['timelines', 'direct', 'unread']) > 0,
}); });
@connect(mapStateToProps) export default @connect(mapStateToProps)
@injectIntl @injectIntl
export default class DirectTimeline extends React.PureComponent { class DirectTimeline extends React.PureComponent {
static propTypes = { static propTypes = {
dispatch: PropTypes.func.isRequired, dispatch: PropTypes.func.isRequired,

@ -21,9 +21,9 @@ const mapStateToProps = state => ({
domains: state.getIn(['domain_lists', 'blocks', 'items']), domains: state.getIn(['domain_lists', 'blocks', 'items']),
}); });
@connect(mapStateToProps) export default @connect(mapStateToProps)
@injectIntl @injectIntl
export default class Blocks extends ImmutablePureComponent { class Blocks extends ImmutablePureComponent {
static propTypes = { static propTypes = {
params: PropTypes.object.isRequired, params: PropTypes.object.isRequired,

@ -21,9 +21,9 @@ const mapStateToProps = state => ({
hasMore: !!state.getIn(['status_lists', 'favourites', 'next']), hasMore: !!state.getIn(['status_lists', 'favourites', 'next']),
}); });
@connect(mapStateToProps) export default @connect(mapStateToProps)
@injectIntl @injectIntl
export default class Favourites extends ImmutablePureComponent { class Favourites extends ImmutablePureComponent {
static propTypes = { static propTypes = {
dispatch: PropTypes.func.isRequired, dispatch: PropTypes.func.isRequired,

@ -15,8 +15,8 @@ const mapStateToProps = (state, props) => ({
accountIds: state.getIn(['user_lists', 'favourited_by', props.params.statusId]), accountIds: state.getIn(['user_lists', 'favourited_by', props.params.statusId]),
}); });
@connect(mapStateToProps) export default @connect(mapStateToProps)
export default class Favourites extends ImmutablePureComponent { class Favourites extends ImmutablePureComponent {
static propTypes = { static propTypes = {
params: PropTypes.object.isRequired, params: PropTypes.object.isRequired,

@ -13,8 +13,8 @@ const messages = defineMessages({
reject: { id: 'follow_request.reject', defaultMessage: 'Reject' }, reject: { id: 'follow_request.reject', defaultMessage: 'Reject' },
}); });
@injectIntl export default @injectIntl
export default class AccountAuthorize extends ImmutablePureComponent { class AccountAuthorize extends ImmutablePureComponent {
static propTypes = { static propTypes = {
account: ImmutablePropTypes.map.isRequired, account: ImmutablePropTypes.map.isRequired,

@ -20,9 +20,9 @@ const mapStateToProps = state => ({
accountIds: state.getIn(['user_lists', 'follow_requests', 'items']), accountIds: state.getIn(['user_lists', 'follow_requests', 'items']),
}); });
@connect(mapStateToProps) export default @connect(mapStateToProps)
@injectIntl @injectIntl
export default class FollowRequests extends ImmutablePureComponent { class FollowRequests extends ImmutablePureComponent {
static propTypes = { static propTypes = {
params: PropTypes.object.isRequired, params: PropTypes.object.isRequired,

@ -22,8 +22,8 @@ const mapStateToProps = (state, props) => ({
hasMore: !!state.getIn(['user_lists', 'followers', props.params.accountId, 'next']), hasMore: !!state.getIn(['user_lists', 'followers', props.params.accountId, 'next']),
}); });
@connect(mapStateToProps) export default @connect(mapStateToProps)
export default class Followers extends ImmutablePureComponent { class Followers extends ImmutablePureComponent {
static propTypes = { static propTypes = {
params: PropTypes.object.isRequired, params: PropTypes.object.isRequired,

@ -22,8 +22,8 @@ const mapStateToProps = (state, props) => ({
hasMore: !!state.getIn(['user_lists', 'following', props.params.accountId, 'next']), hasMore: !!state.getIn(['user_lists', 'following', props.params.accountId, 'next']),
}); });
@connect(mapStateToProps) export default @connect(mapStateToProps)
export default class Following extends ImmutablePureComponent { class Following extends ImmutablePureComponent {
static propTypes = { static propTypes = {
params: PropTypes.object.isRequired, params: PropTypes.object.isRequired,

@ -53,9 +53,9 @@ const badgeDisplay = (number, limit) => {
} }
}; };
@connect(mapStateToProps, mapDispatchToProps) export default @connect(mapStateToProps, mapDispatchToProps)
@injectIntl @injectIntl
export default class GettingStarted extends ImmutablePureComponent { class GettingStarted extends ImmutablePureComponent {
static propTypes = { static propTypes = {
intl: PropTypes.object.isRequired, intl: PropTypes.object.isRequired,

@ -13,8 +13,8 @@ const mapStateToProps = (state, props) => ({
hasUnread: state.getIn(['timelines', `hashtag:${props.params.id}`, 'unread']) > 0, hasUnread: state.getIn(['timelines', `hashtag:${props.params.id}`, 'unread']) > 0,
}); });
@connect(mapStateToProps) export default @connect(mapStateToProps)
export default class HashtagTimeline extends React.PureComponent { class HashtagTimeline extends React.PureComponent {
static propTypes = { static propTypes = {
params: PropTypes.object.isRequired, params: PropTypes.object.isRequired,

@ -4,8 +4,8 @@ import ImmutablePropTypes from 'react-immutable-proptypes';
import { injectIntl, FormattedMessage } from 'react-intl'; import { injectIntl, FormattedMessage } from 'react-intl';
import SettingToggle from '../../notifications/components/setting_toggle'; import SettingToggle from '../../notifications/components/setting_toggle';
@injectIntl export default @injectIntl
export default class ColumnSettings extends React.PureComponent { class ColumnSettings extends React.PureComponent {
static propTypes = { static propTypes = {
settings: ImmutablePropTypes.map.isRequired, settings: ImmutablePropTypes.map.isRequired,

@ -19,9 +19,9 @@ const mapStateToProps = state => ({
isPartial: state.getIn(['timelines', 'home', 'items', 0], null) === null, isPartial: state.getIn(['timelines', 'home', 'items', 0], null) === null,
}); });
@connect(mapStateToProps) export default @connect(mapStateToProps)
@injectIntl @injectIntl
export default class HomeTimeline extends React.PureComponent { class HomeTimeline extends React.PureComponent {
static propTypes = { static propTypes = {
dispatch: PropTypes.func.isRequired, dispatch: PropTypes.func.isRequired,

@ -9,8 +9,8 @@ const messages = defineMessages({
heading: { id: 'keyboard_shortcuts.heading', defaultMessage: 'Keyboard Shortcuts' }, heading: { id: 'keyboard_shortcuts.heading', defaultMessage: 'Keyboard Shortcuts' },
}); });
@injectIntl export default @injectIntl
export default class KeyboardShortcuts extends ImmutablePureComponent { class KeyboardShortcuts extends ImmutablePureComponent {
static propTypes = { static propTypes = {
intl: PropTypes.object.isRequired, intl: PropTypes.object.isRequired,

@ -31,9 +31,9 @@ const mapDispatchToProps = (dispatch, { accountId }) => ({
onAdd: () => dispatch(addToListEditor(accountId)), onAdd: () => dispatch(addToListEditor(accountId)),
}); });
@connect(makeMapStateToProps, mapDispatchToProps) export default @connect(makeMapStateToProps, mapDispatchToProps)
@injectIntl @injectIntl
export default class Account extends ImmutablePureComponent { class Account extends ImmutablePureComponent {
static propTypes = { static propTypes = {
account: ImmutablePropTypes.map.isRequired, account: ImmutablePropTypes.map.isRequired,

@ -19,9 +19,9 @@ const mapDispatchToProps = dispatch => ({
onChange: value => dispatch(changeListSuggestions(value)), onChange: value => dispatch(changeListSuggestions(value)),
}); });
@connect(mapStateToProps, mapDispatchToProps) export default @connect(mapStateToProps, mapDispatchToProps)
@injectIntl @injectIntl
export default class Search extends React.PureComponent { class Search extends React.PureComponent {
static propTypes = { static propTypes = {
intl: PropTypes.object.isRequired, intl: PropTypes.object.isRequired,

@ -22,9 +22,9 @@ const mapDispatchToProps = dispatch => ({
onReset: () => dispatch(resetListEditor()), onReset: () => dispatch(resetListEditor()),
}); });
@connect(mapStateToProps, mapDispatchToProps) export default @connect(mapStateToProps, mapDispatchToProps)
@injectIntl @injectIntl
export default class ListEditor extends ImmutablePureComponent { class ListEditor extends ImmutablePureComponent {
static propTypes = { static propTypes = {
listId: PropTypes.string.isRequired, listId: PropTypes.string.isRequired,

@ -25,9 +25,9 @@ const mapStateToProps = (state, props) => ({
hasUnread: state.getIn(['timelines', `list:${props.params.id}`, 'unread']) > 0, hasUnread: state.getIn(['timelines', `list:${props.params.id}`, 'unread']) > 0,
}); });
@connect(mapStateToProps) export default @connect(mapStateToProps)
@injectIntl @injectIntl
export default class ListTimeline extends React.PureComponent { class ListTimeline extends React.PureComponent {
static contextTypes = { static contextTypes = {
router: PropTypes.object, router: PropTypes.object,

@ -20,9 +20,9 @@ const mapDispatchToProps = dispatch => ({
onSubmit: () => dispatch(submitListEditor(true)), onSubmit: () => dispatch(submitListEditor(true)),
}); });
@connect(mapStateToProps, mapDispatchToProps) export default @connect(mapStateToProps, mapDispatchToProps)
@injectIntl @injectIntl
export default class NewListForm extends React.PureComponent { class NewListForm extends React.PureComponent {
static propTypes = { static propTypes = {
value: PropTypes.string.isRequired, value: PropTypes.string.isRequired,

@ -31,9 +31,9 @@ const mapStateToProps = state => ({
lists: getOrderedLists(state), lists: getOrderedLists(state),
}); });
@connect(mapStateToProps) export default @connect(mapStateToProps)
@injectIntl @injectIntl
export default class Lists extends ImmutablePureComponent { class Lists extends ImmutablePureComponent {
static propTypes = { static propTypes = {
params: PropTypes.object.isRequired, params: PropTypes.object.isRequired,

@ -20,9 +20,9 @@ const mapStateToProps = state => ({
accountIds: state.getIn(['user_lists', 'mutes', 'items']), accountIds: state.getIn(['user_lists', 'mutes', 'items']),
}); });
@connect(mapStateToProps) export default @connect(mapStateToProps)
@injectIntl @injectIntl
export default class Mutes extends ImmutablePureComponent { class Mutes extends ImmutablePureComponent {
static propTypes = { static propTypes = {
params: PropTypes.object.isRequired, params: PropTypes.object.isRequired,

@ -16,8 +16,8 @@ const notificationForScreenReader = (intl, message, timestamp) => {
return output.join(', '); return output.join(', ');
}; };
@injectIntl export default @injectIntl
export default class Notification extends ImmutablePureComponent { class Notification extends ImmutablePureComponent {
static contextTypes = { static contextTypes = {
router: PropTypes.object, router: PropTypes.object,

@ -31,9 +31,9 @@ const mapStateToProps = state => ({
hasMore: state.getIn(['notifications', 'hasMore']), hasMore: state.getIn(['notifications', 'hasMore']),
}); });
@connect(mapStateToProps) export default @connect(mapStateToProps)
@injectIntl @injectIntl
export default class Notifications extends React.PureComponent { class Notifications extends React.PureComponent {
static propTypes = { static propTypes = {
columnId: PropTypes.string, columnId: PropTypes.string,

@ -18,9 +18,9 @@ const mapStateToProps = state => ({
hasMore: !!state.getIn(['status_lists', 'pins', 'next']), hasMore: !!state.getIn(['status_lists', 'pins', 'next']),
}); });
@connect(mapStateToProps) export default @connect(mapStateToProps)
@injectIntl @injectIntl
export default class PinnedStatuses extends ImmutablePureComponent { class PinnedStatuses extends ImmutablePureComponent {
static propTypes = { static propTypes = {
dispatch: PropTypes.func.isRequired, dispatch: PropTypes.func.isRequired,

@ -25,9 +25,9 @@ const mapStateToProps = (state, { onlyMedia, columnId }) => {
}; };
}; };
@connect(mapStateToProps) export default @connect(mapStateToProps)
@injectIntl @injectIntl
export default class PublicTimeline extends React.PureComponent { class PublicTimeline extends React.PureComponent {
static contextTypes = { static contextTypes = {
router: PropTypes.object, router: PropTypes.object,

@ -15,8 +15,8 @@ const mapStateToProps = (state, props) => ({
accountIds: state.getIn(['user_lists', 'reblogged_by', props.params.statusId]), accountIds: state.getIn(['user_lists', 'reblogged_by', props.params.statusId]),
}); });
@connect(mapStateToProps) export default @connect(mapStateToProps)
export default class Reblogs extends ImmutablePureComponent { class Reblogs extends ImmutablePureComponent {
static propTypes = { static propTypes = {
params: PropTypes.object.isRequired, params: PropTypes.object.isRequired,

@ -12,9 +12,9 @@ const messages = defineMessages({
title: { id: 'standalone.public_title', defaultMessage: 'A look inside...' }, title: { id: 'standalone.public_title', defaultMessage: 'A look inside...' },
}); });
@connect() export default @connect()
@injectIntl @injectIntl
export default class CommunityTimeline extends React.PureComponent { class CommunityTimeline extends React.PureComponent {
static propTypes = { static propTypes = {
dispatch: PropTypes.func.isRequired, dispatch: PropTypes.func.isRequired,

@ -7,8 +7,8 @@ import Column from '../../../components/column';
import ColumnHeader from '../../../components/column_header'; import ColumnHeader from '../../../components/column_header';
import { connectHashtagStream } from '../../../actions/streaming'; import { connectHashtagStream } from '../../../actions/streaming';
@connect() export default @connect()
export default class HashtagTimeline extends React.PureComponent { class HashtagTimeline extends React.PureComponent {
static propTypes = { static propTypes = {
dispatch: PropTypes.func.isRequired, dispatch: PropTypes.func.isRequired,

@ -12,9 +12,9 @@ const messages = defineMessages({
title: { id: 'standalone.public_title', defaultMessage: 'A look inside...' }, title: { id: 'standalone.public_title', defaultMessage: 'A look inside...' },
}); });
@connect() export default @connect()
@injectIntl @injectIntl
export default class PublicTimeline extends React.PureComponent { class PublicTimeline extends React.PureComponent {
static propTypes = { static propTypes = {
dispatch: PropTypes.func.isRequired, dispatch: PropTypes.func.isRequired,

@ -28,8 +28,8 @@ const messages = defineMessages({
embed: { id: 'status.embed', defaultMessage: 'Embed' }, embed: { id: 'status.embed', defaultMessage: 'Embed' },
}); });
@injectIntl export default @injectIntl
export default class ActionBar extends React.PureComponent { class ActionBar extends React.PureComponent {
static contextTypes = { static contextTypes = {
router: PropTypes.object, router: PropTypes.object,

@ -104,9 +104,9 @@ const makeMapStateToProps = () => {
return mapStateToProps; return mapStateToProps;
}; };
@injectIntl export default @injectIntl
@connect(makeMapStateToProps) @connect(makeMapStateToProps)
export default class Status extends ImmutablePureComponent { class Status extends ImmutablePureComponent {
static contextTypes = { static contextTypes = {
router: PropTypes.object, router: PropTypes.object,

@ -13,8 +13,8 @@ const messages = defineMessages({
reblog: { id: 'status.reblog', defaultMessage: 'Boost' }, reblog: { id: 'status.reblog', defaultMessage: 'Boost' },
}); });
@injectIntl export default @injectIntl
export default class BoostModal extends ImmutablePureComponent { class BoostModal extends ImmutablePureComponent {
static contextTypes = { static contextTypes = {
router: PropTypes.object, router: PropTypes.object,

@ -35,8 +35,8 @@ const messages = defineMessages({
const shouldHideFAB = path => path.match(/^\/statuses\//); const shouldHideFAB = path => path.match(/^\/statuses\//);
@component => injectIntl(component, { withRef: true }) export default @(component => injectIntl(component, { withRef: true }))
export default class ColumnsArea extends ImmutablePureComponent { class ColumnsArea extends ImmutablePureComponent {
static contextTypes = { static contextTypes = {
router: PropTypes.object.isRequired, router: PropTypes.object.isRequired,

@ -3,8 +3,8 @@ import PropTypes from 'prop-types';
import { injectIntl, FormattedMessage } from 'react-intl'; import { injectIntl, FormattedMessage } from 'react-intl';
import Button from '../../../components/button'; import Button from '../../../components/button';
@injectIntl export default @injectIntl
export default class ConfirmationModal extends React.PureComponent { class ConfirmationModal extends React.PureComponent {
static propTypes = { static propTypes = {
message: PropTypes.node.isRequired, message: PropTypes.node.isRequired,

@ -4,8 +4,8 @@ import ImmutablePureComponent from 'react-immutable-pure-component';
import { FormattedMessage, injectIntl } from 'react-intl'; import { FormattedMessage, injectIntl } from 'react-intl';
import api from '../../../api'; import api from '../../../api';
@injectIntl export default @injectIntl
export default class EmbedModal extends ImmutablePureComponent { class EmbedModal extends ImmutablePureComponent {
static propTypes = { static propTypes = {
url: PropTypes.string.isRequired, url: PropTypes.string.isRequired,

@ -19,8 +19,8 @@ const mapDispatchToProps = (dispatch, { id }) => ({
}); });
@connect(mapStateToProps, mapDispatchToProps) export default @connect(mapStateToProps, mapDispatchToProps)
export default class FocalPointModal extends ImmutablePureComponent { class FocalPointModal extends ImmutablePureComponent {
static propTypes = { static propTypes = {
media: ImmutablePropTypes.map.isRequired, media: ImmutablePropTypes.map.isRequired,

@ -18,8 +18,8 @@ const messages = defineMessages({
export const previewState = 'previewMediaModal'; export const previewState = 'previewMediaModal';
@injectIntl export default @injectIntl
export default class MediaModal extends ImmutablePureComponent { class MediaModal extends ImmutablePureComponent {
static propTypes = { static propTypes = {
media: ImmutablePropTypes.list.isRequired, media: ImmutablePropTypes.list.isRequired,
@ -149,7 +149,7 @@ export default class MediaModal extends ImmutablePureComponent {
startTime={time || 0} startTime={time || 0}
onCloseVideo={onClose} onCloseVideo={onClose}
detailed detailed
description={image.get('description')} alt={image.get('description')}
key={image.get('url')} key={image.get('url')}
/> />
); );

@ -33,9 +33,9 @@ const mapDispatchToProps = dispatch => {
}; };
}; };
@connect(mapStateToProps, mapDispatchToProps) export default @connect(mapStateToProps, mapDispatchToProps)
@injectIntl @injectIntl
export default class MuteModal extends React.PureComponent { class MuteModal extends React.PureComponent {
static propTypes = { static propTypes = {
isSubmitting: PropTypes.bool.isRequired, isSubmitting: PropTypes.bool.isRequired,

@ -177,9 +177,9 @@ const mapStateToProps = state => ({
domain: state.getIn(['meta', 'domain']), domain: state.getIn(['meta', 'domain']),
}); });
@connect(mapStateToProps) export default @connect(mapStateToProps)
@injectIntl @injectIntl
export default class OnboardingModal extends React.PureComponent { class OnboardingModal extends React.PureComponent {
static propTypes = { static propTypes = {
onClose: PropTypes.func.isRequired, onClose: PropTypes.func.isRequired,

@ -37,9 +37,9 @@ const makeMapStateToProps = () => {
return mapStateToProps; return mapStateToProps;
}; };
@connect(makeMapStateToProps) export default @connect(makeMapStateToProps)
@injectIntl @injectIntl
export default class ReportModal extends ImmutablePureComponent { class ReportModal extends ImmutablePureComponent {
static propTypes = { static propTypes = {
isSubmitting: PropTypes.bool, isSubmitting: PropTypes.bool,
@ -106,6 +106,7 @@ export default class ReportModal extends ImmutablePureComponent {
onChange={this.handleCommentChange} onChange={this.handleCommentChange}
onKeyDown={this.handleKeyDown} onKeyDown={this.handleKeyDown}
disabled={isSubmitting} disabled={isSubmitting}
autoFocus
/> />
{domain && ( {domain && (

@ -24,9 +24,9 @@ export function getLink (index) {
return links[index].props.to; return links[index].props.to;
} }
@injectIntl export default @injectIntl
@withRouter @withRouter
export default class TabsBar extends React.PureComponent { class TabsBar extends React.PureComponent {
static propTypes = { static propTypes = {
intl: PropTypes.object.isRequired, intl: PropTypes.object.isRequired,

@ -24,7 +24,7 @@ export default class VideoModal extends ImmutablePureComponent {
startTime={time} startTime={time}
onCloseVideo={onClose} onCloseVideo={onClose}
detailed detailed
description={media.get('description')} alt={media.get('description')}
/> />
</div> </div>
</div> </div>

@ -137,6 +137,7 @@ export default class ZoomableImage extends React.PureComponent {
role='presentation' role='presentation'
ref={this.setImageRef} ref={this.setImageRef}
alt={alt} alt={alt}
title={alt}
src={src} src={src}
style={{ style={{
transform: `scale(${scale})`, transform: `scale(${scale})`,

@ -187,10 +187,10 @@ class SwitchingColumnsArea extends React.PureComponent {
} }
@connect(mapStateToProps) export default @connect(mapStateToProps)
@injectIntl @injectIntl
@withRouter @withRouter
export default class UI extends React.PureComponent { class UI extends React.PureComponent {
static contextTypes = { static contextTypes = {
router: PropTypes.object.isRequired, router: PropTypes.object.isRequired,

@ -26,7 +26,7 @@ WrappedSwitch.propTypes = {
children: PropTypes.node, children: PropTypes.node,
}; };
// Small Wraper to extract the params from the route and pass // Small Wrapper to extract the params from the route and pass
// them to the rendered component, together with the content to // them to the rendered component, together with the content to
// be rendered inside (the children) // be rendered inside (the children)
export class WrappedRoute extends React.Component { export class WrappedRoute extends React.Component {

@ -84,8 +84,8 @@ export const getPointerPosition = (el, event) => {
return position; return position;
}; };
@injectIntl export default @injectIntl
export default class Video extends React.PureComponent { class Video extends React.PureComponent {
static propTypes = { static propTypes = {
preview: PropTypes.string, preview: PropTypes.string,
@ -252,11 +252,12 @@ export default class Video extends React.PureComponent {
} }
handleOpenVideo = () => { handleOpenVideo = () => {
const { src, preview, width, height } = this.props; const { src, preview, width, height, alt } = this.props;
const media = fromJS({ const media = fromJS({
type: 'video', type: 'video',
url: src, url: src,
preview_url: preview, preview_url: preview,
description: alt,
width, width,
height, height,
}); });

@ -15,6 +15,7 @@
"account.follows.empty": "هذا المستخدِم لا يتبع أحدًا بعد.", "account.follows.empty": "هذا المستخدِم لا يتبع أحدًا بعد.",
"account.follows_you": "يتابعك", "account.follows_you": "يتابعك",
"account.hide_reblogs": "إخفاء ترقيات @{name}", "account.hide_reblogs": "إخفاء ترقيات @{name}",
"account.link_verified_on": "Ownership of this link was checked on {date}",
"account.media": "وسائط", "account.media": "وسائط",
"account.mention": "أُذكُر @{name}", "account.mention": "أُذكُر @{name}",
"account.moved_to": "{name} إنتقل إلى :", "account.moved_to": "{name} إنتقل إلى :",

@ -1,174 +1,175 @@
{ {
"account.badges.bot": "Bot", "account.badges.bot": "Robó",
"account.block": "Block @{name}", "account.block": "Bloquiar a @{name}",
"account.block_domain": "Hide everything from {domain}", "account.block_domain": "Hide everything from {domain}",
"account.blocked": "Blocked", "account.blocked": "Blocked",
"account.direct": "Direct message @{name}", "account.direct": "Unviar un mensaxe direutu a @{name}",
"account.disclaimer_full": "Information below may reflect the user's profile incompletely.", "account.disclaimer_full": "Information below may reflect the user's profile incompletely.",
"account.domain_blocked": "Domain hidden", "account.domain_blocked": "Domain hidden",
"account.edit_profile": "Edit profile", "account.edit_profile": "Editar perfil",
"account.endorse": "Feature on profile", "account.endorse": "Feature on profile",
"account.follow": "Follow", "account.follow": "Follow",
"account.followers": "Followers", "account.followers": "Siguidores",
"account.followers.empty": "No one follows this user yet.", "account.followers.empty": "No one follows this user yet.",
"account.follows": "Follows", "account.follows": "Follows",
"account.follows.empty": "This user doesn't follow anyone yet.", "account.follows.empty": "Esti usuariu entá nun sigue a naide.",
"account.follows_you": "Follows you", "account.follows_you": "Follows you",
"account.hide_reblogs": "Hide boosts from @{name}", "account.hide_reblogs": "Hide boosts from @{name}",
"account.link_verified_on": "Ownership of this link was checked on {date}",
"account.media": "Media", "account.media": "Media",
"account.mention": "Mention @{name}", "account.mention": "Mentar a @{name}",
"account.moved_to": "{name} has moved to:", "account.moved_to": "{name} has moved to:",
"account.mute": "Mute @{name}", "account.mute": "Silenciar a @{name}",
"account.mute_notifications": "Mute notifications from @{name}", "account.mute_notifications": "Mute notifications from @{name}",
"account.muted": "Muted", "account.muted": "Muted",
"account.posts": "Toots", "account.posts": "Toots",
"account.posts_with_replies": "Toots and replies", "account.posts_with_replies": "Toots y rempuestes",
"account.report": "Report @{name}", "account.report": "Report @{name}",
"account.requested": "Awaiting approval. Click to cancel follow request", "account.requested": "Awaiting approval. Click to cancel follow request",
"account.share": "Share @{name}'s profile", "account.share": "Share @{name}'s profile",
"account.show_reblogs": "Show boosts from @{name}", "account.show_reblogs": "Show boosts from @{name}",
"account.unblock": "Unblock @{name}", "account.unblock": "Desbloquiar a @{name}",
"account.unblock_domain": "Unhide {domain}", "account.unblock_domain": "Unhide {domain}",
"account.unendorse": "Don't feature on profile", "account.unendorse": "Don't feature on profile",
"account.unfollow": "Unfollow", "account.unfollow": "Unfollow",
"account.unmute": "Unmute @{name}", "account.unmute": "Unmute @{name}",
"account.unmute_notifications": "Unmute notifications from @{name}", "account.unmute_notifications": "Unmute notifications from @{name}",
"account.view_full_profile": "View full profile", "account.view_full_profile": "View full profile",
"alert.unexpected.message": "An unexpected error occurred.", "alert.unexpected.message": "Asocedió un fallu inesperáu.",
"alert.unexpected.title": "Oops!", "alert.unexpected.title": "¡Ups!",
"boost_modal.combo": "You can press {combo} to skip this next time", "boost_modal.combo": "Pues primir {combo} pa saltar esto la próxima vegada",
"bundle_column_error.body": "Something went wrong while loading this component.", "bundle_column_error.body": "Something went wrong while loading this component.",
"bundle_column_error.retry": "Try again", "bundle_column_error.retry": "Try again",
"bundle_column_error.title": "Network error", "bundle_column_error.title": "Network error",
"bundle_modal_error.close": "Close", "bundle_modal_error.close": "Close",
"bundle_modal_error.message": "Something went wrong while loading this component.", "bundle_modal_error.message": "Something went wrong while loading this component.",
"bundle_modal_error.retry": "Try again", "bundle_modal_error.retry": "Try again",
"column.blocks": "Blocked users", "column.blocks": "Usuarios bloquiaos",
"column.community": "Local timeline", "column.community": "Local timeline",
"column.direct": "Direct messages", "column.direct": "Mensaxes direutos",
"column.domain_blocks": "Hidden domains", "column.domain_blocks": "Dominios anubríos",
"column.favourites": "Favourites", "column.favourites": "Favoritos",
"column.follow_requests": "Follow requests", "column.follow_requests": "Solicitúes de siguimientu",
"column.home": "Home", "column.home": "Aniciu",
"column.lists": "Lists", "column.lists": "Llistes",
"column.mutes": "Muted users", "column.mutes": "Usuarios silenciaos",
"column.notifications": "Notifications", "column.notifications": "Avisos",
"column.pins": "Pinned toot", "column.pins": "Toots fixaos",
"column.public": "Federated timeline", "column.public": "Llinia temporal federada",
"column_back_button.label": "Back", "column_back_button.label": "Atrás",
"column_header.hide_settings": "Hide settings", "column_header.hide_settings": "Hide settings",
"column_header.moveLeft_settings": "Move column to the left", "column_header.moveLeft_settings": "Mover la columna a la esquierda",
"column_header.moveRight_settings": "Move column to the right", "column_header.moveRight_settings": "Mover la columna a la drecha",
"column_header.pin": "Pin", "column_header.pin": "Pin",
"column_header.show_settings": "Show settings", "column_header.show_settings": "Show settings",
"column_header.unpin": "Unpin", "column_header.unpin": "Desfixar",
"column_subheading.settings": "Settings", "column_subheading.settings": "Axustes",
"community.column_settings.media_only": "Media Only", "community.column_settings.media_only": "Media Only",
"compose_form.direct_message_warning": "This toot will only be sent to all the mentioned users.", "compose_form.direct_message_warning": "Esti toot namái va unviase a los usuarios mentaos.",
"compose_form.direct_message_warning_learn_more": "Learn more", "compose_form.direct_message_warning_learn_more": "Learn more",
"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.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": "Your account is not {locked}. Anyone can follow you to view your follower-only posts.",
"compose_form.lock_disclaimer.lock": "locked", "compose_form.lock_disclaimer.lock": "locked",
"compose_form.placeholder": "What is on your mind?", "compose_form.placeholder": "¿En qué pienses?",
"compose_form.publish": "Toot", "compose_form.publish": "Toot",
"compose_form.publish_loud": "{publish}!", "compose_form.publish_loud": "{publish}!",
"compose_form.sensitive.marked": "Media is marked as sensitive", "compose_form.sensitive.marked": "Media is marked as sensitive",
"compose_form.sensitive.unmarked": "Media is not marked as sensitive", "compose_form.sensitive.unmarked": "Media is not marked as sensitive",
"compose_form.spoiler.marked": "Text is hidden behind warning", "compose_form.spoiler.marked": "El testu nun va anubrise darrera d'una alvertencia",
"compose_form.spoiler.unmarked": "Text is not hidden", "compose_form.spoiler.unmarked": "El testu va anubrise",
"compose_form.spoiler_placeholder": "Write your warning here", "compose_form.spoiler_placeholder": "Escribi equí l'avertencia",
"confirmation_modal.cancel": "Cancel", "confirmation_modal.cancel": "Encaboxar",
"confirmations.block.confirm": "Block", "confirmations.block.confirm": "Block",
"confirmations.block.message": "Are you sure you want to block {name}?", "confirmations.block.message": "¿De xuru que quies bloquiar a {name}?",
"confirmations.delete.confirm": "Delete", "confirmations.delete.confirm": "Delete",
"confirmations.delete.message": "Are you sure you want to delete this status?", "confirmations.delete.message": "¿De xuru que quies desaniciar esti estáu?",
"confirmations.delete_list.confirm": "Delete", "confirmations.delete_list.confirm": "Delete",
"confirmations.delete_list.message": "Are you sure you want to permanently delete this list?", "confirmations.delete_list.message": "¿De xuru que quies desaniciar dafechu esta llista?",
"confirmations.domain_block.confirm": "Hide entire domain", "confirmations.domain_block.confirm": "Hide entire domain",
"confirmations.domain_block.message": "Are you really, really sure you want to block the entire {domain}? In most cases a few targeted blocks or mutes are sufficient and preferable. You will not see content from that domain in any public timelines or your notifications. Your followers from that domain will be removed.", "confirmations.domain_block.message": "Are you really, really sure you want to block the entire {domain}? In most cases a few targeted blocks or mutes are sufficient and preferable. You will not see content from that domain in any public timelines or your notifications. Your followers from that domain will be removed.",
"confirmations.mute.confirm": "Mute", "confirmations.mute.confirm": "Mute",
"confirmations.mute.message": "Are you sure you want to mute {name}?", "confirmations.mute.message": "¿De xuru que quies silenciar a {name}?",
"confirmations.redraft.confirm": "Delete & redraft", "confirmations.redraft.confirm": "Delete & redraft",
"confirmations.redraft.message": "Are you sure you want to delete this status and re-draft it? You will lose all replies, boosts and favourites to it.", "confirmations.redraft.message": "Are you sure you want to delete this status and re-draft it? You will lose all replies, boosts and favourites to it.",
"confirmations.unfollow.confirm": "Unfollow", "confirmations.unfollow.confirm": "Unfollow",
"confirmations.unfollow.message": "Are you sure you want to unfollow {name}?", "confirmations.unfollow.message": "Are you sure you want to unfollow {name}?",
"embed.instructions": "Embed this status on your website by copying the code below.", "embed.instructions": "Embed this status on your website by copying the code below.",
"embed.preview": "Here is what it will look like:", "embed.preview": "Here is what it will look like:",
"emoji_button.activity": "Activity", "emoji_button.activity": "Activi",
"emoji_button.custom": "Custom", "emoji_button.custom": "Custom",
"emoji_button.flags": "Flags", "emoji_button.flags": "Banderes",
"emoji_button.food": "Food & Drink", "emoji_button.food": "Comída y bébora",
"emoji_button.label": "Insert emoji", "emoji_button.label": "Insert emoji",
"emoji_button.nature": "Nature", "emoji_button.nature": "Natura",
"emoji_button.not_found": "No emojos!! (╯°□°)╯︵ ┻━┻", "emoji_button.not_found": "¡Nun hai fustaxes! (╯°□°)╯︵ ┻━┻",
"emoji_button.objects": "Objects", "emoji_button.objects": "Oxetos",
"emoji_button.people": "People", "emoji_button.people": "Xente",
"emoji_button.recent": "Frequently used", "emoji_button.recent": "Frequently used",
"emoji_button.search": "Search...", "emoji_button.search": "Search...",
"emoji_button.search_results": "Search results", "emoji_button.search_results": "Search results",
"emoji_button.symbols": "Symbols", "emoji_button.symbols": "Símbolos",
"emoji_button.travel": "Travel & Places", "emoji_button.travel": "Viaxes y llugares",
"empty_column.blocks": "You haven't blocked any users yet.", "empty_column.blocks": "Entá nun bloquiesti a dengún usuariu.",
"empty_column.community": "The local timeline is empty. Write something publicly to get the ball rolling!", "empty_column.community": "The local timeline is empty. Write something publicly to get the ball rolling!",
"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": "Entá nun tienes dengún mensaxe direutu. Cuando unvies o recibas dalgún, va apaecer equí",
"empty_column.domain_blocks": "There are no hidden domains yet.", "empty_column.domain_blocks": "Entá nun hai dominios anubríos.",
"empty_column.favourited_statuses": "You don't have any favourite toots yet. When you favourite one, it will show up here.", "empty_column.favourited_statuses": "You don't have any favourite toots yet. When you favourite one, it will show up here.",
"empty_column.favourites": "No one has favourited this toot yet. When someone does, they will show up here.", "empty_column.favourites": "No one has favourited this toot yet. When someone does, they will show up here.",
"empty_column.follow_requests": "You don't have any follow requests yet. When you receive one, it will show up here.", "empty_column.follow_requests": "Entá nun tienes denguna solicitú de siguimientu. Cuando recibas una, va amosase equí.",
"empty_column.hashtag": "There is nothing in this hashtag yet.", "empty_column.hashtag": "There is nothing in this hashtag yet.",
"empty_column.home": "Your home timeline is empty! Visit {public} or use search to get started and meet other users.", "empty_column.home": "Your home timeline is empty! Visit {public} or use search to get started and meet other users.",
"empty_column.home.public_timeline": "the public timeline", "empty_column.home.public_timeline": "la llinia temporal pública",
"empty_column.list": "There is nothing in this list yet. When members of this list post new statuses, they will appear here.", "empty_column.list": "There is nothing in this list yet. When members of this list post new statuses, they will appear here.",
"empty_column.lists": "You don't have any lists yet. When you create one, it will show up here.", "empty_column.lists": "Entá nun tienes denguna llista. Cuando crees una, va amosase equí.",
"empty_column.mutes": "You haven't muted any users yet.", "empty_column.mutes": "Enta nun silenciesti a dengún usuariu.",
"empty_column.notifications": "You don't have any notifications yet. Interact with others to start the conversation.", "empty_column.notifications": "Entá nun tienes dengún avisu. Interactua con otros p'aniciar la conversación.",
"empty_column.public": "There is nothing here! Write something publicly, or manually follow users from other instances to fill it up", "empty_column.public": "There is nothing here! Write something publicly, or manually follow users from other instances to fill it up",
"follow_request.authorize": "Authorize", "follow_request.authorize": "Autorizar",
"follow_request.reject": "Reject", "follow_request.reject": "Refugar",
"getting_started.developers": "Developers", "getting_started.developers": "Desendolcadores",
"getting_started.documentation": "Documentation", "getting_started.documentation": "Documentación",
"getting_started.find_friends": "Find friends from Twitter", "getting_started.find_friends": "Alcontrar collacios de Twitter",
"getting_started.heading": "Getting started", "getting_started.heading": "Getting started",
"getting_started.invite": "Invite people", "getting_started.invite": "Convidar xente",
"getting_started.open_source_notice": "Mastodon is open source software. You can contribute or report issues on GitHub at {github}.", "getting_started.open_source_notice": "Mastodon ye software de códigu abiertu. Pues collaborar o informar de fallos en {github} (GitHub).",
"getting_started.security": "Security", "getting_started.security": "Seguranza",
"getting_started.terms": "Terms of service", "getting_started.terms": "Términos del serviciu",
"home.column_settings.basic": "Basic", "home.column_settings.basic": "Basic",
"home.column_settings.show_reblogs": "Show boosts", "home.column_settings.show_reblogs": "Show boosts",
"home.column_settings.show_replies": "Show replies", "home.column_settings.show_replies": "Show replies",
"keyboard_shortcuts.back": "to navigate back", "keyboard_shortcuts.back": "pa dir p'atrás",
"keyboard_shortcuts.blocked": "to open blocked users list", "keyboard_shortcuts.blocked": "p'abrir la llista d'usuarios bloquiaos",
"keyboard_shortcuts.boost": "to boost", "keyboard_shortcuts.boost": "to boost",
"keyboard_shortcuts.column": "to focus a status in one of the columns", "keyboard_shortcuts.column": "to focus a status in one of the columns",
"keyboard_shortcuts.compose": "to focus the compose textarea", "keyboard_shortcuts.compose": "to focus the compose textarea",
"keyboard_shortcuts.description": "Description", "keyboard_shortcuts.description": "Descripción",
"keyboard_shortcuts.direct": "to open direct messages column", "keyboard_shortcuts.direct": "p'abrir la columna de los mensaxes direutos",
"keyboard_shortcuts.down": "to move down in the list", "keyboard_shortcuts.down": "pa baxar na llista",
"keyboard_shortcuts.enter": "to open status", "keyboard_shortcuts.enter": "to open status",
"keyboard_shortcuts.favourite": "to favourite", "keyboard_shortcuts.favourite": "to favourite",
"keyboard_shortcuts.favourites": "to open favourites list", "keyboard_shortcuts.favourites": "p'abrir la llista de favoritos",
"keyboard_shortcuts.federated": "to open federated timeline", "keyboard_shortcuts.federated": "p'abrir la llinia temporal federada",
"keyboard_shortcuts.heading": "Keyboard Shortcuts", "keyboard_shortcuts.heading": "Atayos del tecláu",
"keyboard_shortcuts.home": "to open home timeline", "keyboard_shortcuts.home": "p'abrir la llinia temporal d'aniciu",
"keyboard_shortcuts.hotkey": "Hotkey", "keyboard_shortcuts.hotkey": "Atayu",
"keyboard_shortcuts.legend": "to display this legend", "keyboard_shortcuts.legend": "p'amosar esta lleenda",
"keyboard_shortcuts.local": "to open local timeline", "keyboard_shortcuts.local": "p'abrir la llinia temporal llocal",
"keyboard_shortcuts.mention": "to mention author", "keyboard_shortcuts.mention": "pa mentar al autor",
"keyboard_shortcuts.muted": "to open muted users list", "keyboard_shortcuts.muted": "p'abrir la llista d'usuarios silenciaos",
"keyboard_shortcuts.my_profile": "to open your profile", "keyboard_shortcuts.my_profile": "to open your profile",
"keyboard_shortcuts.notifications": "to open notifications column", "keyboard_shortcuts.notifications": "p'abrir la columna d'avisos",
"keyboard_shortcuts.pinned": "to open pinned toots list", "keyboard_shortcuts.pinned": "p'abrir la llista de toots fixaos",
"keyboard_shortcuts.profile": "to open author's profile", "keyboard_shortcuts.profile": "p'abrir el perfil del autor",
"keyboard_shortcuts.reply": "to reply", "keyboard_shortcuts.reply": "pa responder",
"keyboard_shortcuts.requests": "to open follow requests list", "keyboard_shortcuts.requests": "p'abrir la llista de solicitúes de siguimientu",
"keyboard_shortcuts.search": "to focus search", "keyboard_shortcuts.search": "to focus search",
"keyboard_shortcuts.start": "to open \"get started\" column", "keyboard_shortcuts.start": "p'abrir la columna «entamar»",
"keyboard_shortcuts.toggle_hidden": "to show/hide text behind CW", "keyboard_shortcuts.toggle_hidden": "to show/hide text behind CW",
"keyboard_shortcuts.toot": "to start a brand new toot", "keyboard_shortcuts.toot": "p'apenzar un toot nuevu",
"keyboard_shortcuts.unfocus": "to un-focus compose textarea/search", "keyboard_shortcuts.unfocus": "to un-focus compose textarea/search",
"keyboard_shortcuts.up": "to move up in the list", "keyboard_shortcuts.up": "pa xubir na llista",
"lightbox.close": "Close", "lightbox.close": "Close",
"lightbox.next": "Next", "lightbox.next": "Siguiente",
"lightbox.previous": "Previous", "lightbox.previous": "Previous",
"lists.account.add": "Add to list", "lists.account.add": "Add to list",
"lists.account.remove": "Remove from list", "lists.account.remove": "Remove from list",
@ -180,55 +181,55 @@
"lists.subheading": "Your lists", "lists.subheading": "Your lists",
"loading_indicator.label": "Loading...", "loading_indicator.label": "Loading...",
"media_gallery.toggle_visible": "Toggle visibility", "media_gallery.toggle_visible": "Toggle visibility",
"missing_indicator.label": "Not found", "missing_indicator.label": "Nun s'alcontró",
"missing_indicator.sublabel": "This resource could not be found", "missing_indicator.sublabel": "Esti recursu nun pudo alcontrase",
"mute_modal.hide_notifications": "Hide notifications from this user?", "mute_modal.hide_notifications": "Hide notifications from this user?",
"navigation_bar.apps": "Mobile apps", "navigation_bar.apps": "Aplicaciones móviles",
"navigation_bar.blocks": "Blocked users", "navigation_bar.blocks": "Usuarios bloquiaos",
"navigation_bar.community_timeline": "Local timeline", "navigation_bar.community_timeline": "Local timeline",
"navigation_bar.compose": "Compose new toot", "navigation_bar.compose": "Compose new toot",
"navigation_bar.direct": "Direct messages", "navigation_bar.direct": "Mensaxes direutos",
"navigation_bar.discover": "Discover", "navigation_bar.discover": "Discover",
"navigation_bar.domain_blocks": "Hidden domains", "navigation_bar.domain_blocks": "Dominios anubríos",
"navigation_bar.edit_profile": "Edit profile", "navigation_bar.edit_profile": "Editar perfil",
"navigation_bar.favourites": "Favourites", "navigation_bar.favourites": "Favoritos",
"navigation_bar.filters": "Muted words", "navigation_bar.filters": "Muted words",
"navigation_bar.follow_requests": "Follow requests", "navigation_bar.follow_requests": "Solicitúes de siguimientu",
"navigation_bar.info": "About this instance", "navigation_bar.info": "Tocante a esta instancia",
"navigation_bar.keyboard_shortcuts": "Hotkeys", "navigation_bar.keyboard_shortcuts": "Atayos",
"navigation_bar.lists": "Lists", "navigation_bar.lists": "Lists",
"navigation_bar.logout": "Logout", "navigation_bar.logout": "Zarrar sesión",
"navigation_bar.mutes": "Muted users", "navigation_bar.mutes": "Usuarios silenciaos",
"navigation_bar.personal": "Personal", "navigation_bar.personal": "Personal",
"navigation_bar.pins": "Pinned toots", "navigation_bar.pins": "Toots fixaos",
"navigation_bar.preferences": "Preferences", "navigation_bar.preferences": "Preferencies",
"navigation_bar.public_timeline": "Federated timeline", "navigation_bar.public_timeline": "Llinia temporal federada",
"navigation_bar.security": "Security", "navigation_bar.security": "Seguranza",
"notification.favourite": "{name} favourited your status", "notification.favourite": "{name} favourited your status",
"notification.follow": "{name} followed you", "notification.follow": "{name} siguióte",
"notification.mention": "{name} mentioned you", "notification.mention": "{name} mentóte",
"notification.reblog": "{name} boosted your status", "notification.reblog": "{name} boosted your status",
"notifications.clear": "Clear notifications", "notifications.clear": "Llimpiar avisos",
"notifications.clear_confirmation": "Are you sure you want to permanently clear all your notifications?", "notifications.clear_confirmation": "¿De xuru que quies llimpiar dafechu tolos avisos?",
"notifications.column_settings.alert": "Desktop notifications", "notifications.column_settings.alert": "Avisos d'escritoriu",
"notifications.column_settings.favourite": "Favourites:", "notifications.column_settings.favourite": "Favourites:",
"notifications.column_settings.follow": "New followers:", "notifications.column_settings.follow": "Siguidores nuevos:",
"notifications.column_settings.mention": "Mentions:", "notifications.column_settings.mention": "Menciones:",
"notifications.column_settings.push": "Push notifications", "notifications.column_settings.push": "Push notifications",
"notifications.column_settings.push_meta": "This device", "notifications.column_settings.push_meta": "Esti preséu",
"notifications.column_settings.reblog": "Boosts:", "notifications.column_settings.reblog": "Boosts:",
"notifications.column_settings.show": "Show in column", "notifications.column_settings.show": "Amosar en columna",
"notifications.column_settings.sound": "Play sound", "notifications.column_settings.sound": "Reproducir soníu",
"notifications.group": "{count} notifications", "notifications.group": "{count} avisos",
"onboarding.done": "Done", "onboarding.done": "Fecho",
"onboarding.next": "Next", "onboarding.next": "Siguiente",
"onboarding.page_five.public_timelines": "The local timeline shows public posts from everyone on {domain}. The federated timeline shows public posts from everyone who people on {domain} follow. These are the Public Timelines, a great way to discover new people.", "onboarding.page_five.public_timelines": "The local timeline shows public posts from everyone on {domain}. The federated timeline shows public posts from everyone who people on {domain} follow. These are the Public Timelines, a great way to discover new people.",
"onboarding.page_four.home": "The home timeline shows posts from people you follow.", "onboarding.page_four.home": "La llinia temporal d'aniciu amuesa artículos de xente a la que sigues.",
"onboarding.page_four.notifications": "The notifications column shows when someone interacts with you.", "onboarding.page_four.notifications": "The notifications column shows when someone interacts with you.",
"onboarding.page_one.federation": "Mastodon is a network of independent servers joining up to make one larger social network. We call these servers instances.", "onboarding.page_one.federation": "Mastodon ye una rede de sividores independientes xuníos pa facer una rede social grande. Nós llamamos instancies a esos sirvidores.",
"onboarding.page_one.full_handle": "Your full handle", "onboarding.page_one.full_handle": "Your full handle",
"onboarding.page_one.handle_hint": "This is what you would tell your friends to search for.", "onboarding.page_one.handle_hint": "This is what you would tell your friends to search for.",
"onboarding.page_one.welcome": "Welcome to Mastodon!", "onboarding.page_one.welcome": "¡Afáyate en Mastodon!",
"onboarding.page_six.admin": "Your instance's admin is {admin}.", "onboarding.page_six.admin": "Your instance's admin is {admin}.",
"onboarding.page_six.almost_done": "Almost done...", "onboarding.page_six.almost_done": "Almost done...",
"onboarding.page_six.appetoot": "Bon Appetoot!", "onboarding.page_six.appetoot": "Bon Appetoot!",
@ -236,7 +237,7 @@
"onboarding.page_six.github": "Mastodon is free open-source software. You can report bugs, request features, or contribute to the code on {github}.", "onboarding.page_six.github": "Mastodon is free open-source software. You can report bugs, request features, or contribute to the code on {github}.",
"onboarding.page_six.guidelines": "community guidelines", "onboarding.page_six.guidelines": "community guidelines",
"onboarding.page_six.read_guidelines": "Please read {domain}'s {guidelines}!", "onboarding.page_six.read_guidelines": "Please read {domain}'s {guidelines}!",
"onboarding.page_six.various_app": "mobile apps", "onboarding.page_six.various_app": "aplicaciones móviles",
"onboarding.page_three.profile": "Edit your profile to change your avatar, bio, and display name. There, you will also find other preferences.", "onboarding.page_three.profile": "Edit your profile to change your avatar, bio, and display name. There, you will also find other preferences.",
"onboarding.page_three.search": "Use the search bar to find people and look at hashtags, such as {illustration} and {introductions}. To look for a person who is not on this instance, use their full handle.", "onboarding.page_three.search": "Use the search bar to find people and look at hashtags, such as {illustration} and {introductions}. To look for a person who is not on this instance, use their full handle.",
"onboarding.page_two.compose": "Write posts from the compose column. You can upload images, change privacy settings, and add content warnings with the icons below.", "onboarding.page_two.compose": "Write posts from the compose column. You can upload images, change privacy settings, and add content warnings with the icons below.",
@ -245,7 +246,7 @@
"privacy.direct.long": "Post to mentioned users only", "privacy.direct.long": "Post to mentioned users only",
"privacy.direct.short": "Direct", "privacy.direct.short": "Direct",
"privacy.private.long": "Post to followers only", "privacy.private.long": "Post to followers only",
"privacy.private.short": "Followers-only", "privacy.private.short": "Namái siguidores",
"privacy.public.long": "Post to public timelines", "privacy.public.long": "Post to public timelines",
"privacy.public.short": "Public", "privacy.public.short": "Public",
"privacy.unlisted.long": "Do not show in public timelines", "privacy.unlisted.long": "Do not show in public timelines",
@ -254,44 +255,44 @@
"regeneration_indicator.sublabel": "Your home feed is being prepared!", "regeneration_indicator.sublabel": "Your home feed is being prepared!",
"relative_time.days": "{number}d", "relative_time.days": "{number}d",
"relative_time.hours": "{number}h", "relative_time.hours": "{number}h",
"relative_time.just_now": "now", "relative_time.just_now": "agora",
"relative_time.minutes": "{number}m", "relative_time.minutes": "{number}m",
"relative_time.seconds": "{number}s", "relative_time.seconds": "{number}s",
"reply_indicator.cancel": "Cancel", "reply_indicator.cancel": "Encaboxar",
"report.forward": "Forward to {target}", "report.forward": "Forward to {target}",
"report.forward_hint": "The account is from another server. Send an anonymized copy of the report there as well?", "report.forward_hint": "The account is from another server. Send an anonymized copy of the report there as well?",
"report.hint": "The report will be sent to your instance moderators. You can provide an explanation of why you are reporting this account below:", "report.hint": "The report will be sent to your instance moderators. You can provide an explanation of why you are reporting this account below:",
"report.placeholder": "Additional comments", "report.placeholder": "Comentarios adicionales",
"report.submit": "Submit", "report.submit": "Submit",
"report.target": "Report {target}", "report.target": "Report {target}",
"search.placeholder": "Search", "search.placeholder": "Search",
"search_popout.search_format": "Advanced search format", "search_popout.search_format": "Advanced search format",
"search_popout.tips.full_text": "Simple text returns statuses you have written, favourited, boosted, or have been mentioned in, as well as matching usernames, display names, and hashtags.", "search_popout.tips.full_text": "Simple text returns statuses you have written, favourited, boosted, or have been mentioned in, as well as matching usernames, display names, and hashtags.",
"search_popout.tips.hashtag": "hashtag", "search_popout.tips.hashtag": "etiqueta",
"search_popout.tips.status": "status", "search_popout.tips.status": "estáu",
"search_popout.tips.text": "Simple text returns matching display names, usernames and hashtags", "search_popout.tips.text": "Simple text returns matching display names, usernames and hashtags",
"search_popout.tips.user": "user", "search_popout.tips.user": "usuariu",
"search_results.accounts": "People", "search_results.accounts": "Xente",
"search_results.hashtags": "Hashtags", "search_results.hashtags": "Hashtags",
"search_results.statuses": "Toots", "search_results.statuses": "Toots",
"search_results.total": "{count, number} {count, plural, one {result} other {results}}", "search_results.total": "{count, number} {count, plural, one {result} other {results}}",
"standalone.public_title": "A look inside...", "standalone.public_title": "A look inside...",
"status.block": "Block @{name}", "status.block": "Bloquiar a @{name}",
"status.cancel_reblog_private": "Unboost", "status.cancel_reblog_private": "Unboost",
"status.cannot_reblog": "This post cannot be boosted", "status.cannot_reblog": "This post cannot be boosted",
"status.delete": "Delete", "status.delete": "Delete",
"status.detailed_status": "Detailed conversation view", "status.detailed_status": "Detailed conversation view",
"status.direct": "Direct message @{name}", "status.direct": "Unviar un mensaxe direutu a @{name}",
"status.embed": "Embed", "status.embed": "Empotrar",
"status.favourite": "Favourite", "status.favourite": "Favourite",
"status.filtered": "Filtered", "status.filtered": "Filtered",
"status.load_more": "Load more", "status.load_more": "Cargar más",
"status.media_hidden": "Media hidden", "status.media_hidden": "Media hidden",
"status.mention": "Mention @{name}", "status.mention": "Mentar a @{name}",
"status.more": "More", "status.more": "Más",
"status.mute": "Mute @{name}", "status.mute": "Silenciar a @{name}",
"status.mute_conversation": "Mute conversation", "status.mute_conversation": "Mute conversation",
"status.open": "Expand this status", "status.open": "Espander esti estáu",
"status.pin": "Pin on profile", "status.pin": "Pin on profile",
"status.pinned": "Pinned toot", "status.pinned": "Pinned toot",
"status.reblog": "Boost", "status.reblog": "Boost",
@ -299,25 +300,25 @@
"status.reblogged_by": "{name} boosted", "status.reblogged_by": "{name} boosted",
"status.reblogs.empty": "No one has boosted this toot yet. When someone does, they will show up here.", "status.reblogs.empty": "No one has boosted this toot yet. When someone does, they will show up here.",
"status.redraft": "Delete & re-draft", "status.redraft": "Delete & re-draft",
"status.reply": "Reply", "status.reply": "Responder",
"status.replyAll": "Reply to thread", "status.replyAll": "Reply to thread",
"status.report": "Report @{name}", "status.report": "Report @{name}",
"status.sensitive_toggle": "Click to view", "status.sensitive_toggle": "Click to view",
"status.sensitive_warning": "Sensitive content", "status.sensitive_warning": "Sensitive content",
"status.share": "Share", "status.share": "Share",
"status.show_less": "Show less", "status.show_less": "Amosar menos",
"status.show_less_all": "Show less for all", "status.show_less_all": "Show less for all",
"status.show_more": "Show more", "status.show_more": "Amosar más",
"status.show_more_all": "Show more for all", "status.show_more_all": "Show more for all",
"status.unmute_conversation": "Unmute conversation", "status.unmute_conversation": "Unmute conversation",
"status.unpin": "Unpin from profile", "status.unpin": "Unpin from profile",
"tabs_bar.federated_timeline": "Federated", "tabs_bar.federated_timeline": "Federated",
"tabs_bar.home": "Home", "tabs_bar.home": "Aniciu",
"tabs_bar.local_timeline": "Local", "tabs_bar.local_timeline": "Local",
"tabs_bar.notifications": "Notifications", "tabs_bar.notifications": "Avisos",
"tabs_bar.search": "Search", "tabs_bar.search": "Search",
"trends.count_by_accounts": "{count} {rawCount, plural, one {person} other {people}} talking", "trends.count_by_accounts": "{count} {rawCount, plural, one {person} other {people}} talking",
"ui.beforeunload": "Your draft will be lost if you leave Mastodon.", "ui.beforeunload": "El borrador va perdese si coles de Mastodon.",
"upload_area.title": "Drag & drop to upload", "upload_area.title": "Drag & drop to upload",
"upload_button.label": "Add media", "upload_button.label": "Add media",
"upload_form.description": "Describe for the visually impaired", "upload_form.description": "Describe for the visually impaired",

@ -15,6 +15,7 @@
"account.follows.empty": "This user doesn't follow anyone yet.", "account.follows.empty": "This user doesn't follow anyone yet.",
"account.follows_you": "Твой последовател", "account.follows_you": "Твой последовател",
"account.hide_reblogs": "Hide boosts from @{name}", "account.hide_reblogs": "Hide boosts from @{name}",
"account.link_verified_on": "Ownership of this link was checked on {date}",
"account.media": "Media", "account.media": "Media",
"account.mention": "Споменаване", "account.mention": "Споменаване",
"account.moved_to": "{name} has moved to:", "account.moved_to": "{name} has moved to:",

@ -15,6 +15,7 @@
"account.follows.empty": "Aquest usuari encara no segueix a ningú.", "account.follows.empty": "Aquest usuari encara no segueix a ningú.",
"account.follows_you": "Et segueix", "account.follows_you": "Et segueix",
"account.hide_reblogs": "Amaga els impulsos de @{name}", "account.hide_reblogs": "Amaga els impulsos de @{name}",
"account.link_verified_on": "Ownership of this link was checked on {date}",
"account.media": "Media", "account.media": "Media",
"account.mention": "Esmentar @{name}", "account.mention": "Esmentar @{name}",
"account.moved_to": "{name} s'ha mogut a:", "account.moved_to": "{name} s'ha mogut a:",

@ -15,6 +15,7 @@
"account.follows.empty": "St'utilizatore ùn seguita nisunu.", "account.follows.empty": "St'utilizatore ùn seguita nisunu.",
"account.follows_you": "Vi seguita", "account.follows_you": "Vi seguita",
"account.hide_reblogs": "Piattà spartere da @{name}", "account.hide_reblogs": "Piattà spartere da @{name}",
"account.link_verified_on": "Ownership of this link was checked on {date}",
"account.media": "Media", "account.media": "Media",
"account.mention": "Mintuvà @{name}", "account.mention": "Mintuvà @{name}",
"account.moved_to": "{name} hè partutu nant'à:", "account.moved_to": "{name} hè partutu nant'à:",

@ -15,6 +15,7 @@
"account.follows.empty": "Tento uživatel ještě nikoho nesleduje.", "account.follows.empty": "Tento uživatel ještě nikoho nesleduje.",
"account.follows_you": "Sleduje vás", "account.follows_you": "Sleduje vás",
"account.hide_reblogs": "Skrýt boosty od uživatele @{name}", "account.hide_reblogs": "Skrýt boosty od uživatele @{name}",
"account.link_verified_on": "Ownership of this link was checked on {date}",
"account.media": "Média", "account.media": "Média",
"account.mention": "Zmínit uživatele @{name}", "account.mention": "Zmínit uživatele @{name}",
"account.moved_to": "{name} se přesunul/a na:", "account.moved_to": "{name} se přesunul/a na:",

@ -1,121 +1,122 @@
{ {
"account.badges.bot": "Bot", "account.badges.bot": "Bot",
"account.block": "Block @{name}", "account.block": "Blociwch @{name}",
"account.block_domain": "Hide everything from {domain}", "account.block_domain": "Cuddiwch bopeth rhag {domain}",
"account.blocked": "Blocked", "account.blocked": "Blociwyd",
"account.direct": "Direct message @{name}", "account.direct": "Neges breifat @{name}",
"account.disclaimer_full": "Information below may reflect the user's profile incompletely.", "account.disclaimer_full": "Gall y wybodaeth isod adlewyrchu darlun anghyflawn o broffil defnyddiwr.",
"account.domain_blocked": "Domain hidden", "account.domain_blocked": "Domain hidden",
"account.edit_profile": "Edit profile", "account.edit_profile": "Golygu proffil",
"account.endorse": "Feature on profile", "account.endorse": "Feature on profile",
"account.follow": "Follow", "account.follow": "Dilyn",
"account.followers": "Followers", "account.followers": "Dilynwyr",
"account.followers.empty": "No one follows this user yet.", "account.followers.empty": "Nid oes neb yn dilyn y defnyddiwr hwn eto.",
"account.follows": "Follows", "account.follows": "Yn dilyn",
"account.follows.empty": "This user doesn't follow anyone yet.", "account.follows.empty": "Nid yw'r defnyddiwr hwn yn dilyn unrhyw un eto.",
"account.follows_you": "Follows you", "account.follows_you": "Yn eich dilyn chi",
"account.hide_reblogs": "Hide boosts from @{name}", "account.hide_reblogs": "Hide boosts from @{name}",
"account.media": "Media", "account.link_verified_on": "Ownership of this link was checked on {date}",
"account.mention": "Mention @{name}", "account.media": "Cyfryngau",
"account.moved_to": "{name} has moved to:", "account.mention": "Crybwyll @{name}",
"account.moved_to": "Mae @{name} wedi symud i:",
"account.mute": "Mute @{name}", "account.mute": "Mute @{name}",
"account.mute_notifications": "Mute notifications from @{name}", "account.mute_notifications": "Mute notifications from @{name}",
"account.muted": "Muted", "account.muted": "Distewyd",
"account.posts": "Toots", "account.posts": "Tŵtiau",
"account.posts_with_replies": "Toots and replies", "account.posts_with_replies": "Toots and replies",
"account.report": "Report @{name}", "account.report": "Adroddwch @{name}",
"account.requested": "Awaiting approval. Click to cancel follow request", "account.requested": "Awaiting approval. Click to cancel follow request",
"account.share": "Share @{name}'s profile", "account.share": "Rhannwch broffil @{name}",
"account.show_reblogs": "Show boosts from @{name}", "account.show_reblogs": "Show boosts from @{name}",
"account.unblock": "Unblock @{name}", "account.unblock": "Dadflociwch @{name}",
"account.unblock_domain": "Unhide {domain}", "account.unblock_domain": "Dadguddiwch {domain}",
"account.unendorse": "Don't feature on profile", "account.unendorse": "Don't feature on profile",
"account.unfollow": "Unfollow", "account.unfollow": "Daddilynwch",
"account.unmute": "Unmute @{name}", "account.unmute": "Unmute @{name}",
"account.unmute_notifications": "Unmute notifications from @{name}", "account.unmute_notifications": "Unmute notifications from @{name}",
"account.view_full_profile": "View full profile", "account.view_full_profile": "View full profile",
"alert.unexpected.message": "An unexpected error occurred.", "alert.unexpected.message": "Digwyddodd gwall annisgwyl.",
"alert.unexpected.title": "Oops!", "alert.unexpected.title": "Wps!",
"boost_modal.combo": "You can press {combo} to skip this next time", "boost_modal.combo": "You can press {combo} to skip this next time",
"bundle_column_error.body": "Something went wrong while loading this component.", "bundle_column_error.body": "Aeth rhywbeth o'i le tra'n llwytho'r elfen hon.",
"bundle_column_error.retry": "Try again", "bundle_column_error.retry": "Ceisiwch eto",
"bundle_column_error.title": "Network error", "bundle_column_error.title": "Gwall rhwydwaith",
"bundle_modal_error.close": "Close", "bundle_modal_error.close": "Close",
"bundle_modal_error.message": "Something went wrong while loading this component.", "bundle_modal_error.message": "Aeth rhywbeth o'i le tra'n llwytho'r elfen hon.",
"bundle_modal_error.retry": "Try again", "bundle_modal_error.retry": "Ceiswich eto",
"column.blocks": "Blocked users", "column.blocks": "Defnyddwyr a flociwyd",
"column.community": "Local timeline", "column.community": "Llinell amser lleol",
"column.direct": "Direct messages", "column.direct": "Negeseuon preifat",
"column.domain_blocks": "Hidden domains", "column.domain_blocks": "Parthau cuddiedig",
"column.favourites": "Favourites", "column.favourites": "Ffefrynnau",
"column.follow_requests": "Follow requests", "column.follow_requests": "Ceisiadau dilyn",
"column.home": "Hafan", "column.home": "Hafan",
"column.lists": "Lists", "column.lists": "Rhestrau",
"column.mutes": "Muted users", "column.mutes": "Defnyddwyr a ddistewyd",
"column.notifications": "Notifications", "column.notifications": "Hysbysiadau",
"column.pins": "Pinned toot", "column.pins": "Pinned toot",
"column.public": "Federated timeline", "column.public": "Federated timeline",
"column_back_button.label": "Nôl", "column_back_button.label": "Nôl",
"column_header.hide_settings": "Hide settings", "column_header.hide_settings": "Hide settings",
"column_header.moveLeft_settings": "Move column to the left", "column_header.moveLeft_settings": "Symudwch y golofn i'r chwith",
"column_header.moveRight_settings": "Move column to the right", "column_header.moveRight_settings": "Symudwch y golofn i'r dde",
"column_header.pin": "Pin", "column_header.pin": "Piniwch",
"column_header.show_settings": "Show settings", "column_header.show_settings": "Dangos gosodiadau",
"column_header.unpin": "Unpin", "column_header.unpin": "Dadbiniwch",
"column_subheading.settings": "Settings", "column_subheading.settings": "Gosodiadau",
"community.column_settings.media_only": "Media Only", "community.column_settings.media_only": "Cyfryngau yn unig",
"compose_form.direct_message_warning": "This toot will only be sent to all the mentioned users.", "compose_form.direct_message_warning": "Mi fydd y tŵt hwn ond yn cael ei anfon at y defnyddwyr sy'n cael eu crybwyll.",
"compose_form.direct_message_warning_learn_more": "Learn more", "compose_form.direct_message_warning_learn_more": "Dysgwch fwy",
"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.hashtag_warning": "Ni fydd y tŵt hwn wedi ei restru o dan unrhyw hashnod gan ei fod heb ei restru. Dim ond tŵtiau cyhoeddus gellid chwilota amdanynt drwy hashnod.",
"compose_form.lock_disclaimer": "Your account is not {locked}. Anyone can follow you to view your follower-only posts.", "compose_form.lock_disclaimer": "Nid yw eich cyfri wedi'i {locked}. Gall unrhyw un eich dilyn i weld eich POSTS dilynwyr-yn-unig.",
"compose_form.lock_disclaimer.lock": "locked", "compose_form.lock_disclaimer.lock": "wedi ei gloi",
"compose_form.placeholder": "What is on your mind?", "compose_form.placeholder": "Be syd ar eich meddwl?",
"compose_form.publish": "Toot", "compose_form.publish": "Tŵt",
"compose_form.publish_loud": "{publish}!", "compose_form.publish_loud": "{publish}!",
"compose_form.sensitive.marked": "Media is marked as sensitive", "compose_form.sensitive.marked": "Media is marked as sensitive",
"compose_form.sensitive.unmarked": "Media is not marked as sensitive", "compose_form.sensitive.unmarked": "Media is not marked as sensitive",
"compose_form.spoiler.marked": "Text is hidden behind warning", "compose_form.spoiler.marked": "Testun wedi ei guddio gan rybudd",
"compose_form.spoiler.unmarked": "Text is not hidden", "compose_form.spoiler.unmarked": "Nid yw'r testun wedi ei guddio",
"compose_form.spoiler_placeholder": "Write your warning here", "compose_form.spoiler_placeholder": "Ysgrifenwch eich rhybudd yma",
"confirmation_modal.cancel": "Cancel", "confirmation_modal.cancel": "Cancel",
"confirmations.block.confirm": "Block", "confirmations.block.confirm": "Blociwch",
"confirmations.block.message": "Are you sure you want to block {name}?", "confirmations.block.message": "Ydych chi'n sicr eich bod eisiau blocio {name}?",
"confirmations.delete.confirm": "Delete", "confirmations.delete.confirm": "Dileu",
"confirmations.delete.message": "Are you sure you want to delete this status?", "confirmations.delete.message": "Ydych chi'n sicr eich bod eisiau dileu y statws hwn?",
"confirmations.delete_list.confirm": "Delete", "confirmations.delete_list.confirm": "Dileu",
"confirmations.delete_list.message": "Are you sure you want to permanently delete this list?", "confirmations.delete_list.message": "Ydych chi'n sicr eich bod eisiau dileu y rhestr hwn am byth?",
"confirmations.domain_block.confirm": "Hide entire domain", "confirmations.domain_block.confirm": "Hide entire domain",
"confirmations.domain_block.message": "Are you really, really sure you want to block the entire {domain}? In most cases a few targeted blocks or mutes are sufficient and preferable. You will not see content from that domain in any public timelines or your notifications. Your followers from that domain will be removed.", "confirmations.domain_block.message": "Are you really, really sure you want to block the entire {domain}? In most cases a few targeted blocks or mutes are sufficient and preferable. You will not see content from that domain in any public timelines or your notifications. Your followers from that domain will be removed.",
"confirmations.mute.confirm": "Mute", "confirmations.mute.confirm": "Mute",
"confirmations.mute.message": "Are you sure you want to mute {name}?", "confirmations.mute.message": "Ydych chi'n sicr eich bod am ddistewi {name}?",
"confirmations.redraft.confirm": "Delete & redraft", "confirmations.redraft.confirm": "Delete & redraft",
"confirmations.redraft.message": "Are you sure you want to delete this status and re-draft it? Favourites and boosts will be lost, and replies to the original post will be orphaned.", "confirmations.redraft.message": "Are you sure you want to delete this status and re-draft it? Favourites and boosts will be lost, and replies to the original post will be orphaned.",
"confirmations.unfollow.confirm": "Unfollow", "confirmations.unfollow.confirm": "Dad-ddilynwch",
"confirmations.unfollow.message": "Are you sure you want to unfollow {name}?", "confirmations.unfollow.message": "Ydych chi'n sicr eich bod am ddad-ddilyn {name}?",
"embed.instructions": "Embed this status on your website by copying the code below.", "embed.instructions": "Embed this status on your website by copying the code below.",
"embed.preview": "Here is what it will look like:", "embed.preview": "Dyma sut olwg fydd arno:",
"emoji_button.activity": "Activity", "emoji_button.activity": "Gweithgarwch",
"emoji_button.custom": "Custom", "emoji_button.custom": "Custom",
"emoji_button.flags": "Flags", "emoji_button.flags": "Baneri",
"emoji_button.food": "Food & Drink", "emoji_button.food": "Bwyd a Diod",
"emoji_button.label": "Insert emoji", "emoji_button.label": "Mewnosodwch emoji",
"emoji_button.nature": "Nature", "emoji_button.nature": "Natur",
"emoji_button.not_found": "No emojos!! (╯°□°)╯︵ ┻━┻", "emoji_button.not_found": "Dim emojos!! (╯°□°)╯︵ ┻━┻",
"emoji_button.objects": "Objects", "emoji_button.objects": "Gwrthrychau",
"emoji_button.people": "People", "emoji_button.people": "Pobl",
"emoji_button.recent": "Frequently used", "emoji_button.recent": "Defnyddir yn aml",
"emoji_button.search": "Search...", "emoji_button.search": "Chwilio...",
"emoji_button.search_results": "Search results", "emoji_button.search_results": "Canlyniadau chwilio",
"emoji_button.symbols": "Symbols", "emoji_button.symbols": "Symbolau",
"emoji_button.travel": "Travel & Places", "emoji_button.travel": "Teithio & Llefydd",
"empty_column.blocks": "You haven't blocked any users yet.", "empty_column.blocks": "Nid ydych wedi blocio unrhyw ddefnyddwyr eto.",
"empty_column.community": "The local timeline is empty. Write something publicly to get the ball rolling!", "empty_column.community": "The local timeline is empty. Write something publicly to get the ball rolling!",
"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": "Nid oes gennych unrhyw negeseuon preifat eto. Pan y byddwch yn anfon neu derbyn un, mi fydd yn ymddangos yma.",
"empty_column.domain_blocks": "There are no hidden domains yet.", "empty_column.domain_blocks": "Nid oes yna unrhyw barthau cuddiedig eto.",
"empty_column.favourited_statuses": "You don't have any favourite toots yet. When you favourite one, it will show up here.", "empty_column.favourited_statuses": "Nid oes gennych unrhyw hoff dwtiau eto. Pan y byddwch yn hoffi un, mi fydd yn ymddangos yma.",
"empty_column.favourites": "No one has favourited this toot yet. When someone does, they will show up here.", "empty_column.favourites": "Nid oes neb wedi hoffi'r tŵt yma eto. Pan bydd rhywun yn ei hoffi, mi fyddent yn ymddangos yma.",
"empty_column.follow_requests": "You don't have any follow requests yet. When you receive one, it will show up here.", "empty_column.follow_requests": "You don't have any follow requests yet. When you receive one, it will show up here.",
"empty_column.hashtag": "There is nothing in this hashtag yet.", "empty_column.hashtag": "Nid oes dim ar yr hashnod hwn eto.",
"empty_column.home": "Your home timeline is empty! Visit {public} or use search to get started and meet other users.", "empty_column.home": "Your home timeline is empty! Visit {public} or use search to get started and meet other users.",
"empty_column.home.public_timeline": "the public timeline", "empty_column.home.public_timeline": "the public timeline",
"empty_column.list": "There is nothing in this list yet. When members of this list post new statuses, they will appear here.", "empty_column.list": "There is nothing in this list yet. When members of this list post new statuses, they will appear here.",
@ -123,120 +124,120 @@
"empty_column.mutes": "You haven't muted any users yet.", "empty_column.mutes": "You haven't muted any users yet.",
"empty_column.notifications": "You don't have any notifications yet. Interact with others to start the conversation.", "empty_column.notifications": "You don't have any notifications yet. Interact with others to start the conversation.",
"empty_column.public": "There is nothing here! Write something publicly, or manually follow users from other instances to fill it up", "empty_column.public": "There is nothing here! Write something publicly, or manually follow users from other instances to fill it up",
"follow_request.authorize": "Authorize", "follow_request.authorize": "Caniatau",
"follow_request.reject": "Reject", "follow_request.reject": "Gwrthod",
"getting_started.developers": "Developers", "getting_started.developers": "Datblygwyr",
"getting_started.documentation": "Documentation", "getting_started.documentation": "Dogfennaeth",
"getting_started.find_friends": "Find friends from Twitter", "getting_started.find_friends": "Canfod ffrindiau o Twitter",
"getting_started.heading": "Getting started", "getting_started.heading": "Dechrau",
"getting_started.invite": "Invite people", "getting_started.invite": "Gwahoddwch bobl",
"getting_started.open_source_notice": "Mastodon is open source software. You can contribute or report issues on GitHub at {github}.", "getting_started.open_source_notice": "Mastodon is open source software. You can contribute or report issues on GitHub at {github}.",
"getting_started.security": "Security", "getting_started.security": "Diogelwch",
"getting_started.terms": "Terms of service", "getting_started.terms": "Terms of service",
"home.column_settings.basic": "Basic", "home.column_settings.basic": "Syml",
"home.column_settings.show_reblogs": "Show boosts", "home.column_settings.show_reblogs": "Show boosts",
"home.column_settings.show_replies": "Show replies", "home.column_settings.show_replies": "Dangoswch ymatebion",
"keyboard_shortcuts.back": "to navigate back", "keyboard_shortcuts.back": "to navigate back",
"keyboard_shortcuts.blocked": "to open blocked users list", "keyboard_shortcuts.blocked": "to open blocked users list",
"keyboard_shortcuts.boost": "to boost", "keyboard_shortcuts.boost": "to boost",
"keyboard_shortcuts.column": "to focus a status in one of the columns", "keyboard_shortcuts.column": "to focus a status in one of the columns",
"keyboard_shortcuts.compose": "to focus the compose textarea", "keyboard_shortcuts.compose": "to focus the compose textarea",
"keyboard_shortcuts.description": "Description", "keyboard_shortcuts.description": "Disgrifiad",
"keyboard_shortcuts.direct": "to open direct messages column", "keyboard_shortcuts.direct": "i agor colofn negeseuon preifat",
"keyboard_shortcuts.down": "to move down in the list", "keyboard_shortcuts.down": "i symud lawr yn y rhestr",
"keyboard_shortcuts.enter": "to open status", "keyboard_shortcuts.enter": "i agor statws",
"keyboard_shortcuts.favourite": "to favourite", "keyboard_shortcuts.favourite": "i hoffi",
"keyboard_shortcuts.favourites": "to open favourites list", "keyboard_shortcuts.favourites": "i agor rhestr hoffi",
"keyboard_shortcuts.federated": "to open federated timeline", "keyboard_shortcuts.federated": "to open federated timeline",
"keyboard_shortcuts.heading": "Keyboard Shortcuts", "keyboard_shortcuts.heading": "Keyboard Shortcuts",
"keyboard_shortcuts.home": "to open home timeline", "keyboard_shortcuts.home": "to open home timeline",
"keyboard_shortcuts.hotkey": "Hotkey", "keyboard_shortcuts.hotkey": "Hotkey",
"keyboard_shortcuts.legend": "to display this legend", "keyboard_shortcuts.legend": "to display this legend",
"keyboard_shortcuts.local": "to open local timeline", "keyboard_shortcuts.local": "to open local timeline",
"keyboard_shortcuts.mention": "to mention author", "keyboard_shortcuts.mention": "i grybwyll yr awdur",
"keyboard_shortcuts.muted": "to open muted users list", "keyboard_shortcuts.muted": "to open muted users list",
"keyboard_shortcuts.my_profile": "to open your profile", "keyboard_shortcuts.my_profile": "i agor eich proffil",
"keyboard_shortcuts.notifications": "to open notifications column", "keyboard_shortcuts.notifications": "i agor colofn hysbysiadau",
"keyboard_shortcuts.pinned": "to open pinned toots list", "keyboard_shortcuts.pinned": "to open pinned toots list",
"keyboard_shortcuts.profile": "to open author's profile", "keyboard_shortcuts.profile": "i agor proffil yr awdur",
"keyboard_shortcuts.reply": "to reply", "keyboard_shortcuts.reply": "i ateb",
"keyboard_shortcuts.requests": "to open follow requests list", "keyboard_shortcuts.requests": "to open follow requests list",
"keyboard_shortcuts.search": "to focus search", "keyboard_shortcuts.search": "to focus search",
"keyboard_shortcuts.start": "to open \"get started\" column", "keyboard_shortcuts.start": "to open \"get started\" column",
"keyboard_shortcuts.toggle_hidden": "to show/hide text behind CW", "keyboard_shortcuts.toggle_hidden": "to show/hide text behind CW",
"keyboard_shortcuts.toot": "to start a brand new toot", "keyboard_shortcuts.toot": "i ddechrau tŵt newydd sbon",
"keyboard_shortcuts.unfocus": "to un-focus compose textarea/search", "keyboard_shortcuts.unfocus": "to un-focus compose textarea/search",
"keyboard_shortcuts.up": "to move up in the list", "keyboard_shortcuts.up": "to move up in the list",
"lightbox.close": "Close", "lightbox.close": "Cau",
"lightbox.next": "Next", "lightbox.next": "Nesaf",
"lightbox.previous": "Previous", "lightbox.previous": "Previous",
"lists.account.add": "Add to list", "lists.account.add": "Ychwanegwch at restr",
"lists.account.remove": "Remove from list", "lists.account.remove": "Remove from list",
"lists.delete": "Delete list", "lists.delete": "Dileu rhestr",
"lists.edit": "Edit list", "lists.edit": "Golygwch restr",
"lists.new.create": "Add list", "lists.new.create": "Ychwanegwch restr",
"lists.new.title_placeholder": "New list title", "lists.new.title_placeholder": "New list title",
"lists.search": "Search among people you follow", "lists.search": "Search among people you follow",
"lists.subheading": "Your lists", "lists.subheading": "Eich rhestrau",
"loading_indicator.label": "Loading...", "loading_indicator.label": "Llwytho...",
"media_gallery.toggle_visible": "Toggle visibility", "media_gallery.toggle_visible": "Toggle visibility",
"missing_indicator.label": "Not found", "missing_indicator.label": "Heb ei ganfod",
"missing_indicator.sublabel": "This resource could not be found", "missing_indicator.sublabel": "Ni ellid canfod yr adnodd hwn",
"mute_modal.hide_notifications": "Hide notifications from this user?", "mute_modal.hide_notifications": "Cuddiwch hysbysiadau rhag y defnyddiwr hwn?",
"navigation_bar.apps": "Mobile apps", "navigation_bar.apps": "Apiau symudol",
"navigation_bar.blocks": "Blocked users", "navigation_bar.blocks": "Defnyddwyr wedi eu blocio",
"navigation_bar.community_timeline": "Local timeline", "navigation_bar.community_timeline": "Local timeline",
"navigation_bar.compose": "Compose new toot", "navigation_bar.compose": "Cyfansoddwch dŵt newydd",
"navigation_bar.direct": "Direct messages", "navigation_bar.direct": "Negeseuon preifat",
"navigation_bar.discover": "Discover", "navigation_bar.discover": "Darganfyddwch",
"navigation_bar.domain_blocks": "Hidden domains", "navigation_bar.domain_blocks": "Parthau cuddiedig",
"navigation_bar.edit_profile": "Edit profile", "navigation_bar.edit_profile": "Golygu proffil",
"navigation_bar.favourites": "Favourites", "navigation_bar.favourites": "Ffefrynnau",
"navigation_bar.filters": "Muted words", "navigation_bar.filters": "Muted words",
"navigation_bar.follow_requests": "Follow requests", "navigation_bar.follow_requests": "Ceisiadau dilyn",
"navigation_bar.info": "About this instance", "navigation_bar.info": "About this instance",
"navigation_bar.keyboard_shortcuts": "Hotkeys", "navigation_bar.keyboard_shortcuts": "Hotkeys",
"navigation_bar.lists": "Lists", "navigation_bar.lists": "Rhestrau",
"navigation_bar.logout": "Logout", "navigation_bar.logout": "Allgofnodi",
"navigation_bar.mutes": "Muted users", "navigation_bar.mutes": "Muted users",
"navigation_bar.personal": "Personal", "navigation_bar.personal": "Personol",
"navigation_bar.pins": "Pinned toots", "navigation_bar.pins": "Tŵtiau wedi eu pinio",
"navigation_bar.preferences": "Preferences", "navigation_bar.preferences": "Dewisiadau",
"navigation_bar.public_timeline": "Federated timeline", "navigation_bar.public_timeline": "Federated timeline",
"navigation_bar.security": "Security", "navigation_bar.security": "Diogelwch",
"notification.favourite": "{name} favourited your status", "notification.favourite": "hoffodd {name} eich statws",
"notification.follow": "{name} followed you", "notification.follow": "dilynodd {name} chi",
"notification.mention": "{name} mentioned you", "notification.mention": "{name} mentioned you",
"notification.reblog": "{name} boosted your status", "notification.reblog": "{name} boosted your status",
"notifications.clear": "Clear notifications", "notifications.clear": "Clirio hysbysiadau",
"notifications.clear_confirmation": "Are you sure you want to permanently clear all your notifications?", "notifications.clear_confirmation": "Are you sure you want to permanently clear all your notifications?",
"notifications.column_settings.alert": "Desktop notifications", "notifications.column_settings.alert": "Desktop notifications",
"notifications.column_settings.favourite": "Favourites:", "notifications.column_settings.favourite": "Ffefrynnau:",
"notifications.column_settings.follow": "New followers:", "notifications.column_settings.follow": "Dilynwyr newydd:",
"notifications.column_settings.mention": "Mentions:", "notifications.column_settings.mention": "Mentions:",
"notifications.column_settings.push": "Push notifications", "notifications.column_settings.push": "Push notifications",
"notifications.column_settings.push_meta": "This device", "notifications.column_settings.push_meta": "This device",
"notifications.column_settings.reblog": "Boosts:", "notifications.column_settings.reblog": "Boosts:",
"notifications.column_settings.show": "Show in column", "notifications.column_settings.show": "Show in column",
"notifications.column_settings.sound": "Play sound", "notifications.column_settings.sound": "Chwarae sain",
"notifications.group": "{count} notifications", "notifications.group": "{count} o hysbysiadau",
"onboarding.done": "Done", "onboarding.done": "Done",
"onboarding.next": "Next", "onboarding.next": "Nesaf",
"onboarding.page_five.public_timelines": "The local timeline shows public posts from everyone on {domain}. The federated timeline shows public posts from everyone who people on {domain} follow. These are the Public Timelines, a great way to discover new people.", "onboarding.page_five.public_timelines": "The local timeline shows public posts from everyone on {domain}. The federated timeline shows public posts from everyone who people on {domain} follow. These are the Public Timelines, a great way to discover new people.",
"onboarding.page_four.home": "The home timeline shows posts from people you follow.", "onboarding.page_four.home": "The home timeline shows posts from people you follow.",
"onboarding.page_four.notifications": "The notifications column shows when someone interacts with you.", "onboarding.page_four.notifications": "The notifications column shows when someone interacts with you.",
"onboarding.page_one.federation": "Mastodon is a network of independent servers joining up to make one larger social network. We call these servers instances.", "onboarding.page_one.federation": "Mastodon is a network of independent servers joining up to make one larger social network. We call these servers instances.",
"onboarding.page_one.full_handle": "Your full handle", "onboarding.page_one.full_handle": "Your full handle",
"onboarding.page_one.handle_hint": "This is what you would tell your friends to search for.", "onboarding.page_one.handle_hint": "This is what you would tell your friends to search for.",
"onboarding.page_one.welcome": "Welcome to Mastodon!", "onboarding.page_one.welcome": "Croeso i Mastodon!",
"onboarding.page_six.admin": "Your instance's admin is {admin}.", "onboarding.page_six.admin": "Your instance's admin is {admin}.",
"onboarding.page_six.almost_done": "Almost done...", "onboarding.page_six.almost_done": "Almost done...",
"onboarding.page_six.appetoot": "Bon Appetoot!", "onboarding.page_six.appetoot": "Bon Apetŵt!",
"onboarding.page_six.apps_available": "There are {apps} available for iOS, Android and other platforms.", "onboarding.page_six.apps_available": "There are {apps} available for iOS, Android and other platforms.",
"onboarding.page_six.github": "Mastodon is free open-source software. You can report bugs, request features, or contribute to the code on {github}.", "onboarding.page_six.github": "Mastodon is free open-source software. You can report bugs, request features, or contribute to the code on {github}.",
"onboarding.page_six.guidelines": "community guidelines", "onboarding.page_six.guidelines": "canllawiau cymunedol",
"onboarding.page_six.read_guidelines": "Please read {domain}'s {guidelines}!", "onboarding.page_six.read_guidelines": "Please read {domain}'s {guidelines}!",
"onboarding.page_six.various_app": "mobile apps", "onboarding.page_six.various_app": "apiau symudol",
"onboarding.page_three.profile": "Edit your profile to change your avatar, bio, and display name. There, you will also find other preferences.", "onboarding.page_three.profile": "Edit your profile to change your avatar, bio, and display name. There, you will also find other preferences.",
"onboarding.page_three.search": "Use the search bar to find people and look at hashtags, such as {illustration} and {introductions}. To look for a person who is not on this instance, use their full handle.", "onboarding.page_three.search": "Use the search bar to find people and look at hashtags, such as {illustration} and {introductions}. To look for a person who is not on this instance, use their full handle.",
"onboarding.page_two.compose": "Write posts from the compose column. You can upload images, change privacy settings, and add content warnings with the icons below.", "onboarding.page_two.compose": "Write posts from the compose column. You can upload images, change privacy settings, and add content warnings with the icons below.",
@ -245,50 +246,50 @@
"privacy.direct.long": "Post to mentioned users only", "privacy.direct.long": "Post to mentioned users only",
"privacy.direct.short": "Direct", "privacy.direct.short": "Direct",
"privacy.private.long": "Post to followers only", "privacy.private.long": "Post to followers only",
"privacy.private.short": "Followers-only", "privacy.private.short": "Dilynwyr-yn-unig",
"privacy.public.long": "Post to public timelines", "privacy.public.long": "Post to public timelines",
"privacy.public.short": "Public", "privacy.public.short": "Cyhoeddus",
"privacy.unlisted.long": "Do not show in public timelines", "privacy.unlisted.long": "Do not show in public timelines",
"privacy.unlisted.short": "Unlisted", "privacy.unlisted.short": "Heb ei restru",
"regeneration_indicator.label": "Loading…", "regeneration_indicator.label": "Llwytho…",
"regeneration_indicator.sublabel": "Your home feed is being prepared!", "regeneration_indicator.sublabel": "Mae eich ffrwd cartref yn cael ei baratoi!",
"relative_time.days": "{number}d", "relative_time.days": "{number}d",
"relative_time.hours": "{number}h", "relative_time.hours": "{number}h",
"relative_time.just_now": "now", "relative_time.just_now": "nawr",
"relative_time.minutes": "{number}m", "relative_time.minutes": "{number}m",
"relative_time.seconds": "{number}s", "relative_time.seconds": "{number}s",
"reply_indicator.cancel": "Cancel", "reply_indicator.cancel": "Canslo",
"report.forward": "Forward to {target}", "report.forward": "Forward to {target}",
"report.forward_hint": "The account is from another server. Send an anonymized copy of the report there as well?", "report.forward_hint": "The account is from another server. Send an anonymized copy of the report there as well?",
"report.hint": "The report will be sent to your instance moderators. You can provide an explanation of why you are reporting this account below:", "report.hint": "The report will be sent to your instance moderators. You can provide an explanation of why you are reporting this account below:",
"report.placeholder": "Additional comments", "report.placeholder": "Sylwadau ychwanegol",
"report.submit": "Submit", "report.submit": "Submit",
"report.target": "Report {target}", "report.target": "Report {target}",
"search.placeholder": "Search", "search.placeholder": "Chwilio",
"search_popout.search_format": "Advanced search format", "search_popout.search_format": "Advanced search format",
"search_popout.tips.full_text": "Simple text returns statuses you have written, favourited, boosted, or have been mentioned in, as well as matching usernames, display names, and hashtags.", "search_popout.tips.full_text": "Simple text returns statuses you have written, favourited, boosted, or have been mentioned in, as well as matching usernames, display names, and hashtags.",
"search_popout.tips.hashtag": "hashtag", "search_popout.tips.hashtag": "hashnod",
"search_popout.tips.status": "status", "search_popout.tips.status": "statws",
"search_popout.tips.text": "Simple text returns matching display names, usernames and hashtags", "search_popout.tips.text": "Simple text returns matching display names, usernames and hashtags",
"search_popout.tips.user": "user", "search_popout.tips.user": "defnyddiwr",
"search_results.accounts": "People", "search_results.accounts": "Pobl",
"search_results.hashtags": "Hashtags", "search_results.hashtags": "Hanshnodau",
"search_results.statuses": "Toots", "search_results.statuses": "Twtiau",
"search_results.total": "{count, number} {count, plural, one {result} other {results}}", "search_results.total": "{count, number} {count, plural, one {result} other {results}}",
"standalone.public_title": "A look inside...", "standalone.public_title": "A look inside...",
"status.block": "Block @{name}", "status.block": "Block @{name}",
"status.cancel_reblog_private": "Unboost", "status.cancel_reblog_private": "Unboost",
"status.cannot_reblog": "This post cannot be boosted", "status.cannot_reblog": "This post cannot be boosted",
"status.delete": "Delete", "status.delete": "Dileu",
"status.detailed_status": "Detailed conversation view", "status.detailed_status": "Detailed conversation view",
"status.direct": "Direct message @{name}", "status.direct": "Neges breifat @{name}",
"status.embed": "Embed", "status.embed": "Plannu",
"status.favourite": "Favourite", "status.favourite": "Favourite",
"status.filtered": "Filtered", "status.filtered": "Filtered",
"status.load_more": "Load more", "status.load_more": "Llwythwch mwy",
"status.media_hidden": "Media hidden", "status.media_hidden": "Media hidden",
"status.mention": "Mention @{name}", "status.mention": "Mention @{name}",
"status.more": "More", "status.more": "Mwy",
"status.mute": "Mute @{name}", "status.mute": "Mute @{name}",
"status.mute_conversation": "Mute conversation", "status.mute_conversation": "Mute conversation",
"status.open": "Expand this status", "status.open": "Expand this status",
@ -299,23 +300,23 @@
"status.reblogged_by": "{name} boosted", "status.reblogged_by": "{name} boosted",
"status.reblogs.empty": "No one has boosted this toot yet. When someone does, they will show up here.", "status.reblogs.empty": "No one has boosted this toot yet. When someone does, they will show up here.",
"status.redraft": "Delete & re-draft", "status.redraft": "Delete & re-draft",
"status.reply": "Reply", "status.reply": "Ateb",
"status.replyAll": "Reply to thread", "status.replyAll": "Ateb i edefyn",
"status.report": "Report @{name}", "status.report": "Report @{name}",
"status.sensitive_toggle": "Click to view", "status.sensitive_toggle": "Click to view",
"status.sensitive_warning": "Sensitive content", "status.sensitive_warning": "Cynnwys sensitif",
"status.share": "Share", "status.share": "Rhannwch",
"status.show_less": "Show less", "status.show_less": "Dangoswch lai",
"status.show_less_all": "Show less for all", "status.show_less_all": "Dangoswch lai i bawb",
"status.show_more": "Show more", "status.show_more": "Dangoswch fwy",
"status.show_more_all": "Show more for all", "status.show_more_all": "Show more for all",
"status.unmute_conversation": "Unmute conversation", "status.unmute_conversation": "Unmute conversation",
"status.unpin": "Unpin from profile", "status.unpin": "Unpin from profile",
"tabs_bar.federated_timeline": "Federated", "tabs_bar.federated_timeline": "Federated",
"tabs_bar.home": "Home", "tabs_bar.home": "Hafan",
"tabs_bar.local_timeline": "Local", "tabs_bar.local_timeline": "Lleol",
"tabs_bar.notifications": "Notifications", "tabs_bar.notifications": "Hysbysiadau",
"tabs_bar.search": "Search", "tabs_bar.search": "Chwilio",
"trends.count_by_accounts": "{count} {rawCount, plural, one {person} other {people}} talking", "trends.count_by_accounts": "{count} {rawCount, plural, one {person} other {people}} talking",
"ui.beforeunload": "Your draft will be lost if you leave Mastodon.", "ui.beforeunload": "Your draft will be lost if you leave Mastodon.",
"upload_area.title": "Drag & drop to upload", "upload_area.title": "Drag & drop to upload",
@ -323,7 +324,7 @@
"upload_form.description": "Describe for the visually impaired", "upload_form.description": "Describe for the visually impaired",
"upload_form.focus": "Crop", "upload_form.focus": "Crop",
"upload_form.undo": "Delete", "upload_form.undo": "Delete",
"upload_progress.label": "Uploading...", "upload_progress.label": "Uwchlwytho...",
"video.close": "Close video", "video.close": "Close video",
"video.exit_fullscreen": "Exit full screen", "video.exit_fullscreen": "Exit full screen",
"video.expand": "Expand video", "video.expand": "Expand video",
@ -331,6 +332,6 @@
"video.hide": "Hide video", "video.hide": "Hide video",
"video.mute": "Mute sound", "video.mute": "Mute sound",
"video.pause": "Pause", "video.pause": "Pause",
"video.play": "Play", "video.play": "Chwarae",
"video.unmute": "Unmute sound" "video.unmute": "Unmute sound"
} }

@ -15,6 +15,7 @@
"account.follows.empty": "Denne bruger følger endnu ikke nogen.", "account.follows.empty": "Denne bruger følger endnu ikke nogen.",
"account.follows_you": "Følger dig", "account.follows_you": "Følger dig",
"account.hide_reblogs": "Skjul fremhævelserne fra @{name}", "account.hide_reblogs": "Skjul fremhævelserne fra @{name}",
"account.link_verified_on": "Ownership of this link was checked on {date}",
"account.media": "Medie", "account.media": "Medie",
"account.mention": "Nævn @{name}", "account.mention": "Nævn @{name}",
"account.moved_to": "{name} er flyttet til:", "account.moved_to": "{name} er flyttet til:",
@ -200,7 +201,7 @@
"navigation_bar.logout": "Logud", "navigation_bar.logout": "Logud",
"navigation_bar.mutes": "Dæmpede brugere", "navigation_bar.mutes": "Dæmpede brugere",
"navigation_bar.personal": "Personligt", "navigation_bar.personal": "Personligt",
"navigation_bar.pins": "Fastgjorte toots", "navigation_bar.pins": "Fastgjorte trut",
"navigation_bar.preferences": "Præferencer", "navigation_bar.preferences": "Præferencer",
"navigation_bar.public_timeline": "Fælles tidslinje", "navigation_bar.public_timeline": "Fælles tidslinje",
"navigation_bar.security": "Sikkerhed", "navigation_bar.security": "Sikkerhed",
@ -273,7 +274,7 @@
"search_popout.tips.user": "bruger", "search_popout.tips.user": "bruger",
"search_results.accounts": "Folk", "search_results.accounts": "Folk",
"search_results.hashtags": "Emnetags", "search_results.hashtags": "Emnetags",
"search_results.statuses": "Toote", "search_results.statuses": "Trut",
"search_results.total": "{count, number} {count, plural, et {result} andre {results}}", "search_results.total": "{count, number} {count, plural, et {result} andre {results}}",
"standalone.public_title": "Et kig indenfor...", "standalone.public_title": "Et kig indenfor...",
"status.block": "Bloker @{name}", "status.block": "Bloker @{name}",

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

Loading…
Cancel
Save