Merge branch 'master' into glitch-soc/merge-upstream

Conflicts:
- .eslintrc.yml
  Removed, as upstream removed it.
- app/controllers/admin/statuses_controller.rb
  Minor code cleanup when porting one of our features.
- app/models/account.rb
  Note length validation has changed upstream.
  We now use upstream's validation (dropped legacy glitch-soc
  account metadata stuff) but with configurable limit.
- app/services/post_status_service.rb
  Upstream has added support for scheduled toots, refactoring
  the code a bit. Adapted our changes to this refactoring.
- app/views/stream_entries/_detailed_status.html.haml
  Not a real conflict, changes too close.
- app/views/stream_entries/_simple_status.html.haml
  Not a real conflict, changes too close.
main
Thibaut Girka 6 years ago
commit a2a64ecd3e

@ -1,30 +1,13 @@
# See https://help.github.com/articles/ignoring-files for more about ignoring files. /build/**
# /coverage/**
# If you find yourself ignoring temporary files generated by your text editor /db/**
# or operating system, you probably want to add a global ignore instead: /lib/**
# git config --global core.excludesfile '~/.gitignore_global' /log/**
/node_modules/**
# Ignore bundler config. /nonobox/**
/.bundle /public/**
!/public/embed.js
# Ignore the default SQLite database. /spec/**
/db/*.sqlite3 /tmp/**
/db/*.sqlite3-journal /vendor/**
!.eslintrc.js
# Ignore all logfiles and tempfiles.
/log/*
!/log/.keep
/tmp
coverage
public/system
public/assets
.env
.env.production
node_modules/
neo4j/
# Ignore Vagrant files
.vagrant/
# Ignore Capistrano customizations
config/deploy/*

@ -0,0 +1,199 @@
module.exports = {
root: true,
env: {
browser: true,
node: true,
es6: true,
jest: true,
},
globals: {
ATTACHMENT_HOST: false,
},
parser: 'babel-eslint',
plugins: [
'react',
'jsx-a11y',
'import',
'promise',
],
parserOptions: {
sourceType: 'module',
ecmaFeatures: {
experimentalObjectRestSpread: true,
jsx: true,
},
ecmaVersion: 2018,
},
settings: {
react: {
version: 'detect',
},
'import/extensions': [
'.js',
],
'import/ignore': [
'node_modules',
'\\.(css|scss|json)$',
],
},
rules: {
'brace-style': 'warn',
'comma-dangle': ['error', 'always-multiline'],
'comma-spacing': [
'warn',
{
before: false,
after: true,
},
],
'comma-style': ['warn', 'last'],
'consistent-return': 'error',
'dot-notation': 'error',
eqeqeq: 'error',
indent: ['warn', 2],
'jsx-quotes': ['error', 'prefer-single'],
'no-catch-shadow': 'error',
'no-cond-assign': 'error',
'no-console': [
'warn',
{
allow: [
'error',
'warn',
],
},
],
'no-fallthrough': 'error',
'no-irregular-whitespace': 'error',
'no-mixed-spaces-and-tabs': 'warn',
'no-nested-ternary': 'warn',
'no-trailing-spaces': 'warn',
'no-undef': 'error',
'no-unreachable': 'error',
'no-unused-expressions': 'error',
'no-unused-vars': [
'error',
{
vars: 'all',
args: 'after-used',
ignoreRestSiblings: true,
},
],
'object-curly-spacing': ['error', 'always'],
'padded-blocks': [
'error',
{
classes: 'always',
},
],
quotes: ['error', 'single'],
semi: 'error',
strict: 'off',
'valid-typeof': 'error',
'react/jsx-boolean-value': 'error',
'react/jsx-closing-bracket-location': ['error', 'line-aligned'],
'react/jsx-curly-spacing': 'error',
'react/jsx-equals-spacing': 'error',
'react/jsx-first-prop-new-line': ['error', 'multiline-multiprop'],
'react/jsx-indent': ['error', 2],
'react/jsx-no-bind': 'error',
'react/jsx-no-duplicate-props': 'error',
'react/jsx-no-undef': 'error',
'react/jsx-tag-spacing': 'error',
'react/jsx-uses-react': 'error',
'react/jsx-uses-vars': 'error',
'react/jsx-wrap-multilines': 'error',
'react/no-multi-comp': 'off',
'react/no-string-refs': 'error',
'react/prop-types': 'error',
'react/self-closing-comp': 'error',
'jsx-a11y/accessible-emoji': 'warn',
'jsx-a11y/alt-text': 'warn',
'jsx-a11y/anchor-has-content': 'warn',
'jsx-a11y/anchor-is-valid': [
'warn',
{
components: [
'Link',
'NavLink',
],
specialLink: [
'to',
],
aspect: [
'noHref',
'invalidHref',
'preferButton',
],
},
],
'jsx-a11y/aria-activedescendant-has-tabindex': 'warn',
'jsx-a11y/aria-props': 'warn',
'jsx-a11y/aria-proptypes': 'warn',
'jsx-a11y/aria-role': 'warn',
'jsx-a11y/aria-unsupported-elements': 'warn',
'jsx-a11y/heading-has-content': 'warn',
'jsx-a11y/html-has-lang': 'warn',
'jsx-a11y/iframe-has-title': 'warn',
'jsx-a11y/img-redundant-alt': 'warn',
'jsx-a11y/interactive-supports-focus': 'warn',
'jsx-a11y/label-has-for': 'off',
'jsx-a11y/mouse-events-have-key-events': 'warn',
'jsx-a11y/no-access-key': 'warn',
'jsx-a11y/no-distracting-elements': 'warn',
'jsx-a11y/no-noninteractive-element-interactions': [
'warn',
{
handlers: [
'onClick',
],
},
],
'jsx-a11y/no-onchange': 'warn',
'jsx-a11y/no-redundant-roles': 'warn',
'jsx-a11y/no-static-element-interactions': [
'warn',
{
handlers: [
'onClick',
],
},
],
'jsx-a11y/role-has-required-aria-props': 'warn',
'jsx-a11y/role-supports-aria-props': 'off',
'jsx-a11y/scope': 'warn',
'jsx-a11y/tabindex-no-positive': 'warn',
'import/extensions': [
'error',
'always',
{
js: 'never',
},
],
'import/newline-after-import': 'error',
'import/no-extraneous-dependencies': [
'error',
{
devDependencies: [
'config/webpack/**',
'app/javascript/mastodon/test_setup.js',
'app/javascript/**/__tests__/**',
],
},
],
'import/no-unresolved': 'error',
'import/no-webpack-loader-syntax': 'error',
'promise/catch-or-return': 'error',
},
};

@ -1,177 +0,0 @@
---
root: true
env:
browser: true
node: true
es6: true
jest: true
globals:
ATTACHMENT_HOST: false
parser: babel-eslint
plugins:
- react
- jsx-a11y
- import
- promise
parserOptions:
sourceType: module
ecmaFeatures:
experimentalObjectRestSpread: true
jsx: true
ecmaVersion: 2018
settings:
react:
version: detect
import/extensions:
- .js
import/ignore:
- node_modules
- \\.(css|scss|json)$
import/resolver:
node:
moduleDirectory:
- node_modules
- app/javascript
rules:
brace-style: warn
comma-dangle:
- error
- always-multiline
comma-spacing:
- warn
- before: false
after: true
comma-style:
- warn
- last
consistent-return: error
dot-notation: error
eqeqeq: error
indent:
- warn
- 2
jsx-quotes:
- error
- prefer-single
no-catch-shadow: error
no-cond-assign: error
no-console:
- warn
- allow:
- error
- warn
no-fallthrough: error
no-irregular-whitespace: error
no-mixed-spaces-and-tabs: warn
no-nested-ternary: warn
no-trailing-spaces: warn
no-undef: error
no-unreachable: error
no-unused-expressions: error
no-unused-vars:
- error
- vars: all
args: after-used
ignoreRestSiblings: true
object-curly-spacing:
- error
- always
padded-blocks:
- error
- classes: always
quotes:
- error
- single
semi: error
strict: off
valid-typeof: error
react/jsx-boolean-value: error
react/jsx-closing-bracket-location:
- error
- line-aligned
react/jsx-curly-spacing: error
react/jsx-equals-spacing: error
react/jsx-first-prop-new-line:
- error
- multiline-multiprop
react/jsx-indent:
- error
- 2
react/jsx-no-bind: error
react/jsx-no-duplicate-props: error
react/jsx-no-undef: error
react/jsx-tag-spacing: error
react/jsx-uses-react: error
react/jsx-uses-vars: error
react/jsx-wrap-multilines: error
react/no-multi-comp: off
react/no-string-refs: error
react/prop-types: error
react/self-closing-comp: error
jsx-a11y/accessible-emoji: warn
jsx-a11y/alt-text: warn
jsx-a11y/anchor-has-content: warn
jsx-a11y/anchor-is-valid:
- warn
- components:
- Link
- NavLink
specialLink:
- to
aspect:
- noHref
- invalidHref
- preferButton
jsx-a11y/aria-activedescendant-has-tabindex: warn
jsx-a11y/aria-props: warn
jsx-a11y/aria-proptypes: warn
jsx-a11y/aria-role: warn
jsx-a11y/aria-unsupported-elements: warn
jsx-a11y/heading-has-content: warn
jsx-a11y/html-has-lang: warn
jsx-a11y/iframe-has-title: warn
jsx-a11y/img-redundant-alt: warn
jsx-a11y/interactive-supports-focus: warn
jsx-a11y/label-has-for: off
jsx-a11y/mouse-events-have-key-events: warn
jsx-a11y/no-access-key: warn
jsx-a11y/no-distracting-elements: warn
jsx-a11y/no-noninteractive-element-interactions:
- warn
- handlers:
- onClick
jsx-a11y/no-onchange: warn
jsx-a11y/no-redundant-roles: warn
jsx-a11y/no-static-element-interactions:
- warn
- handlers:
- onClick
jsx-a11y/role-has-required-aria-props: warn
jsx-a11y/role-supports-aria-props: off
jsx-a11y/scope: warn
jsx-a11y/tabindex-no-positive: warn
import/extensions:
- error
- always
- js: never
import/newline-after-import: error
import/no-extraneous-dependencies:
- error
- devDependencies:
- "config/webpack/**"
- "app/javascript/mastodon/test_setup.js"
- "app/javascript/**/__tests__/**"
import/no-unresolved: error
import/no-webpack-loader-syntax: error
promise/catch-or-return: error

@ -4,38 +4,38 @@ and provided thanks to the work of the following contributors:
* [Gargron](https://github.com/Gargron) * [Gargron](https://github.com/Gargron)
* [ykzts](https://github.com/ykzts) * [ykzts](https://github.com/ykzts)
* [akihikodaki](https://github.com/akihikodaki) * [akihikodaki](https://github.com/akihikodaki)
* [mjankowski](https://github.com/mjankowski)
* [ThibG](https://github.com/ThibG) * [ThibG](https://github.com/ThibG)
* [mjankowski](https://github.com/mjankowski)
* [unarist](https://github.com/unarist) * [unarist](https://github.com/unarist)
* [m4sk1n](https://github.com/m4sk1n) * [m4sk1n](https://github.com/m4sk1n)
* [dependabot[bot]](https://github.com/apps/dependabot)
* [yiskah](https://github.com/yiskah) * [yiskah](https://github.com/yiskah)
* [nolanlawson](https://github.com/nolanlawson) * [nolanlawson](https://github.com/nolanlawson)
* [sorin-davidoi](https://github.com/sorin-davidoi) * [sorin-davidoi](https://github.com/sorin-davidoi)
* [ysksn](https://github.com/ysksn)
* [abcang](https://github.com/abcang) * [abcang](https://github.com/abcang)
* [lynlynlynx](https://github.com/lynlynlynx) * [lynlynlynx](https://github.com/lynlynlynx)
* [dependabot[bot]](https://github.com/apps/dependabot)
* [alpaca-tc](https://github.com/alpaca-tc) * [alpaca-tc](https://github.com/alpaca-tc)
* [mayaeh](https://github.com/mayaeh)
* [renatolond](https://github.com/renatolond)
* [nclm](https://github.com/nclm) * [nclm](https://github.com/nclm)
* [ineffyble](https://github.com/ineffyble) * [ineffyble](https://github.com/ineffyble)
* [renatolond](https://github.com/renatolond)
* [jeroenpraat](https://github.com/jeroenpraat) * [jeroenpraat](https://github.com/jeroenpraat)
* [mayaeh](https://github.com/mayaeh)
* [blackle](https://github.com/blackle) * [blackle](https://github.com/blackle)
* [Quent-in](https://github.com/Quent-in) * [Quent-in](https://github.com/Quent-in)
* [JantsoP](https://github.com/JantsoP) * [JantsoP](https://github.com/JantsoP)
* [mabkenar](https://github.com/mabkenar)
* [nullkal](https://github.com/nullkal) * [nullkal](https://github.com/nullkal)
* [yookoala](https://github.com/yookoala) * [yookoala](https://github.com/yookoala)
* [mabkenar](https://github.com/mabkenar) * [Kjwon15](https://github.com/Kjwon15)
* [ysksn](https://github.com/ysksn)
* [shuheiktgw](https://github.com/shuheiktgw) * [shuheiktgw](https://github.com/shuheiktgw)
* [ashfurrow](https://github.com/ashfurrow) * [ashfurrow](https://github.com/ashfurrow)
* [Kjwon15](https://github.com/Kjwon15) * [Quenty31](https://github.com/Quenty31)
* [zunda](https://github.com/zunda) * [zunda](https://github.com/zunda)
* [eramdam](https://github.com/eramdam) * [eramdam](https://github.com/eramdam)
* [masarakki](https://github.com/masarakki)
* [takayamaki](https://github.com/takayamaki) * [takayamaki](https://github.com/takayamaki)
* [masarakki](https://github.com/masarakki)
* [ticky](https://github.com/ticky) * [ticky](https://github.com/ticky)
* [Quenty31](https://github.com/Quenty31)
* [danhunsaker](https://github.com/danhunsaker) * [danhunsaker](https://github.com/danhunsaker)
* [ThisIsMissEm](https://github.com/ThisIsMissEm) * [ThisIsMissEm](https://github.com/ThisIsMissEm)
* [hcmiya](https://github.com/hcmiya) * [hcmiya](https://github.com/hcmiya)
@ -88,16 +88,19 @@ and provided thanks to the work of the following contributors:
* [mistydemeo](https://github.com/mistydemeo) * [mistydemeo](https://github.com/mistydemeo)
* [dunn](https://github.com/dunn) * [dunn](https://github.com/dunn)
* [xqus](https://github.com/xqus) * [xqus](https://github.com/xqus)
* [hugogameiro](https://github.com/hugogameiro)
* [pfm-eyesightjp](https://github.com/pfm-eyesightjp) * [pfm-eyesightjp](https://github.com/pfm-eyesightjp)
* [fakenine](https://github.com/fakenine) * [fakenine](https://github.com/fakenine)
* [tsuwatch](https://github.com/tsuwatch) * [tsuwatch](https://github.com/tsuwatch)
* [victorhck](https://github.com/victorhck) * [victorhck](https://github.com/victorhck)
* [ashleyhull-versent](https://github.com/ashleyhull-versent)
* [kedamaDQ](https://github.com/kedamaDQ)
* [puckipedia](https://github.com/puckipedia) * [puckipedia](https://github.com/puckipedia)
* [fvh-P](https://github.com/fvh-P) * [fvh-P](https://github.com/fvh-P)
* [contraexemplo](https://github.com/contraexemplo) * [contraexemplo](https://github.com/contraexemplo)
* [hugogameiro](https://github.com/hugogameiro)
* [kazu9su](https://github.com/kazu9su) * [kazu9su](https://github.com/kazu9su)
* [Komic](https://github.com/Komic) * [Komic](https://github.com/Komic)
* [lmorchard](https://github.com/lmorchard)
* [diomed](https://github.com/diomed) * [diomed](https://github.com/diomed)
* [ariasuni](https://github.com/ariasuni) * [ariasuni](https://github.com/ariasuni)
* [Neetshin](mailto:neetshin@neetsh.in) * [Neetshin](mailto:neetshin@neetsh.in)
@ -105,7 +108,6 @@ and provided thanks to the work of the following contributors:
* [ProgVal](https://github.com/ProgVal) * [ProgVal](https://github.com/ProgVal)
* [valentin2105](https://github.com/valentin2105) * [valentin2105](https://github.com/valentin2105)
* [yuntan](https://github.com/yuntan) * [yuntan](https://github.com/yuntan)
* [ashleyhull-versent](https://github.com/ashleyhull-versent)
* [goofy-bz](mailto:goofy@babelzilla.org) * [goofy-bz](mailto:goofy@babelzilla.org)
* [kadiix](https://github.com/kadiix) * [kadiix](https://github.com/kadiix)
* [kodacs](https://github.com/kodacs) * [kodacs](https://github.com/kodacs)
@ -119,35 +121,37 @@ and provided thanks to the work of the following contributors:
* [northerner](https://github.com/northerner) * [northerner](https://github.com/northerner)
* [fhemberger](https://github.com/fhemberger) * [fhemberger](https://github.com/fhemberger)
* [greysteil](https://github.com/greysteil) * [greysteil](https://github.com/greysteil)
* [hnrysmth](https://github.com/hnrysmth) * [hensmith](https://github.com/hensmith)
* [hinaloe](https://github.com/hinaloe)
* [d6rkaiz](https://github.com/d6rkaiz) * [d6rkaiz](https://github.com/d6rkaiz)
* [Reverite](https://github.com/Reverite)
* [JMendyk](https://github.com/JMendyk) * [JMendyk](https://github.com/JMendyk)
* [JohnD28](https://github.com/JohnD28) * [JohnD28](https://github.com/JohnD28)
* [znz](https://github.com/znz) * [znz](https://github.com/znz)
* [Naouak](https://github.com/Naouak) * [Naouak](https://github.com/Naouak)
* [pawelngei](https://github.com/pawelngei)
* [reneklacan](https://github.com/reneklacan) * [reneklacan](https://github.com/reneklacan)
* [ekiru](https://github.com/ekiru) * [ekiru](https://github.com/ekiru)
* [tcitworld](https://github.com/tcitworld) * [tcitworld](https://github.com/tcitworld)
* [geta6](https://github.com/geta6) * [geta6](https://github.com/geta6)
* [happycoloredbanana](https://github.com/happycoloredbanana) * [happycoloredbanana](https://github.com/happycoloredbanana)
* [kedamaDQ](https://github.com/kedamaDQ)
* [leopku](https://github.com/leopku) * [leopku](https://github.com/leopku)
* [SansPseudoFix](https://github.com/SansPseudoFix) * [SansPseudoFix](https://github.com/SansPseudoFix)
* [tomfhowe](https://github.com/tomfhowe) * [tomfhowe](https://github.com/tomfhowe)
* [noraworld](https://github.com/noraworld) * [noraworld](https://github.com/noraworld)
* [theboss](https://github.com/theboss) * [theboss](https://github.com/theboss)
* [178inaba](https://github.com/178inaba) * [178inaba](https://github.com/178inaba)
* [Aditoo17](https://github.com/Aditoo17)
* [alyssais](https://github.com/alyssais) * [alyssais](https://github.com/alyssais)
* [kodnaplakal](https://github.com/kodnaplakal) * [kodnaplakal](https://github.com/kodnaplakal)
* [stalker314314](https://github.com/stalker314314) * [stalker314314](https://github.com/stalker314314)
* [huertanix](https://github.com/huertanix) * [huertanix](https://github.com/huertanix)
* [genesixx](https://github.com/genesixx) * [genesixx](https://github.com/genesixx)
* [halkeye](https://github.com/halkeye) * [halkeye](https://github.com/halkeye)
* [hinaloe](https://github.com/hinaloe)
* [treby](https://github.com/treby) * [treby](https://github.com/treby)
* [Reverite](https://github.com/Reverite)
* [jpdevries](https://github.com/jpdevries) * [jpdevries](https://github.com/jpdevries)
* [H-C-F](https://github.com/H-C-F) * [gdpelican](https://github.com/gdpelican)
* [kmichl](https://github.com/kmichl)
* [Kurtis Rainbolt-Greene](mailto:me@kurtisrainboltgreene.name) * [Kurtis Rainbolt-Greene](mailto:me@kurtisrainboltgreene.name)
* [saper](https://github.com/saper) * [saper](https://github.com/saper)
* [nevillepark](https://github.com/nevillepark) * [nevillepark](https://github.com/nevillepark)
@ -157,6 +161,7 @@ and provided thanks to the work of the following contributors:
* [Ram Lmn](mailto:ramlmn@users.noreply.github.com) * [Ram Lmn](mailto:ramlmn@users.noreply.github.com)
* [harukasan](https://github.com/harukasan) * [harukasan](https://github.com/harukasan)
* [stamak](https://github.com/stamak) * [stamak](https://github.com/stamak)
* [noellabo](https://github.com/noellabo)
* [Technowix](mailto:technowix@users.noreply.github.com) * [Technowix](mailto:technowix@users.noreply.github.com)
* [Eychics](https://github.com/Eychics) * [Eychics](https://github.com/Eychics)
* [Thor Harald Johansen](mailto:thj@thj.no) * [Thor Harald Johansen](mailto:thj@thj.no)
@ -165,22 +170,27 @@ and provided thanks to the work of the following contributors:
* [Valentin_NC](mailto:valentin.ouvrard@nautile.sarl) * [Valentin_NC](mailto:valentin.ouvrard@nautile.sarl)
* [R0ckweb](https://github.com/R0ckweb) * [R0ckweb](https://github.com/R0ckweb)
* [caasi](https://github.com/caasi) * [caasi](https://github.com/caasi)
* [chr-1x](https://github.com/chr-1x)
* [esetomo](https://github.com/esetomo) * [esetomo](https://github.com/esetomo)
* [foxiehkins](https://github.com/foxiehkins) * [foxiehkins](https://github.com/foxiehkins)
* [hoodie](mailto:hoodiekitten@outlook.com) * [hoodie](mailto:hoodiekitten@outlook.com)
* [luzi82](https://github.com/luzi82) * [luzi82](https://github.com/luzi82)
* [duxovni](https://github.com/duxovni) * [duxovni](https://github.com/duxovni)
* [trwnh](https://github.com/trwnh)
* [unsmell](https://github.com/unsmell) * [unsmell](https://github.com/unsmell)
* [valerauko](https://github.com/valerauko)
* [chriswmartin](https://github.com/chriswmartin) * [chriswmartin](https://github.com/chriswmartin)
* [vahnj](https://github.com/vahnj) * [vahnj](https://github.com/vahnj)
* [ikuradon](https://github.com/ikuradon) * [ikuradon](https://github.com/ikuradon)
* [AndreLewin](https://github.com/AndreLewin) * [AndreLewin](https://github.com/AndreLewin)
* [rinsuki](https://github.com/rinsuki) * [rinsuki](https://github.com/rinsuki)
* [0xflotus](https://github.com/0xflotus)
* [redtachyons](https://github.com/redtachyons) * [redtachyons](https://github.com/redtachyons)
* [thurloat](https://github.com/thurloat) * [thurloat](https://github.com/thurloat)
* [aaribaud](https://github.com/aaribaud) * [aaribaud](https://github.com/aaribaud)
* [Andrew](mailto:andrewlchronister@gmail.com) * [Andrew](mailto:andrewlchronister@gmail.com)
* [estuans](https://github.com/estuans) * [estuans](https://github.com/estuans)
* [BenLubar](https://github.com/BenLubar)
* [dissolve](https://github.com/dissolve) * [dissolve](https://github.com/dissolve)
* [PurpleBooth](https://github.com/PurpleBooth) * [PurpleBooth](https://github.com/PurpleBooth)
* [bradurani](https://github.com/bradurani) * [bradurani](https://github.com/bradurani)
@ -192,7 +202,7 @@ and provided thanks to the work of the following contributors:
* [cdutson](https://github.com/cdutson) * [cdutson](https://github.com/cdutson)
* [farlistener](https://github.com/farlistener) * [farlistener](https://github.com/farlistener)
* [DavidLibeau](https://github.com/DavidLibeau) * [DavidLibeau](https://github.com/DavidLibeau)
* [SirCmpwn](https://github.com/SirCmpwn) * [ddevault](https://github.com/ddevault)
* [Fjoerfoks](https://github.com/Fjoerfoks) * [Fjoerfoks](https://github.com/Fjoerfoks)
* [fmauNeko](https://github.com/fmauNeko) * [fmauNeko](https://github.com/fmauNeko)
* [gloaec](https://github.com/gloaec) * [gloaec](https://github.com/gloaec)
@ -207,6 +217,7 @@ and provided thanks to the work of the following contributors:
* [jasonrhodes](https://github.com/jasonrhodes) * [jasonrhodes](https://github.com/jasonrhodes)
* [Jason Snell](mailto:jason@newrelic.com) * [Jason Snell](mailto:jason@newrelic.com)
* [jviide](https://github.com/jviide) * [jviide](https://github.com/jviide)
* [YuleZ](https://github.com/YuleZ)
* [crakaC](https://github.com/crakaC) * [crakaC](https://github.com/crakaC)
* [tkbky](https://github.com/tkbky) * [tkbky](https://github.com/tkbky)
* [Kaylee](mailto:kaylee@codethat.sucks) * [Kaylee](mailto:kaylee@codethat.sucks)
@ -223,10 +234,12 @@ and provided thanks to the work of the following contributors:
* [petzah](https://github.com/petzah) * [petzah](https://github.com/petzah)
* [ignisf](https://github.com/ignisf) * [ignisf](https://github.com/ignisf)
* [raymestalez](https://github.com/raymestalez) * [raymestalez](https://github.com/raymestalez)
* [remram44](https://github.com/remram44)
* [sascha-sl](https://github.com/sascha-sl) * [sascha-sl](https://github.com/sascha-sl)
* [u1-liquid](https://github.com/u1-liquid) * [u1-liquid](https://github.com/u1-liquid)
* [sim6](https://github.com/sim6) * [sim6](https://github.com/sim6)
* [stemid](https://github.com/stemid) * [stemid](https://github.com/stemid)
* [sumdog](https://github.com/sumdog)
* [ThomasLeister](https://github.com/ThomasLeister) * [ThomasLeister](https://github.com/ThomasLeister)
* [mcat-ee](https://github.com/mcat-ee) * [mcat-ee](https://github.com/mcat-ee)
* [tototoshi](https://github.com/tototoshi) * [tototoshi](https://github.com/tototoshi)
@ -243,7 +256,6 @@ and provided thanks to the work of the following contributors:
* [aus-social](https://github.com/aus-social) * [aus-social](https://github.com/aus-social)
* [imbsky](https://github.com/imbsky) * [imbsky](https://github.com/imbsky)
* [bsky](mailto:me@imbsky.net) * [bsky](mailto:me@imbsky.net)
* [chr-1x](https://github.com/chr-1x)
* [codl](https://github.com/codl) * [codl](https://github.com/codl)
* [cpsdqs](https://github.com/cpsdqs) * [cpsdqs](https://github.com/cpsdqs)
* [barzamin](https://github.com/barzamin) * [barzamin](https://github.com/barzamin)
@ -252,6 +264,7 @@ and provided thanks to the work of the following contributors:
* [ik11235](https://github.com/ik11235) * [ik11235](https://github.com/ik11235)
* [kawax](https://github.com/kawax) * [kawax](https://github.com/kawax)
* [007lva](https://github.com/007lva) * [007lva](https://github.com/007lva)
* [mbajur](https://github.com/mbajur)
* [matsurai25](https://github.com/matsurai25) * [matsurai25](https://github.com/matsurai25)
* [mecab](https://github.com/mecab) * [mecab](https://github.com/mecab)
* [nicobz25](https://github.com/nicobz25) * [nicobz25](https://github.com/nicobz25)
@ -259,7 +272,6 @@ and provided thanks to the work of the following contributors:
* [pinfort](https://github.com/pinfort) * [pinfort](https://github.com/pinfort)
* [rbaumert](https://github.com/rbaumert) * [rbaumert](https://github.com/rbaumert)
* [rhoio](https://github.com/rhoio) * [rhoio](https://github.com/rhoio)
* [trwnh](https://github.com/trwnh)
* [usagi-f](https://github.com/usagi-f) * [usagi-f](https://github.com/usagi-f)
* [vidarlee](https://github.com/vidarlee) * [vidarlee](https://github.com/vidarlee)
* [vjackson725](https://github.com/vjackson725) * [vjackson725](https://github.com/vjackson725)
@ -269,11 +281,11 @@ and provided thanks to the work of the following contributors:
* [Awea](https://github.com/Awea) * [Awea](https://github.com/Awea)
* [halcy](https://github.com/halcy) * [halcy](https://github.com/halcy)
* [naaaaaaaaaaaf](https://github.com/naaaaaaaaaaaf) * [naaaaaaaaaaaf](https://github.com/naaaaaaaaaaaf)
* [NecroTechno](https://github.com/NecroTechno)
* [8398a7](https://github.com/8398a7) * [8398a7](https://github.com/8398a7)
* [857b](https://github.com/857b) * [857b](https://github.com/857b)
* [insom](https://github.com/insom) * [insom](https://github.com/insom)
* [Aditoo17](https://github.com/Aditoo17) * [tachyons](https://github.com/tachyons)
* [Esteth](https://github.com/Esteth)
* [unascribed](https://github.com/unascribed) * [unascribed](https://github.com/unascribed)
* [Aguay-val](https://github.com/Aguay-val) * [Aguay-val](https://github.com/Aguay-val)
* [Akihiko Odaki](mailto:nekomanma@pixiv.co.jp) * [Akihiko Odaki](mailto:nekomanma@pixiv.co.jp)
@ -283,6 +295,7 @@ and provided thanks to the work of the following contributors:
* [alxrcs](https://github.com/alxrcs) * [alxrcs](https://github.com/alxrcs)
* [console-cowboy](https://github.com/console-cowboy) * [console-cowboy](https://github.com/console-cowboy)
* [pointlessone](https://github.com/pointlessone) * [pointlessone](https://github.com/pointlessone)
* [Alkarex](https://github.com/Alkarex)
* [a2](https://github.com/a2) * [a2](https://github.com/a2)
* [0xa](https://github.com/0xa) * [0xa](https://github.com/0xa)
* [palindromordnilap](https://github.com/palindromordnilap) * [palindromordnilap](https://github.com/palindromordnilap)
@ -299,7 +312,6 @@ and provided thanks to the work of the following contributors:
* [ayumin](https://github.com/ayumin) * [ayumin](https://github.com/ayumin)
* [BaptisteGelez](https://github.com/BaptisteGelez) * [BaptisteGelez](https://github.com/BaptisteGelez)
* [bzg](https://github.com/bzg) * [bzg](https://github.com/bzg)
* [BenLubar](https://github.com/BenLubar)
* [benediktg](https://github.com/benediktg) * [benediktg](https://github.com/benediktg)
* [blakebarnett](https://github.com/blakebarnett) * [blakebarnett](https://github.com/blakebarnett)
* [bradj](https://github.com/bradj) * [bradj](https://github.com/bradj)
@ -341,6 +353,7 @@ and provided thanks to the work of the following contributors:
* [espenronnevik](https://github.com/espenronnevik) * [espenronnevik](https://github.com/espenronnevik)
* [Finariel](https://github.com/Finariel) * [Finariel](https://github.com/Finariel)
* [siuying](https://github.com/siuying) * [siuying](https://github.com/siuying)
* [fwenzel](https://github.com/fwenzel)
* [GenbuHase](https://github.com/GenbuHase) * [GenbuHase](https://github.com/GenbuHase)
* [hattori6789](https://github.com/hattori6789) * [hattori6789](https://github.com/hattori6789)
* [algernon](https://github.com/algernon) * [algernon](https://github.com/algernon)
@ -375,10 +388,9 @@ and provided thanks to the work of the following contributors:
* [jguerder](https://github.com/jguerder) * [jguerder](https://github.com/jguerder)
* [Jehops](https://github.com/Jehops) * [Jehops](https://github.com/Jehops)
* [joshuap](https://github.com/joshuap) * [joshuap](https://github.com/joshuap)
* [YuleZ](https://github.com/YuleZ)
* [Tiwy57](https://github.com/Tiwy57) * [Tiwy57](https://github.com/Tiwy57)
* [xuv](https://github.com/xuv) * [xuv](https://github.com/xuv)
* [Jnsll](https://github.com/Jnsll) * [June Sallou](mailto:jnsll@users.noreply.github.com)
* [j0k3r](https://github.com/j0k3r) * [j0k3r](https://github.com/j0k3r)
* [KEINOS](https://github.com/KEINOS) * [KEINOS](https://github.com/KEINOS)
* [futoase](https://github.com/futoase) * [futoase](https://github.com/futoase)
@ -389,7 +401,6 @@ and provided thanks to the work of the following contributors:
* [k0ta0uchi](https://github.com/k0ta0uchi) * [k0ta0uchi](https://github.com/k0ta0uchi)
* [KrzysiekJ](https://github.com/KrzysiekJ) * [KrzysiekJ](https://github.com/KrzysiekJ)
* [leowzukw](https://github.com/leowzukw) * [leowzukw](https://github.com/leowzukw)
* [lmorchard](https://github.com/lmorchard)
* [Tak](https://github.com/Tak) * [Tak](https://github.com/Tak)
* [cacheflow](https://github.com/cacheflow) * [cacheflow](https://github.com/cacheflow)
* [ldidry](https://github.com/ldidry) * [ldidry](https://github.com/ldidry)
@ -426,6 +437,7 @@ and provided thanks to the work of the following contributors:
* [lae](https://github.com/lae) * [lae](https://github.com/lae)
* [Nanamachi](https://github.com/Nanamachi) * [Nanamachi](https://github.com/Nanamachi)
* [orinthe](https://github.com/orinthe) * [orinthe](https://github.com/orinthe)
* [NecroTechno](https://github.com/NecroTechno)
* [Dar13](https://github.com/Dar13) * [Dar13](https://github.com/Dar13)
* [ngerakines](https://github.com/ngerakines) * [ngerakines](https://github.com/ngerakines)
* [vonneudeck](https://github.com/vonneudeck) * [vonneudeck](https://github.com/vonneudeck)
@ -443,7 +455,6 @@ and provided thanks to the work of the following contributors:
* [Pangoraw](https://github.com/Pangoraw) * [Pangoraw](https://github.com/Pangoraw)
* [peterkeen](https://github.com/peterkeen) * [peterkeen](https://github.com/peterkeen)
* [pgate](https://github.com/pgate) * [pgate](https://github.com/pgate)
* [remram44](https://github.com/remram44)
* [retokromer](https://github.com/retokromer) * [retokromer](https://github.com/retokromer)
* [rfwatson](https://github.com/rfwatson) * [rfwatson](https://github.com/rfwatson)
* [rfreebern](https://github.com/rfreebern) * [rfreebern](https://github.com/rfreebern)
@ -455,19 +466,22 @@ and provided thanks to the work of the following contributors:
* [sts10](https://github.com/sts10) * [sts10](https://github.com/sts10)
* [skoji](https://github.com/skoji) * [skoji](https://github.com/skoji)
* [ScienJus](https://github.com/ScienJus) * [ScienJus](https://github.com/ScienJus)
* [larkinscott](https://github.com/larkinscott) * [Scott Larkin](mailto:scott@codeclimate.com)
* [imolein](https://github.com/imolein) * [Sebastian Hübner](mailto:imolein@users.noreply.github.com)
* [blinry](https://github.com/blinry) * [Sebastian Morr](mailto:sebastian@morr.cc)
* [Noiwex](https://github.com/Noiwex) * [Sergei Č](mailto:noiwex1911@gmail.com)
* [yuki764](https://github.com/yuki764) * [Setuu](mailto:yuki764setuu@gmail.com)
* [shnjp](https://github.com/shnjp) * [Shaun Gillies](mailto:me@shaungillies.net)
* [ernix](https://github.com/ernix) * [Shin Adachi](mailto:shn@glucose.jp)
* [rosylilly](https://github.com/rosylilly) * [Shin Kojima](mailto:shin@kojima.org)
* [shouko](https://github.com/shouko) * [Sho Kusano](mailto:rosylilly@aduca.org)
* [Shouko Yu](mailto:imshouko@gmail.com)
* [Sina Mashek](mailto:sina@mashek.xyz) * [Sina Mashek](mailto:sina@mashek.xyz)
* [sossii](https://github.com/sossii) * [Sir-Boops](mailto:admin@boops.me)
* [Soshi Kato](mailto:mail@sossii.com)
* [Spanky](mailto:2788886+spankyworks@users.noreply.github.com) * [Spanky](mailto:2788886+spankyworks@users.noreply.github.com)
* [StefOfficiel](mailto:pichard.stephane@free.fr) * [StefOfficiel](mailto:pichard.stephane@free.fr)
* [Steven Tappert](mailto:admin@dark-it.net)
* [Svetlozar Todorov](mailto:svetlik@users.noreply.github.com) * [Svetlozar Todorov](mailto:svetlik@users.noreply.github.com)
* [Sébastien Santoro](mailto:dereckson@espace-win.org) * [Sébastien Santoro](mailto:dereckson@espace-win.org)
* [Tad Thorley](mailto:phaedryx@users.noreply.github.com) * [Tad Thorley](mailto:phaedryx@users.noreply.github.com)
@ -521,11 +535,13 @@ and provided thanks to the work of the following contributors:
* [jacob](mailto:jacobherringtondeveloper@gmail.com) * [jacob](mailto:jacobherringtondeveloper@gmail.com)
* [jenn kaplan](mailto:me@jkap.io) * [jenn kaplan](mailto:me@jkap.io)
* [jirayudech](mailto:jirayudech@gmail.com) * [jirayudech](mailto:jirayudech@gmail.com)
* [jomo](mailto:github@jomo.tv)
* [jooops](mailto:joops@autistici.org) * [jooops](mailto:joops@autistici.org)
* [jukper](mailto:jukkaperanto@gmail.com) * [jukper](mailto:jukkaperanto@gmail.com)
* [jumoru](mailto:jumoru@mailbox.org) * [jumoru](mailto:jumoru@mailbox.org)
* [karlyeurl](mailto:karl.yeurl@gmail.com) * [karlyeurl](mailto:karl.yeurl@gmail.com)
* [kedama](mailto:32974885+kedamadq@users.noreply.github.com) * [kedama](mailto:32974885+kedamadq@users.noreply.github.com)
* [kodai](mailto:shirafuta.kodai@gmail.com)
* [kuro5hin](mailto:rusty@kuro5hin.org) * [kuro5hin](mailto:rusty@kuro5hin.org)
* [luzpaz](mailto:luzpaz@users.noreply.github.com) * [luzpaz](mailto:luzpaz@users.noreply.github.com)
* [maxypy](mailto:maxime@mpigou.fr) * [maxypy](mailto:maxime@mpigou.fr)
@ -533,6 +549,7 @@ and provided thanks to the work of the following contributors:
* [mimikun](mailto:dzdzble_effort_311@outlook.jp) * [mimikun](mailto:dzdzble_effort_311@outlook.jp)
* [mshrtkch](mailto:mshrtkch@users.noreply.github.com) * [mshrtkch](mailto:mshrtkch@users.noreply.github.com)
* [muan](mailto:muan@github.com) * [muan](mailto:muan@github.com)
* [namelessGonbai](mailto:43787036+namelessgonbai@users.noreply.github.com)
* [neetshin](mailto:neetshin@neetsh.in) * [neetshin](mailto:neetshin@neetsh.in)
* [nightpool](mailto:nightpool@users.noreply.github.com) * [nightpool](mailto:nightpool@users.noreply.github.com)
* [rch850](mailto:rich850@gmail.com) * [rch850](mailto:rich850@gmail.com)

@ -3,6 +3,111 @@ Changelog
All notable changes to this project will be documented in this file. All notable changes to this project will be documented in this file.
## [Unreleased]
### Added
- Add link for adding a user to a list from their profile (#9062)
- Add joining several hashtags in a single column (#8904)
- Add volume sliders for videos (#9366)
- Add a tooltip explaining what a locked account is (#9403)
- Add preloaded cache for common JSON-LD contexts (#9412)
- Add profile directory (#9427)
- Add setting to not group reblogs in home feed (#9248)
- Add admin ability to remove a user's header image (#9495)
- Add account hashtags to ActivityPub actor JSON (#9450)
- Add error message for avatar image that's too large (#9518)
- Add notification quick-filter bar (#9399)
- Add new first-time tutorial (#9531)
- Add moderation warnings (#9519)
- Add emoji codepoint mappings for v11.0 (#9618)
- Add REST API for creating an account (#9572)
- Add support for Malayalam in language filter (#9624)
- Add exclude_reblogs option to account statuses API (#9640)
- Add local followers page to admin account UI (#9610)
- Add healthcheck commands to docker-compose.yml (#9143)
- Add handler for Move activity to migrate followers (#9629)
- Add CSV export for lists and domain blocks (#9677)
- Add `tootctl accounts follow ACCT` (#9414)
- Add scheduled statuses (#9706)
- Add immutable caching for S3 objects (#9722)
- Add cache to custom emojis API (#9732)
- Add preview cards to non-detailed statuses on public pages (#9714)
- Add `mod` and `moderator` to list of default reserved usernames (#9713)
- Add quick links to the admin interface in the web UI (#8545)
### Changed
- Temporarily pause timeline if mouse moved recently (#9200)
- Change the password form order (#9267)
- Redesign admin UI for accounts (#9340, #9643)
- Redesign admin UI for instances/domain blocks (#9645)
- Swap avatar and header input fields in profile page (#9271)
- When posting in mobile mode, go back to previous history location (#9502)
- Split out is_changing_upload from is_submitting (#9536)
- Back to the getting-started when pins the timeline. (#9561)
- Allow unauthenticated REST API access to GET /api/v1/accounts/:id/statuses (#9573)
- Limit maximum visibility of local silenced users to unlisted (#9583)
- Change API error message for unconfirmed accounts (#9625)
- Change the icon to "reply-all" when it's a reply to other accounts (#9378)
- Do not ignore federated reports targetting already-reported accounts (#9534)
- Upgrade default Ruby version to 2.6.0 (#9688)
- Change e-mail digest frequency (#9689)
- Change Docker images for Tor support in docker-compose.yml (#9438)
- Display fallback link card thumbnail when none is given (#9715)
- Change account bio length validation to ignore mention domains and URLs (#9717)
- Use configured contact user for "anonymous" federation activities (#9661)
- Change remote interaction dialog to use specific actions instead of generic "interact" (#9743)
- Always re-fetch public key when signature verification fails to support blind key rotation (#9667)
- Make replies to boosts impossible, connect reply to original status instead (#9129)
- Change e-mail MX validation to check both A and MX records against blacklist (#9489)
### Removed
- Remove links to bridge.joinmastodon.org (non-functional) (#9608)
- Remove LD-Signatures from activities that do not need them (#9659)
### Fixed
- Remove unused computation of reblog references from updateTimeline (#9244)
- Fix loaded embeds resetting if a status arrives from API again (#9270)
- Fix race condition causing shallow status with only a "favourited" attribute (#9272)
- Remove intermediary arrays when creating hash maps from results (#9291)
- Extract counters from accounts table to account_stats table to improve performance (#9295)
- Change identities id column to a bigint (#9371)
- Fix conversations API pagination (#9407)
- Improve account suspension speed and completeness (#9290)
- Fix thread depth computation in statuses_controller (#9426)
- Fix database deadlocks by moving account stats update outside transaction (#9437)
- Escape HTML in profile name preview in profile settings (#9446)
- Use same CORS policy for /@:username and /users/:username (#9485)
- Make custom emoji domains case insensitive (#9474)
- Various fixes to scrollable lists and media gallery (#9501)
- Fix bootsnap cache directory being declared relatively (#9511)
- Fix timeline pagination in the web UI (#9516)
- Fix padding on dropdown elements in preferences (#9517)
- Make avatar and headers respect GIF autoplay settings (#9515)
- Do no retry Web Push workers if the server returns a 4xx response (#9434)
- Minor scrollable list fixes (#9551)
- Ignore low-confidence CharlockHolmes guesses when parsing link cards (#9510)
- Fix `tootctl accounts rotate` not updating public keys (#9556)
- Fix CSP / X-Frame-Options for media players (#9558)
- Fix unnecessary loadMore calls when the end of a timeline has been reached (#9581)
- Skip mailer job retries when a record no longer exists (#9590)
- Fix composer not getting focus after reply confirmation dialog (#9602)
- Fix signature verification stoplight triggering on non-timeout errors (#9617)
- Fix ThreadResolveWorker getting queued with invalid URLs (#9628)
- Fix crash when clearing uninitialized timeline (#9662)
- Avoid duplicate work by merging ReplyDistributionWorker into DistributionWorker (#9660)
- Skip full text search if it fails, instead of erroring out completely (#9654)
- Fix profile metadata links not verifying correctly sometimes (#9673)
- Ensure blocked user unfollows blocker if Block/Undo-Block activities are processed out of order (#9687)
- Fix unreadable text color in report modal for some statuses (#9716)
- Stop GIFV timeline preview explicitly when it's opened in modal (#9749)
### Security
- Sanitize and sandbox toot embeds in web UI (#9552)
## [2.6.5] - 2018-12-01 ## [2.6.5] - 2018-12-01
### Changed ### Changed

@ -53,12 +53,12 @@ gem 'htmlentities', '~> 4.3'
gem 'http', '~> 3.3' gem 'http', '~> 3.3'
gem 'http_accept_language', '~> 2.1' gem 'http_accept_language', '~> 2.1'
gem 'http_parser.rb', '~> 0.6', git: 'https://github.com/tmm1/http_parser.rb', ref: '54b17ba8c7d8d20a16dfc65d1775241833219cf2' gem 'http_parser.rb', '~> 0.6', git: 'https://github.com/tmm1/http_parser.rb', ref: '54b17ba8c7d8d20a16dfc65d1775241833219cf2'
gem 'httplog', '~> 1.1' gem 'httplog', '~> 1.2'
gem 'idn-ruby', require: 'idn' gem 'idn-ruby', require: 'idn'
gem 'kaminari', '~> 1.1' gem 'kaminari', '~> 1.1'
gem 'link_header', '~> 0.0' gem 'link_header', '~> 0.0'
gem 'mime-types', '~> 3.2', require: 'mime/types/columnar' gem 'mime-types', '~> 3.2', require: 'mime/types/columnar'
gem 'nokogiri', '~> 1.9' gem 'nokogiri', '~> 1.10'
gem 'nsa', '~> 0.2' gem 'nsa', '~> 0.2'
gem 'oj', '~> 3.7' gem 'oj', '~> 3.7'
gem 'ostatus2', '~> 2.0' gem 'ostatus2', '~> 2.0'
@ -128,7 +128,7 @@ group :development do
gem 'letter_opener', '~> 1.7' gem 'letter_opener', '~> 1.7'
gem 'letter_opener_web', '~> 1.3' gem 'letter_opener_web', '~> 1.3'
gem 'memory_profiler' gem 'memory_profiler'
gem 'rubocop', '~> 0.61', require: false gem 'rubocop', '~> 0.62', require: false
gem 'brakeman', '~> 4.3', require: false gem 'brakeman', '~> 4.3', require: false
gem 'bundler-audit', '~> 0.6', require: false gem 'bundler-audit', '~> 0.6', require: false
gem 'scss_lint', '~> 0.57', require: false gem 'scss_lint', '~> 0.57', require: false

@ -268,7 +268,7 @@ GEM
domain_name (~> 0.5) domain_name (~> 0.5)
http-form_data (2.1.1) http-form_data (2.1.1)
http_accept_language (2.1.1) http_accept_language (2.1.1)
httplog (1.1.1) httplog (1.2.0)
rack (>= 1.0) rack (>= 1.0)
rainbow (>= 2.0.0) rainbow (>= 2.0.0)
i18n (1.1.1) i18n (1.1.1)
@ -356,7 +356,7 @@ GEM
net-ssh (>= 2.6.5) net-ssh (>= 2.6.5)
net-ssh (5.0.2) net-ssh (5.0.2)
nio4r (2.3.1) nio4r (2.3.1)
nokogiri (1.9.1) nokogiri (1.10.0)
mini_portile2 (~> 2.4.0) mini_portile2 (~> 2.4.0)
nokogumbo (2.0.0) nokogumbo (2.0.0)
nokogiri (~> 1.8, >= 1.8.4) nokogiri (~> 1.8, >= 1.8.4)
@ -365,7 +365,7 @@ GEM
concurrent-ruby (~> 1.0.0) concurrent-ruby (~> 1.0.0)
sidekiq (>= 3.5.0) sidekiq (>= 3.5.0)
statsd-ruby (~> 1.2.0) statsd-ruby (~> 1.2.0)
oj (3.7.4) oj (3.7.6)
omniauth (1.9.0) omniauth (1.9.0)
hashie (>= 3.4.6, < 3.7.0) hashie (>= 3.4.6, < 3.7.0)
rack (>= 1.6.2, < 3) rack (>= 1.6.2, < 3)
@ -392,7 +392,7 @@ GEM
av (~> 0.9.0) av (~> 0.9.0)
paperclip (>= 2.5.2) paperclip (>= 2.5.2)
parallel (1.12.1) parallel (1.12.1)
parallel_tests (2.27.0) parallel_tests (2.27.1)
parallel parallel
parser (2.5.3.0) parser (2.5.3.0)
ast (~> 2.4.0) ast (~> 2.4.0)
@ -418,7 +418,7 @@ GEM
pry-byebug (3.6.0) pry-byebug (3.6.0)
byebug (~> 10.0) byebug (~> 10.0)
pry (~> 0.10) pry (~> 0.10)
pry-rails (0.3.8) pry-rails (0.3.9)
pry (>= 0.10.4) pry (>= 0.10.4)
public_suffix (3.0.3) public_suffix (3.0.3)
puma (3.12.0) puma (3.12.0)
@ -527,7 +527,7 @@ GEM
rspec-core (~> 3.0, >= 3.0.0) rspec-core (~> 3.0, >= 3.0.0)
sidekiq (>= 2.4.0) sidekiq (>= 2.4.0)
rspec-support (3.8.0) rspec-support (3.8.0)
rubocop (0.61.1) rubocop (0.62.0)
jaro_winkler (~> 1.5.1) jaro_winkler (~> 1.5.1)
parallel (~> 1.10) parallel (~> 1.10)
parser (>= 2.5, != 2.5.1.1) parser (>= 2.5, != 2.5.1.1)
@ -607,7 +607,7 @@ GEM
tty-command (0.8.2) tty-command (0.8.2)
pastel (~> 0.7.0) pastel (~> 0.7.0)
tty-cursor (0.6.0) tty-cursor (0.6.0)
tty-prompt (0.18.0) tty-prompt (0.18.1)
necromancer (~> 0.4.0) necromancer (~> 0.4.0)
pastel (~> 0.7.0) pastel (~> 0.7.0)
timers (~> 4.0) timers (~> 4.0)
@ -622,12 +622,12 @@ GEM
unf (~> 0.1.0) unf (~> 0.1.0)
tzinfo (1.2.5) tzinfo (1.2.5)
thread_safe (~> 0.1) thread_safe (~> 0.1)
tzinfo-data (1.2018.7) tzinfo-data (1.2018.9)
tzinfo (>= 1.0.0) tzinfo (>= 1.0.0)
unf (0.1.4) unf (0.1.4)
unf_ext unf_ext
unf_ext (0.0.7.5) unf_ext (0.0.7.5)
unicode-display_width (1.4.0) unicode-display_width (1.4.1)
uniform_notifier (1.12.1) uniform_notifier (1.12.1)
warden (1.2.7) warden (1.2.7)
rack (>= 1.0) rack (>= 1.0)
@ -639,7 +639,7 @@ GEM
activesupport (>= 4.2) activesupport (>= 4.2)
rack-proxy (>= 0.6.1) rack-proxy (>= 0.6.1)
railties (>= 4.2) railties (>= 4.2)
webpush (0.3.4) webpush (0.3.5)
hkdf (~> 0.2) hkdf (~> 0.2)
jwt (~> 2.0) jwt (~> 2.0)
websocket-driver (0.7.0) websocket-driver (0.7.0)
@ -695,7 +695,7 @@ DEPENDENCIES
http (~> 3.3) http (~> 3.3)
http_accept_language (~> 2.1) http_accept_language (~> 2.1)
http_parser.rb (~> 0.6)! http_parser.rb (~> 0.6)!
httplog (~> 1.1) httplog (~> 1.2)
i18n-tasks (~> 0.9) i18n-tasks (~> 0.9)
idn-ruby idn-ruby
iso-639 iso-639
@ -712,7 +712,7 @@ DEPENDENCIES
microformats (~> 4.0) microformats (~> 4.0)
mime-types (~> 3.2) mime-types (~> 3.2)
net-ldap (~> 0.10) net-ldap (~> 0.10)
nokogiri (~> 1.9) nokogiri (~> 1.10)
nsa (~> 0.2) nsa (~> 0.2)
oj (~> 3.7) oj (~> 3.7)
omniauth (~> 1.9) omniauth (~> 1.9)
@ -746,7 +746,7 @@ DEPENDENCIES
rqrcode (~> 0.10) rqrcode (~> 0.10)
rspec-rails (~> 3.8) rspec-rails (~> 3.8)
rspec-sidekiq (~> 3.0) rspec-sidekiq (~> 3.0)
rubocop (~> 0.61) rubocop (~> 0.62)
sanitize (~> 5.0) sanitize (~> 5.0)
scss_lint (~> 0.57) scss_lint (~> 0.57)
sidekiq (~> 5.2) sidekiq (~> 5.2)

@ -4,14 +4,9 @@ module Admin
class DomainBlocksController < BaseController class DomainBlocksController < BaseController
before_action :set_domain_block, only: [:show, :destroy] before_action :set_domain_block, only: [:show, :destroy]
def index
authorize :domain_block, :index?
@domain_blocks = DomainBlock.page(params[:page])
end
def new def new
authorize :domain_block, :create? authorize :domain_block, :create?
@domain_block = DomainBlock.new @domain_block = DomainBlock.new(domain: params[:_domain])
end end
def create def create
@ -22,7 +17,7 @@ module Admin
if @domain_block.save if @domain_block.save
DomainBlockWorker.perform_async(@domain_block.id) DomainBlockWorker.perform_async(@domain_block.id)
log_action :create, @domain_block log_action :create, @domain_block
redirect_to admin_domain_blocks_path, notice: I18n.t('admin.domain_blocks.created_msg') redirect_to admin_instances_path(limited: '1'), notice: I18n.t('admin.domain_blocks.created_msg')
else else
render :new render :new
end end
@ -36,7 +31,7 @@ module Admin
authorize @domain_block, :destroy? authorize @domain_block, :destroy?
UnblockDomainService.new.call(@domain_block, retroactive_unblock?) UnblockDomainService.new.call(@domain_block, retroactive_unblock?)
log_action :destroy, @domain_block log_action :destroy, @domain_block
redirect_to admin_domain_blocks_path, notice: I18n.t('admin.domain_blocks.destroyed_msg') redirect_to admin_instances_path(limited: '1'), notice: I18n.t('admin.domain_blocks.destroyed_msg')
end end
private private

@ -8,15 +8,11 @@ module Admin
def index def index
authorize :account, :index? authorize :account, :index?
@followers = followers.recent.page(params[:page]).per(PER_PAGE) @followers = @account.followers.local.recent.page(params[:page]).per(PER_PAGE)
end end
def set_account def set_account
@account = Account.find(params[:account_id]) @account = Account.find(params[:account_id])
end end
def followers
Follow.includes(:account).where(target_account: @account)
end
end end
end end

@ -4,14 +4,21 @@ module Admin
class InstancesController < BaseController class InstancesController < BaseController
def index def index
authorize :instance, :index? authorize :instance, :index?
@instances = ordered_instances @instances = ordered_instances
end end
def resubscribe def show
authorize :instance, :resubscribe? authorize :instance, :show?
params.require(:by_domain)
Pubsubhubbub::SubscribeWorker.push_bulk(subscribeable_accounts.pluck(:id)) @instance = Instance.new(Account.by_domain_accounts.find_by(domain: params[:id]) || DomainBlock.find_by!(domain: params[:id]))
redirect_to admin_instances_path @following_count = Follow.where(account: Account.where(domain: params[:id])).count
@followers_count = Follow.where(target_account: Account.where(domain: params[:id])).count
@reports_count = Report.where(target_account: Account.where(domain: params[:id])).count
@blocks_count = Block.where(target_account: Account.where(domain: params[:id])).count
@available = DeliveryFailureTracker.available?(Account.select(:shared_inbox_url).where(domain: params[:id]).first&.shared_inbox_url)
@media_storage = MediaAttachment.where(account: Account.where(domain: params[:id])).sum(:file_file_size)
@domain_block = DomainBlock.find_by(domain: params[:id])
end end
private private
@ -27,17 +34,11 @@ module Admin
helper_method :paginated_instances helper_method :paginated_instances
def ordered_instances def ordered_instances
paginated_instances.map { |account| Instance.new(account) } paginated_instances.map { |resource| Instance.new(resource) }
end
def subscribeable_accounts
Account.remote.where(protocol: :ostatus).where(domain: params[:by_domain])
end end
def filter_params def filter_params
params.permit( params.permit(:limited)
:domain_name
)
end end
end end
end end

@ -26,7 +26,7 @@ module Admin
authorize :status, :index? authorize :status, :index?
@statuses = @account.statuses.where(id: params[:id]) @statuses = @account.statuses.where(id: params[:id])
authorize @statuses[0], :show? authorize @statuses.first, :show?
@form = Form::StatusBatch.new @form = Form::StatusBatch.new
end end

@ -76,7 +76,7 @@ class Api::V1::AccountsController < Api::BaseController
end end
def account_params def account_params
params.permit(:username, :email, :password, :agreement) params.permit(:username, :email, :password, :agreement, :locale)
end end
def check_enabled_registrations def check_enabled_registrations

@ -4,6 +4,8 @@ class Api::V1::CustomEmojisController < Api::BaseController
respond_to :json respond_to :json
def index def index
render json: CustomEmoji.local.where(disabled: false), each_serializer: REST::CustomEmojiSerializer render_cached_json('api:v1:custom_emojis', expires_in: 1.minute) do
ActiveModelSerializers::SerializableResource.new(CustomEmoji.local.where(disabled: false), each_serializer: REST::CustomEmojiSerializer)
end
end end
end end

@ -0,0 +1,77 @@
# frozen_string_literal: true
class Api::V1::ScheduledStatusesController < Api::BaseController
include Authorization
before_action -> { doorkeeper_authorize! :read, :'read:statuses' }, except: [:update, :destroy]
before_action -> { doorkeeper_authorize! :write, :'write:statuses' }, only: [:update, :destroy]
before_action :set_statuses, only: :index
before_action :set_status, except: :index
after_action :insert_pagination_headers, only: :index
def index
render json: @statuses, each_serializer: REST::ScheduledStatusSerializer
end
def show
render json: @status, serializer: REST::ScheduledStatusSerializer
end
def update
@status.update!(scheduled_status_params)
render json: @status, serializer: REST::ScheduledStatusSerializer
end
def destroy
@status.destroy!
render_empty
end
private
def set_statuses
@statuses = current_account.scheduled_statuses.paginate_by_id(limit_param(DEFAULT_STATUSES_LIMIT), params_slice(:max_id, :since_id, :min_id))
end
def set_status
@status = current_account.scheduled_statuses.find(params[:id])
end
def scheduled_status_params
params.permit(:scheduled_at)
end
def pagination_params(core_params)
params.slice(:limit).permit(:limit).merge(core_params)
end
def insert_pagination_headers
set_pagination_headers(next_path, prev_path)
end
def next_path
if records_continue?
api_v1_scheduled_statuses_url pagination_params(max_id: pagination_max_id)
end
end
def prev_path
unless @statuses.empty?
api_v1_scheduled_statuses_url pagination_params(min_id: pagination_since_id)
end
end
def records_continue?
@statuses.size == limit_param(DEFAULT_STATUSES_LIMIT)
end
def pagination_max_id
@statuses.last.id
end
def pagination_since_id
@statuses.first.id
end
end

@ -45,16 +45,17 @@ class Api::V1::StatusesController < Api::BaseController
def create def create
@status = PostStatusService.new.call(current_user.account, @status = PostStatusService.new.call(current_user.account,
status_params[:status], text: status_params[:status],
status_params[:in_reply_to_id].blank? ? nil : Status.find(status_params[:in_reply_to_id]), thread: status_params[:in_reply_to_id].blank? ? nil : Status.find(status_params[:in_reply_to_id]),
media_ids: status_params[:media_ids], media_ids: status_params[:media_ids],
sensitive: status_params[:sensitive], sensitive: status_params[:sensitive],
spoiler_text: status_params[:spoiler_text], spoiler_text: status_params[:spoiler_text],
visibility: status_params[:visibility], visibility: status_params[:visibility],
scheduled_at: status_params[:scheduled_at],
application: doorkeeper_token.application, application: doorkeeper_token.application,
idempotency: request.headers['Idempotency-Key']) idempotency: request.headers['Idempotency-Key'])
render json: @status, serializer: REST::StatusSerializer render json: @status, serializer: @status.is_a?(ScheduledStatus) ? REST::ScheduledStatusSerializer : REST::StatusSerializer
end end
def destroy def destroy
@ -77,7 +78,7 @@ class Api::V1::StatusesController < Api::BaseController
end end
def status_params def status_params
params.permit(:status, :in_reply_to_id, :sensitive, :spoiler_text, :visibility, media_ids: []) params.permit(:status, :in_reply_to_id, :sensitive, :spoiler_text, :visibility, :scheduled_at, media_ids: [])
end end
def pagination_params(core_params) def pagination_params(core_params)

@ -60,24 +60,27 @@ module SignatureVerification
signature = Base64.decode64(signature_params['signature']) signature = Base64.decode64(signature_params['signature'])
compare_signed_string = build_signed_string(signature_params['headers']) compare_signed_string = build_signed_string(signature_params['headers'])
if account.keypair.public_key.verify(OpenSSL::Digest::SHA256.new, signature, compare_signed_string) return account unless verify_signature(account, signature, compare_signed_string).nil?
@signed_request_account = account
@signed_request_account
elsif account.possibly_stale?
account = account.refresh!
if account.keypair.public_key.verify(OpenSSL::Digest::SHA256.new, signature, compare_signed_string) account_stoplight = Stoplight("source:#{request.ip}") { account.possibly_stale? ? account.refresh! : account_refresh_key(account) }
@signed_request_account = account .with_fallback { nil }
@signed_request_account .with_threshold(1)
else .with_cool_off_time(5.minutes.seconds)
@signature_verification_failure_reason = "Verification failed for #{account.username}@#{account.domain} #{account.uri}" .with_error_handler { |error, handle| error.is_a?(HTTP::Error) ? handle.call(error) : raise(error) }
account = account_stoplight.run
if account.nil?
@signature_verification_failure_reason = "Public key not found for key #{signature_params['keyId']}"
@signed_request_account = nil @signed_request_account = nil
return
end end
else
return account unless verify_signature(account, signature, compare_signed_string).nil?
@signature_verification_failure_reason = "Verification failed for #{account.username}@#{account.domain} #{account.uri}" @signature_verification_failure_reason = "Verification failed for #{account.username}@#{account.domain} #{account.uri}"
@signed_request_account = nil @signed_request_account = nil
end end
end
def request_body def request_body
@request_body ||= request.raw_post @request_body ||= request.raw_post
@ -85,6 +88,15 @@ module SignatureVerification
private private
def verify_signature(account, signature, compare_signed_string)
if account.keypair.public_key.verify(OpenSSL::Digest::SHA256.new, signature, compare_signed_string)
@signed_request_account = account
@signed_request_account
end
rescue OpenSSL::PKey::RSAError
nil
end
def build_signed_string(signed_headers) def build_signed_string(signed_headers)
signed_headers = 'date' if signed_headers.blank? signed_headers = 'date' if signed_headers.blank?
@ -131,4 +143,9 @@ module SignatureVerification
account account
end end
end end
def account_refresh_key(account)
return if account.local? || !account.activitypub?
ActivityPub::FetchRemoteAccountService.new.call(account.uri, only_key: true)
end
end end

@ -5,6 +5,7 @@ class RemoteInteractionController < ApplicationController
layout 'modal' layout 'modal'
before_action :set_interaction_type
before_action :set_status before_action :set_status
before_action :set_body_classes before_action :set_body_classes
before_action :set_pack before_action :set_pack
@ -50,4 +51,8 @@ class RemoteInteractionController < ApplicationController
def set_pack def set_pack
use_pack 'modal' use_pack 'modal'
end end
def set_interaction_type
@interaction_type = %w(reply reblog favourite).include?(params[:type]) ? params[:type] : 'reply'
end
end end

@ -6,8 +6,9 @@ module Admin::FilterHelper
INVITE_FILTER = %i(available expired).freeze INVITE_FILTER = %i(available expired).freeze
CUSTOM_EMOJI_FILTERS = %i(local remote by_domain shortcode).freeze CUSTOM_EMOJI_FILTERS = %i(local remote by_domain shortcode).freeze
TAGS_FILTERS = %i(hidden).freeze TAGS_FILTERS = %i(hidden).freeze
INSTANCES_FILTERS = %i(limited).freeze
FILTERS = ACCOUNT_FILTERS + REPORT_FILTERS + INVITE_FILTER + CUSTOM_EMOJI_FILTERS + TAGS_FILTERS FILTERS = ACCOUNT_FILTERS + REPORT_FILTERS + INVITE_FILTER + CUSTOM_EMOJI_FILTERS + TAGS_FILTERS + INSTANCES_FILTERS
def filter_link_to(text, link_to_params, link_class_params = link_to_params) def filter_link_to(text, link_to_params, link_class_params = link_to_params)
new_url = filtered_url_for(link_to_params) new_url = filtered_url_for(link_to_params)

@ -68,10 +68,10 @@ class Account extends ImmutablePureComponent {
if (hidden) { if (hidden) {
return ( return (
<div> <Fragment>
{account.get('display_name')} {account.get('display_name')}
{account.get('username')} {account.get('username')}
</div> </Fragment>
); );
} }

@ -51,6 +51,10 @@ class Item extends React.PureComponent {
const { index, onClick } = this.props; const { index, onClick } = this.props;
if (e.button === 0 && !(e.ctrlKey || e.metaKey)) { if (e.button === 0 && !(e.ctrlKey || e.metaKey)) {
if (this.hoverToPlay()) {
e.target.pause();
e.target.currentTime = 0;
}
e.preventDefault(); e.preventDefault();
onClick(index); onClick(index);
} }

@ -5,7 +5,7 @@ import IconButton from './icon_button';
import DropdownMenuContainer from '../containers/dropdown_menu_container'; import DropdownMenuContainer from '../containers/dropdown_menu_container';
import { defineMessages, injectIntl } from 'react-intl'; import { defineMessages, injectIntl } from 'react-intl';
import ImmutablePureComponent from 'react-immutable-pure-component'; import ImmutablePureComponent from 'react-immutable-pure-component';
import { me } from '../initial_state'; import { me, isStaff } from '../initial_state';
const messages = defineMessages({ const messages = defineMessages({
delete: { id: 'status.delete', defaultMessage: 'Delete' }, delete: { id: 'status.delete', defaultMessage: 'Delete' },
@ -30,6 +30,8 @@ const messages = defineMessages({
pin: { id: 'status.pin', defaultMessage: 'Pin on profile' }, pin: { id: 'status.pin', defaultMessage: 'Pin on profile' },
unpin: { id: 'status.unpin', defaultMessage: 'Unpin from profile' }, unpin: { id: 'status.unpin', defaultMessage: 'Unpin from profile' },
embed: { id: 'status.embed', defaultMessage: 'Embed' }, embed: { id: 'status.embed', defaultMessage: 'Embed' },
admin_account: { id: 'status.admin_account', defaultMessage: 'Open moderation interface for @{name}' },
admin_status: { id: 'status.admin_status', defaultMessage: 'Open this status in the moderation interface' },
}); });
const obfuscatedCount = count => { const obfuscatedCount = count => {
@ -182,6 +184,11 @@ class StatusActionBar extends ImmutablePureComponent {
menu.push({ text: intl.formatMessage(messages.mute, { name: status.getIn(['account', 'username']) }), action: this.handleMuteClick }); menu.push({ text: intl.formatMessage(messages.mute, { name: status.getIn(['account', 'username']) }), action: this.handleMuteClick });
menu.push({ text: intl.formatMessage(messages.block, { name: status.getIn(['account', 'username']) }), action: this.handleBlockClick }); menu.push({ text: intl.formatMessage(messages.block, { name: status.getIn(['account', 'username']) }), action: this.handleBlockClick });
menu.push({ text: intl.formatMessage(messages.report, { name: status.getIn(['account', 'username']) }), action: this.handleReport }); menu.push({ text: intl.formatMessage(messages.report, { name: status.getIn(['account', 'username']) }), action: this.handleReport });
if (isStaff) {
menu.push(null);
menu.push({ text: intl.formatMessage(messages.admin_account, { name: status.getIn(['account', 'username']) }), href: `/admin/accounts/${status.getIn(['account', 'id'])}` });
menu.push({ text: intl.formatMessage(messages.admin_status), href: `/admin/accounts/${status.getIn(['account', 'id'])}/statuses/${status.get('id')}` });
}
} }
if (status.get('visibility') === 'direct') { if (status.get('visibility') === 'direct') {

@ -4,7 +4,7 @@ import PropTypes from 'prop-types';
import DropdownMenuContainer from '../../../containers/dropdown_menu_container'; import DropdownMenuContainer from '../../../containers/dropdown_menu_container';
import { NavLink } 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, isStaff } from '../../../initial_state';
import { shortNumberFormat } from '../../../utils/numbers'; import { shortNumberFormat } from '../../../utils/numbers';
const messages = defineMessages({ const messages = defineMessages({
@ -35,6 +35,7 @@ const messages = defineMessages({
endorse: { id: 'account.endorse', defaultMessage: 'Feature on profile' }, endorse: { id: 'account.endorse', defaultMessage: 'Feature on profile' },
unendorse: { id: 'account.unendorse', defaultMessage: 'Don\'t feature on profile' }, unendorse: { id: 'account.unendorse', defaultMessage: 'Don\'t feature on profile' },
add_or_remove_from_list: { id: 'account.add_or_remove_from_list', defaultMessage: 'Add or Remove from lists' }, add_or_remove_from_list: { id: 'account.add_or_remove_from_list', defaultMessage: 'Add or Remove from lists' },
admin_account: { id: 'status.admin_account', defaultMessage: 'Open moderation interface for @{name}' },
}); });
export default @injectIntl export default @injectIntl
@ -151,6 +152,11 @@ class ActionBar extends React.PureComponent {
} }
} }
if (account.get('id') !== me && isStaff) {
menu.push(null);
menu.push({ text: intl.formatMessage(messages.admin_account, { name: account.get('username') }), href: `/admin/accounts/${account.get('id')}` });
}
return ( return (
<div> <div>
{extraInfo} {extraInfo}

@ -32,6 +32,7 @@ const messages = defineMessages({
personal: { id: 'navigation_bar.personal', defaultMessage: 'Personal' }, personal: { id: 'navigation_bar.personal', defaultMessage: 'Personal' },
security: { id: 'navigation_bar.security', defaultMessage: 'Security' }, security: { id: 'navigation_bar.security', defaultMessage: 'Security' },
menu: { id: 'getting_started.heading', defaultMessage: 'Getting started' }, menu: { id: 'getting_started.heading', defaultMessage: 'Getting started' },
profile_directory: { id: 'getting_started.directory', defaultMessage: 'Profile directory' },
}); });
const mapStateToProps = state => ({ const mapStateToProps = state => ({
@ -87,10 +88,29 @@ class GettingStarted extends ImmutablePureComponent {
<ColumnSubheading key={i++} text={intl.formatMessage(messages.discover)} />, <ColumnSubheading key={i++} text={intl.formatMessage(messages.discover)} />,
<ColumnLink key={i++} icon='users' text={intl.formatMessage(messages.community_timeline)} to='/timelines/public/local' />, <ColumnLink key={i++} icon='users' text={intl.formatMessage(messages.community_timeline)} to='/timelines/public/local' />,
<ColumnLink key={i++} icon='globe' text={intl.formatMessage(messages.public_timeline)} to='/timelines/public' />, <ColumnLink key={i++} icon='globe' text={intl.formatMessage(messages.public_timeline)} to='/timelines/public' />,
);
height += 34 + 48*2;
if (profile_directory) {
navItems.push(
<ColumnLink key={i++} icon='address-book' text={intl.formatMessage(messages.profile_directory)} href='/explore' />
);
height += 48;
}
navItems.push(
<ColumnSubheading key={i++} text={intl.formatMessage(messages.personal)} /> <ColumnSubheading key={i++} text={intl.formatMessage(messages.personal)} />
); );
height += 34*2 + 48*2; height += 34;
} else if (profile_directory) {
navItems.push(
<ColumnLink key={i++} icon='address-book' text={intl.formatMessage(messages.profile_directory)} href='/explore' />
);
height += 48;
} }
navItems.push( navItems.push(
@ -136,7 +156,6 @@ class GettingStarted extends ImmutablePureComponent {
<div className='getting-started__footer'> <div className='getting-started__footer'>
<ul> <ul>
{profile_directory && <li><a href='/explore' target='_blank'><FormattedMessage id='getting_started.directory' defaultMessage='Profile directory' /></a> · </li>}
{invitesEnabled && <li><a href='/invites' target='_blank'><FormattedMessage id='getting_started.invite' defaultMessage='Invite people' /></a> · </li>} {invitesEnabled && <li><a href='/invites' target='_blank'><FormattedMessage id='getting_started.invite' defaultMessage='Invite people' /></a> · </li>}
{multiColumn && <li><Link to='/keyboard-shortcuts'><FormattedMessage id='navigation_bar.keyboard_shortcuts' defaultMessage='Hotkeys' /></Link> · </li>} {multiColumn && <li><Link to='/keyboard-shortcuts'><FormattedMessage id='navigation_bar.keyboard_shortcuts' defaultMessage='Hotkeys' /></Link> · </li>}
<li><a href='/auth/edit'><FormattedMessage id='getting_started.security' defaultMessage='Security' /></a> · </li> <li><a href='/auth/edit'><FormattedMessage id='getting_started.security' defaultMessage='Security' /></a> · </li>

@ -4,7 +4,7 @@ import IconButton from '../../../components/icon_button';
import ImmutablePropTypes from 'react-immutable-proptypes'; import ImmutablePropTypes from 'react-immutable-proptypes';
import DropdownMenuContainer from '../../../containers/dropdown_menu_container'; import DropdownMenuContainer from '../../../containers/dropdown_menu_container';
import { defineMessages, injectIntl } from 'react-intl'; import { defineMessages, injectIntl } from 'react-intl';
import { me } from '../../../initial_state'; import { me, isStaff } from '../../../initial_state';
const messages = defineMessages({ const messages = defineMessages({
delete: { id: 'status.delete', defaultMessage: 'Delete' }, delete: { id: 'status.delete', defaultMessage: 'Delete' },
@ -26,6 +26,8 @@ const messages = defineMessages({
pin: { id: 'status.pin', defaultMessage: 'Pin on profile' }, pin: { id: 'status.pin', defaultMessage: 'Pin on profile' },
unpin: { id: 'status.unpin', defaultMessage: 'Unpin from profile' }, unpin: { id: 'status.unpin', defaultMessage: 'Unpin from profile' },
embed: { id: 'status.embed', defaultMessage: 'Embed' }, embed: { id: 'status.embed', defaultMessage: 'Embed' },
admin_account: { id: 'status.admin_account', defaultMessage: 'Open moderation interface for @{name}' },
admin_status: { id: 'status.admin_status', defaultMessage: 'Open this status in the moderation interface' },
}); });
export default @injectIntl export default @injectIntl
@ -145,6 +147,11 @@ class ActionBar extends React.PureComponent {
menu.push({ text: intl.formatMessage(messages.mute, { name: status.getIn(['account', 'username']) }), action: this.handleMuteClick }); menu.push({ text: intl.formatMessage(messages.mute, { name: status.getIn(['account', 'username']) }), action: this.handleMuteClick });
menu.push({ text: intl.formatMessage(messages.block, { name: status.getIn(['account', 'username']) }), action: this.handleBlockClick }); menu.push({ text: intl.formatMessage(messages.block, { name: status.getIn(['account', 'username']) }), action: this.handleBlockClick });
menu.push({ text: intl.formatMessage(messages.report, { name: status.getIn(['account', 'username']) }), action: this.handleReport }); menu.push({ text: intl.formatMessage(messages.report, { name: status.getIn(['account', 'username']) }), action: this.handleReport });
if (isStaff) {
menu.push(null);
menu.push({ text: intl.formatMessage(messages.admin_account, { name: status.getIn(['account', 'username']) }), href: `/admin/accounts/${status.getIn(['account', 'id'])}` });
menu.push({ text: intl.formatMessage(messages.admin_status), href: `/admin/accounts/${status.getIn(['account', 'id'])}/statuses/${status.get('id')}` });
}
} }
const shareButton = ('share' in navigator) && status.get('visibility') === 'public' && ( const shareButton = ('share' in navigator) && status.get('visibility') === 'public' && (

@ -195,6 +195,12 @@ export default class Card extends React.PureComponent {
{thumbnail} {thumbnail}
</div> </div>
); );
} else {
embed = (
<div className='status-card__image'>
<i className='fa fa-file-text' />
</div>
);
} }
return ( return (

@ -17,5 +17,6 @@ export const invitesEnabled = getMeta('invites_enabled');
export const version = getMeta('version'); export const version = getMeta('version');
export const mascot = getMeta('mascot'); export const mascot = getMeta('mascot');
export const profile_directory = getMeta('profile_directory'); export const profile_directory = getMeta('profile_directory');
export const isStaff = getMeta('is_staff');
export default initialState; export default initialState;

@ -292,6 +292,8 @@
"search_results.statuses": "التبويقات", "search_results.statuses": "التبويقات",
"search_results.total": "{count, number} {count, plural, one {result} و {results}}", "search_results.total": "{count, number} {count, plural, one {result} و {results}}",
"standalone.public_title": "نظرة على ...", "standalone.public_title": "نظرة على ...",
"status.admin_account": "Open moderation interface for @{name}",
"status.admin_status": "Open this status in the moderation interface",
"status.block": "Block @{name}", "status.block": "Block @{name}",
"status.cancel_reblog_private": "إلغاء الترقية", "status.cancel_reblog_private": "إلغاء الترقية",
"status.cannot_reblog": "تعذرت ترقية هذا المنشور", "status.cannot_reblog": "تعذرت ترقية هذا المنشور",

@ -292,6 +292,8 @@
"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.admin_account": "Open moderation interface for @{name}",
"status.admin_status": "Open this status in the moderation interface",
"status.block": "Bloquiar a @{name}", "status.block": "Bloquiar a @{name}",
"status.cancel_reblog_private": "Dexar de compartir", "status.cancel_reblog_private": "Dexar de compartir",
"status.cannot_reblog": "Esti artículu nun pue compartise", "status.cannot_reblog": "Esti artículu nun pue compartise",

@ -292,6 +292,8 @@
"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.admin_account": "Open moderation interface for @{name}",
"status.admin_status": "Open this status in the moderation interface",
"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",

@ -132,7 +132,7 @@
"follow_request.authorize": "Autoritzar", "follow_request.authorize": "Autoritzar",
"follow_request.reject": "Rebutjar", "follow_request.reject": "Rebutjar",
"getting_started.developers": "Desenvolupadors", "getting_started.developers": "Desenvolupadors",
"getting_started.directory": "Profile directory", "getting_started.directory": "Directori de perfils",
"getting_started.documentation": "Documentació", "getting_started.documentation": "Documentació",
"getting_started.heading": "Començant", "getting_started.heading": "Començant",
"getting_started.invite": "Convida gent", "getting_started.invite": "Convida gent",
@ -149,23 +149,23 @@
"home.column_settings.basic": "Bàsic", "home.column_settings.basic": "Bàsic",
"home.column_settings.show_reblogs": "Mostrar impulsos", "home.column_settings.show_reblogs": "Mostrar impulsos",
"home.column_settings.show_replies": "Mostrar respostes", "home.column_settings.show_replies": "Mostrar respostes",
"introduction.federation.action": "Next", "introduction.federation.action": "Següent",
"introduction.federation.federated.headline": "Federated", "introduction.federation.federated.headline": "Federated",
"introduction.federation.federated.text": "Public posts from other servers of the fediverse will appear in the federated timeline.", "introduction.federation.federated.text": "Les publicacions públiques d'altres servidors del fedivers apareixeran a la línia de temps federada.",
"introduction.federation.home.headline": "Home", "introduction.federation.home.headline": "Home",
"introduction.federation.home.text": "Posts from people you follow will appear in your home feed. You can follow anyone on any server!", "introduction.federation.home.text": "Les publicacions de les persones que segueixes apareixeran a la línia de temps Inici. Pots seguir qualsevol persona de qualsevol servidor!",
"introduction.federation.local.headline": "Local", "introduction.federation.local.headline": "Local",
"introduction.federation.local.text": "Public posts from people on the same server as you will appear in the local timeline.", "introduction.federation.local.text": "Les publicacions públiques de les persones del teu mateix servidor apareixeran a la línia de temps local.",
"introduction.interactions.action": "Finish tutorial!", "introduction.interactions.action": "Finalitza el tutorial!",
"introduction.interactions.favourite.headline": "Favourite", "introduction.interactions.favourite.headline": "Favorit",
"introduction.interactions.favourite.text": "You can save a toot for later, and let the author know that you liked it, by favouriting it.", "introduction.interactions.favourite.text": "Pots desar un toot per a més tard i deixar que l'autor sàpiga que t'ha agradat, marcant-lo com a favorit.",
"introduction.interactions.reblog.headline": "Boost", "introduction.interactions.reblog.headline": "Impuls",
"introduction.interactions.reblog.text": "You can share other people's toots with your followers by boosting them.", "introduction.interactions.reblog.text": "Pots compartir amb els teus seguidors els toots d'altres usuaris, impulsant-los.",
"introduction.interactions.reply.headline": "Reply", "introduction.interactions.reply.headline": "Respondre",
"introduction.interactions.reply.text": "You can reply to other people's and your own toots, which will chain them together in a conversation.", "introduction.interactions.reply.text": "Pots respondre als toots d'altres persones i als teus propis, que els unirà en una conversa.",
"introduction.welcome.action": "Let's go!", "introduction.welcome.action": "Som-hi!",
"introduction.welcome.headline": "First steps", "introduction.welcome.headline": "Primers passos",
"introduction.welcome.text": "Welcome to the fediverse! In a few moments, you'll be able to broadcast messages and talk to your friends across a wide variety of servers. But this server, {domain}, is special—it hosts your profile, so remember its name.", "introduction.welcome.text": "Benvingut al fedivers! En uns moments podràs emetre missatges i conversar amb els teus amics en una gran varietat de servidors. Però aquest servidor, {domain}, és especial: allotja el teu perfil així que recorda el seu nom.",
"keyboard_shortcuts.back": "navegar enrera", "keyboard_shortcuts.back": "navegar enrera",
"keyboard_shortcuts.blocked": "per obrir la llista d'usuaris bloquejats", "keyboard_shortcuts.blocked": "per obrir la llista d'usuaris bloquejats",
"keyboard_shortcuts.boost": "impulsar", "keyboard_shortcuts.boost": "impulsar",
@ -242,20 +242,20 @@
"notifications.clear_confirmation": "Estàs segur que vols esborrar permanenment totes les teves notificacions?", "notifications.clear_confirmation": "Estàs segur que vols esborrar permanenment totes les teves notificacions?",
"notifications.column_settings.alert": "Notificacions d'escriptori", "notifications.column_settings.alert": "Notificacions d'escriptori",
"notifications.column_settings.favourite": "Favorits:", "notifications.column_settings.favourite": "Favorits:",
"notifications.column_settings.filter_bar.advanced": "Display all categories", "notifications.column_settings.filter_bar.advanced": "Mostra totes les categories",
"notifications.column_settings.filter_bar.category": "Quick filter bar", "notifications.column_settings.filter_bar.category": "Barra ràpida de filtres",
"notifications.column_settings.filter_bar.show": "Show", "notifications.column_settings.filter_bar.show": "Mostra",
"notifications.column_settings.follow": "Nous seguidors:", "notifications.column_settings.follow": "Nous seguidors:",
"notifications.column_settings.mention": "Mencions:", "notifications.column_settings.mention": "Mencions:",
"notifications.column_settings.push": "Push notificacions", "notifications.column_settings.push": "Push notificacions",
"notifications.column_settings.reblog": "Impulsos:", "notifications.column_settings.reblog": "Impulsos:",
"notifications.column_settings.show": "Mostrar en la columna", "notifications.column_settings.show": "Mostrar en la columna",
"notifications.column_settings.sound": "Reproduïr so", "notifications.column_settings.sound": "Reproduïr so",
"notifications.filter.all": "All", "notifications.filter.all": "Tots",
"notifications.filter.boosts": "Boosts", "notifications.filter.boosts": "Impulsos",
"notifications.filter.favourites": "Favourites", "notifications.filter.favourites": "Favorits",
"notifications.filter.follows": "Follows", "notifications.filter.follows": "Seguiments",
"notifications.filter.mentions": "Mentions", "notifications.filter.mentions": "Mencions",
"notifications.group": "{count} notificacions", "notifications.group": "{count} notificacions",
"privacy.change": "Ajusta l'estat de privacitat", "privacy.change": "Ajusta l'estat de privacitat",
"privacy.direct.long": "Publicar només per als usuaris esmentats", "privacy.direct.long": "Publicar només per als usuaris esmentats",
@ -292,6 +292,8 @@
"search_results.statuses": "Toots", "search_results.statuses": "Toots",
"search_results.total": "{count, number} {count, plural, un {result} altres {results}}", "search_results.total": "{count, number} {count, plural, un {result} altres {results}}",
"standalone.public_title": "Una mirada a l'interior ...", "standalone.public_title": "Una mirada a l'interior ...",
"status.admin_account": "Open moderation interface for @{name}",
"status.admin_status": "Open this status in the moderation interface",
"status.block": "Block @{name}", "status.block": "Block @{name}",
"status.cancel_reblog_private": "Desfer l'impuls", "status.cancel_reblog_private": "Desfer l'impuls",
"status.cannot_reblog": "Aquesta publicació no pot ser retootejada", "status.cannot_reblog": "Aquesta publicació no pot ser retootejada",

@ -132,7 +132,7 @@
"follow_request.authorize": "Auturizà", "follow_request.authorize": "Auturizà",
"follow_request.reject": "Righjittà", "follow_request.reject": "Righjittà",
"getting_started.developers": "Sviluppatori", "getting_started.developers": "Sviluppatori",
"getting_started.directory": "Profile directory", "getting_started.directory": "Annuariu di i prufili",
"getting_started.documentation": "Documentation", "getting_started.documentation": "Documentation",
"getting_started.heading": "Per principià", "getting_started.heading": "Per principià",
"getting_started.invite": "Invità ghjente", "getting_started.invite": "Invità ghjente",
@ -292,6 +292,8 @@
"search_results.statuses": "Statuti", "search_results.statuses": "Statuti",
"search_results.total": "{count, number} {count, plural, one {risultatu} other {risultati}}", "search_results.total": "{count, number} {count, plural, one {risultatu} other {risultati}}",
"standalone.public_title": "Una vista à l'internu...", "standalone.public_title": "Una vista à l'internu...",
"status.admin_account": "Open moderation interface for @{name}",
"status.admin_status": "Open this status in the moderation interface",
"status.block": "Bluccà @{name}", "status.block": "Bluccà @{name}",
"status.cancel_reblog_private": "Ùn sparte più", "status.cancel_reblog_private": "Ùn sparte più",
"status.cannot_reblog": "Stu statutu ùn pò micca esse spartutu", "status.cannot_reblog": "Stu statutu ùn pò micca esse spartutu",
@ -341,7 +343,7 @@
"upload_area.title": "Drag & drop per caricà un fugliale", "upload_area.title": "Drag & drop per caricà un fugliale",
"upload_button.label": "Aghjunghje un media (JPEG, PNG, GIF, WebM, MP4, MOV)", "upload_button.label": "Aghjunghje un media (JPEG, PNG, GIF, WebM, MP4, MOV)",
"upload_form.description": "Discrive per i malvistosi", "upload_form.description": "Discrive per i malvistosi",
"upload_form.focus": "Riquatrà", "upload_form.focus": "Cambià a vista",
"upload_form.undo": "Sguassà", "upload_form.undo": "Sguassà",
"upload_progress.label": "Caricamentu...", "upload_progress.label": "Caricamentu...",
"video.close": "Chjudà a video", "video.close": "Chjudà a video",

@ -12,7 +12,7 @@
"account.follow": "Sledovat", "account.follow": "Sledovat",
"account.followers": "Sledovatelé", "account.followers": "Sledovatelé",
"account.followers.empty": "Tohoto uživatele ještě nikdo nesleduje.", "account.followers.empty": "Tohoto uživatele ještě nikdo nesleduje.",
"account.follows": "Sleduje", "account.follows": "Sledovaní",
"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}",
@ -132,7 +132,7 @@
"follow_request.authorize": "Autorizovat", "follow_request.authorize": "Autorizovat",
"follow_request.reject": "Odmítnout", "follow_request.reject": "Odmítnout",
"getting_started.developers": "Vývojáři", "getting_started.developers": "Vývojáři",
"getting_started.directory": "Profile directory", "getting_started.directory": "Adresář profilů",
"getting_started.documentation": "Dokumentace", "getting_started.documentation": "Dokumentace",
"getting_started.heading": "Začínáme", "getting_started.heading": "Začínáme",
"getting_started.invite": "Pozvat lidi", "getting_started.invite": "Pozvat lidi",
@ -292,6 +292,8 @@
"search_results.statuses": "Tooty", "search_results.statuses": "Tooty",
"search_results.total": "{count, number} {count, plural, one {výsledek} few {výsledky} many {výsledku} other {výsledků}}", "search_results.total": "{count, number} {count, plural, one {výsledek} few {výsledky} many {výsledku} other {výsledků}}",
"standalone.public_title": "Nahlédněte dovnitř...", "standalone.public_title": "Nahlédněte dovnitř...",
"status.admin_account": "Open moderation interface for @{name}",
"status.admin_status": "Open this status in the moderation interface",
"status.block": "Zablokovat uživatele @{name}", "status.block": "Zablokovat uživatele @{name}",
"status.cancel_reblog_private": "Zrušit boost", "status.cancel_reblog_private": "Zrušit boost",
"status.cannot_reblog": "Tento příspěvek nemůže být boostnutý", "status.cannot_reblog": "Tento příspěvek nemůže být boostnutý",
@ -341,7 +343,7 @@
"upload_area.title": "Přetažením nahrajete", "upload_area.title": "Přetažením nahrajete",
"upload_button.label": "Přidat média (JPEG, PNG, GIF, WebM, MP4, MOV)", "upload_button.label": "Přidat média (JPEG, PNG, GIF, WebM, MP4, MOV)",
"upload_form.description": "Popis pro zrakově postižené", "upload_form.description": "Popis pro zrakově postižené",
"upload_form.focus": "Vystřihnout", "upload_form.focus": "Změnit náhled",
"upload_form.undo": "Smazat", "upload_form.undo": "Smazat",
"upload_progress.label": "Nahrávám...", "upload_progress.label": "Nahrávám...",
"video.close": "Zavřít video", "video.close": "Zavřít video",

@ -292,6 +292,8 @@
"search_results.statuses": "Tŵtiau", "search_results.statuses": "Tŵtiau",
"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": "Golwg tu fewn...", "standalone.public_title": "Golwg tu fewn...",
"status.admin_account": "Open moderation interface for @{name}",
"status.admin_status": "Open this status in the moderation interface",
"status.block": "Blocio @{name}", "status.block": "Blocio @{name}",
"status.cancel_reblog_private": "Dadfŵstio", "status.cancel_reblog_private": "Dadfŵstio",
"status.cannot_reblog": "Ni ellir sbarduno'r tŵt hwn", "status.cannot_reblog": "Ni ellir sbarduno'r tŵt hwn",

@ -149,7 +149,7 @@
"home.column_settings.basic": "Grundlæggende", "home.column_settings.basic": "Grundlæggende",
"home.column_settings.show_reblogs": "Vis fremhævelser", "home.column_settings.show_reblogs": "Vis fremhævelser",
"home.column_settings.show_replies": "Vis svar", "home.column_settings.show_replies": "Vis svar",
"introduction.federation.action": "Next", "introduction.federation.action": "Næste",
"introduction.federation.federated.headline": "Federated", "introduction.federation.federated.headline": "Federated",
"introduction.federation.federated.text": "Public posts from other servers of the fediverse will appear in the federated timeline.", "introduction.federation.federated.text": "Public posts from other servers of the fediverse will appear in the federated timeline.",
"introduction.federation.home.headline": "Home", "introduction.federation.home.headline": "Home",
@ -251,10 +251,10 @@
"notifications.column_settings.reblog": "Fremhævelser:", "notifications.column_settings.reblog": "Fremhævelser:",
"notifications.column_settings.show": "Vis i kolonne", "notifications.column_settings.show": "Vis i kolonne",
"notifications.column_settings.sound": "Afspil lyd", "notifications.column_settings.sound": "Afspil lyd",
"notifications.filter.all": "All", "notifications.filter.all": "Alle",
"notifications.filter.boosts": "Boosts", "notifications.filter.boosts": "Boosts",
"notifications.filter.favourites": "Favourites", "notifications.filter.favourites": "Favoritter",
"notifications.filter.follows": "Follows", "notifications.filter.follows": "Følger",
"notifications.filter.mentions": "Mentions", "notifications.filter.mentions": "Mentions",
"notifications.group": "{count} notifikationer", "notifications.group": "{count} notifikationer",
"privacy.change": "Ændre status privatliv", "privacy.change": "Ændre status privatliv",
@ -292,6 +292,8 @@
"search_results.statuses": "Trut", "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.admin_account": "Open moderation interface for @{name}",
"status.admin_status": "Open this status in the moderation interface",
"status.block": "Bloker @{name}", "status.block": "Bloker @{name}",
"status.cancel_reblog_private": "Fremhæv ikke længere", "status.cancel_reblog_private": "Fremhæv ikke længere",
"status.cannot_reblog": "Denne post kan ikke fremhæves", "status.cannot_reblog": "Denne post kan ikke fremhæves",

@ -132,7 +132,7 @@
"follow_request.authorize": "Erlauben", "follow_request.authorize": "Erlauben",
"follow_request.reject": "Ablehnen", "follow_request.reject": "Ablehnen",
"getting_started.developers": "Entwickler", "getting_started.developers": "Entwickler",
"getting_started.directory": "Profile directory", "getting_started.directory": "Profilverzeichnis",
"getting_started.documentation": "Dokumentation", "getting_started.documentation": "Dokumentation",
"getting_started.heading": "Erste Schritte", "getting_started.heading": "Erste Schritte",
"getting_started.invite": "Leute einladen", "getting_started.invite": "Leute einladen",
@ -292,6 +292,8 @@
"search_results.statuses": "Beiträge", "search_results.statuses": "Beiträge",
"search_results.total": "{count, number} {count, plural, one {Ergebnis} other {Ergebnisse}}", "search_results.total": "{count, number} {count, plural, one {Ergebnis} other {Ergebnisse}}",
"standalone.public_title": "Ein kleiner Einblick …", "standalone.public_title": "Ein kleiner Einblick …",
"status.admin_account": "Open moderation interface for @{name}",
"status.admin_status": "Open this status in the moderation interface",
"status.block": "Blockiere @{name}", "status.block": "Blockiere @{name}",
"status.cancel_reblog_private": "Nicht mehr teilen", "status.cancel_reblog_private": "Nicht mehr teilen",
"status.cannot_reblog": "Dieser Beitrag kann nicht geteilt werden", "status.cannot_reblog": "Dieser Beitrag kann nicht geteilt werden",
@ -341,7 +343,7 @@
"upload_area.title": "Zum Hochladen hereinziehen", "upload_area.title": "Zum Hochladen hereinziehen",
"upload_button.label": "Mediendatei hinzufügen (JPEG, PNG, GIF, WebM, MP4, MOV)", "upload_button.label": "Mediendatei hinzufügen (JPEG, PNG, GIF, WebM, MP4, MOV)",
"upload_form.description": "Für Menschen mit Sehbehinderung beschreiben", "upload_form.description": "Für Menschen mit Sehbehinderung beschreiben",
"upload_form.focus": "Zuschneiden", "upload_form.focus": "Thumbnail bearbeiten",
"upload_form.undo": "Löschen", "upload_form.undo": "Löschen",
"upload_progress.label": "Wird hochgeladen …", "upload_progress.label": "Wird hochgeladen …",
"video.close": "Video schließen", "video.close": "Video schließen",

@ -302,6 +302,14 @@
{ {
"defaultMessage": "Embed", "defaultMessage": "Embed",
"id": "status.embed" "id": "status.embed"
},
{
"defaultMessage": "Open moderation interface for @{name}",
"id": "status.admin_account"
},
{
"defaultMessage": "Open this status in the moderation interface",
"id": "status.admin_status"
} }
], ],
"path": "app/javascript/mastodon/components/status_action_bar.json" "path": "app/javascript/mastodon/components/status_action_bar.json"
@ -594,6 +602,10 @@
"defaultMessage": "Add or Remove from lists", "defaultMessage": "Add or Remove from lists",
"id": "account.add_or_remove_from_list" "id": "account.add_or_remove_from_list"
}, },
{
"defaultMessage": "Open moderation interface for @{name}",
"id": "status.admin_account"
},
{ {
"defaultMessage": "Information below may reflect the user's profile incompletely.", "defaultMessage": "Information below may reflect the user's profile incompletely.",
"id": "account.disclaimer_full" "id": "account.disclaimer_full"
@ -1926,6 +1938,14 @@
{ {
"defaultMessage": "Embed", "defaultMessage": "Embed",
"id": "status.embed" "id": "status.embed"
},
{
"defaultMessage": "Open moderation interface for @{name}",
"id": "status.admin_account"
},
{
"defaultMessage": "Open this status in the moderation interface",
"id": "status.admin_status"
} }
], ],
"path": "app/javascript/mastodon/features/status/components/action_bar.json" "path": "app/javascript/mastodon/features/status/components/action_bar.json"

@ -132,7 +132,7 @@
"follow_request.authorize": "Ενέκρινε", "follow_request.authorize": "Ενέκρινε",
"follow_request.reject": "Απέρριψε", "follow_request.reject": "Απέρριψε",
"getting_started.developers": "Ανάπτυξη", "getting_started.developers": "Ανάπτυξη",
"getting_started.directory": "Profile directory", "getting_started.directory": "Κατάλογος λογαριασμών",
"getting_started.documentation": "Τεκμηρίωση", "getting_started.documentation": "Τεκμηρίωση",
"getting_started.heading": "Αφετηρία", "getting_started.heading": "Αφετηρία",
"getting_started.invite": "Προσκάλεσε κόσμο", "getting_started.invite": "Προσκάλεσε κόσμο",
@ -292,6 +292,8 @@
"search_results.statuses": "Τουτ", "search_results.statuses": "Τουτ",
"search_results.total": "{count, number} {count, plural, ένα {result} υπόλοιπα {results}}", "search_results.total": "{count, number} {count, plural, ένα {result} υπόλοιπα {results}}",
"standalone.public_title": "Μια πρώτη γεύση...", "standalone.public_title": "Μια πρώτη γεύση...",
"status.admin_account": "Open moderation interface for @{name}",
"status.admin_status": "Open this status in the moderation interface",
"status.block": "Αποκλεισμός @{name}", "status.block": "Αποκλεισμός @{name}",
"status.cancel_reblog_private": "Ακύρωσε την προώθηση", "status.cancel_reblog_private": "Ακύρωσε την προώθηση",
"status.cannot_reblog": "Αυτή η δημοσίευση δεν μπορεί να προωθηθεί", "status.cannot_reblog": "Αυτή η δημοσίευση δεν μπορεί να προωθηθεί",
@ -341,7 +343,7 @@
"upload_area.title": "Drag & drop για να ανεβάσεις", "upload_area.title": "Drag & drop για να ανεβάσεις",
"upload_button.label": "Πρόσθεσε πολυμέσα (JPEG, PNG, GIF, WebM, MP4, MOV)", "upload_button.label": "Πρόσθεσε πολυμέσα (JPEG, PNG, GIF, WebM, MP4, MOV)",
"upload_form.description": "Περιέγραψε για όσους & όσες έχουν προβλήματα όρασης", "upload_form.description": "Περιέγραψε για όσους & όσες έχουν προβλήματα όρασης",
"upload_form.focus": "Περικοπή", "upload_form.focus": "Αλλαγή προεπισκόπησης",
"upload_form.undo": "Διαγραφή", "upload_form.undo": "Διαγραφή",
"upload_progress.label": "Ανεβαίνει...", "upload_progress.label": "Ανεβαίνει...",
"video.close": "Κλείσε το βίντεο", "video.close": "Κλείσε το βίντεο",

@ -297,6 +297,8 @@
"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.admin_account": "Open moderation interface for @{name}",
"status.admin_status": "Open this status in the moderation interface",
"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",

@ -292,6 +292,8 @@
"search_results.statuses": "Mesaĝoj", "search_results.statuses": "Mesaĝoj",
"search_results.total": "{count, number} {count, plural, one {rezulto} other {rezultoj}}", "search_results.total": "{count, number} {count, plural, one {rezulto} other {rezultoj}}",
"standalone.public_title": "Enrigardo…", "standalone.public_title": "Enrigardo…",
"status.admin_account": "Open moderation interface for @{name}",
"status.admin_status": "Open this status in the moderation interface",
"status.block": "Bloki @{name}", "status.block": "Bloki @{name}",
"status.cancel_reblog_private": "Eksdiskonigi", "status.cancel_reblog_private": "Eksdiskonigi",
"status.cannot_reblog": "Ĉi tiu mesaĝo ne diskonigeblas", "status.cannot_reblog": "Ĉi tiu mesaĝo ne diskonigeblas",

@ -292,6 +292,8 @@
"search_results.statuses": "Toots", "search_results.statuses": "Toots",
"search_results.total": "{count, number} {count, plural, one {resultado} other {resultados}}", "search_results.total": "{count, number} {count, plural, one {resultado} other {resultados}}",
"standalone.public_title": "Un pequeño vistazo...", "standalone.public_title": "Un pequeño vistazo...",
"status.admin_account": "Open moderation interface for @{name}",
"status.admin_status": "Open this status in the moderation interface",
"status.block": "Block @{name}", "status.block": "Block @{name}",
"status.cancel_reblog_private": "Des-impulsar", "status.cancel_reblog_private": "Des-impulsar",
"status.cannot_reblog": "Este toot no puede retootearse", "status.cannot_reblog": "Este toot no puede retootearse",

@ -132,7 +132,7 @@
"follow_request.authorize": "Baimendu", "follow_request.authorize": "Baimendu",
"follow_request.reject": "Ukatu", "follow_request.reject": "Ukatu",
"getting_started.developers": "Garatzaileak", "getting_started.developers": "Garatzaileak",
"getting_started.directory": "Profile directory", "getting_started.directory": "Profil-direktorioa",
"getting_started.documentation": "Dokumentazioa", "getting_started.documentation": "Dokumentazioa",
"getting_started.heading": "Menua", "getting_started.heading": "Menua",
"getting_started.invite": "Gonbidatu jendea", "getting_started.invite": "Gonbidatu jendea",
@ -149,23 +149,23 @@
"home.column_settings.basic": "Oinarrizkoa", "home.column_settings.basic": "Oinarrizkoa",
"home.column_settings.show_reblogs": "Erakutsi bultzadak", "home.column_settings.show_reblogs": "Erakutsi bultzadak",
"home.column_settings.show_replies": "Erakutsi erantzunak", "home.column_settings.show_replies": "Erakutsi erantzunak",
"introduction.federation.action": "Next", "introduction.federation.action": "Hurrengoa",
"introduction.federation.federated.headline": "Federated", "introduction.federation.federated.headline": "Federated",
"introduction.federation.federated.text": "Public posts from other servers of the fediverse will appear in the federated timeline.", "introduction.federation.federated.text": "Fedibertsoko beste zerbitzarietako bidalketa publikoak federatutako denbora-lerroan agertuko dira.",
"introduction.federation.home.headline": "Home", "introduction.federation.home.headline": "Home",
"introduction.federation.home.text": "Posts from people you follow will appear in your home feed. You can follow anyone on any server!", "introduction.federation.home.text": "Jarraitzen dituzun horien mezuak zure hasierako jarioan agertuko dira. Edozein zerbitzariko edonor jarraitu dezakezu!",
"introduction.federation.local.headline": "Local", "introduction.federation.local.headline": "Local",
"introduction.federation.local.text": "Public posts from people on the same server as you will appear in the local timeline.", "introduction.federation.local.text": "Zure zerbitzari berean dauden horien mezu publikoak denbora-lerro lokalean agertuko dira.",
"introduction.interactions.action": "Finish tutorial!", "introduction.interactions.action": "Amaitu tutoriala!",
"introduction.interactions.favourite.headline": "Favourite", "introduction.interactions.favourite.headline": "Gogokoa",
"introduction.interactions.favourite.text": "You can save a toot for later, and let the author know that you liked it, by favouriting it.", "introduction.interactions.favourite.text": "Toot bat geroko gorde dezakezu, eta egileari gustukoa duzula jakinarazi, hau gogoko bihurtuz.",
"introduction.interactions.reblog.headline": "Boost", "introduction.interactions.reblog.headline": "Bultzada",
"introduction.interactions.reblog.text": "You can share other people's toots with your followers by boosting them.", "introduction.interactions.reblog.text": "Beste batzuen mezuak partekatu ditzakezu zure jarraitzaileekin hauei bultzada emanez.",
"introduction.interactions.reply.headline": "Reply", "introduction.interactions.reply.headline": "Erantzun",
"introduction.interactions.reply.text": "You can reply to other people's and your own toots, which will chain them together in a conversation.", "introduction.interactions.reply.text": "Besteen mezuei eta zure mezuei ere erantzun diezaiekezu, eta elkarrizketa batean lotuta agertuko dira.",
"introduction.welcome.action": "Let's go!", "introduction.welcome.action": "Goazen!",
"introduction.welcome.headline": "First steps", "introduction.welcome.headline": "Lehen urratsak",
"introduction.welcome.text": "Welcome to the fediverse! In a few moments, you'll be able to broadcast messages and talk to your friends across a wide variety of servers. But this server, {domain}, is special—it hosts your profile, so remember its name.", "introduction.welcome.text": "Ongi etorri fedibertsora! Hemendik gutxira hainbat zerbitzarietan zehar mezuak zabaldu eta lagunekin hitz egin ahal izango duzu. Baina zerbitzari hau hainbat zerbitzarietan zehar. berezia da, hau da zure profila ostatatzen duena, ez ahaztu bere izena.",
"keyboard_shortcuts.back": "atzera nabigatzeko", "keyboard_shortcuts.back": "atzera nabigatzeko",
"keyboard_shortcuts.blocked": "blokeatutako erabiltzaileen zerrenda irekitzeko", "keyboard_shortcuts.blocked": "blokeatutako erabiltzaileen zerrenda irekitzeko",
"keyboard_shortcuts.boost": "bultzada ematea", "keyboard_shortcuts.boost": "bultzada ematea",
@ -242,20 +242,20 @@
"notifications.clear_confirmation": "Ziur zure jakinarazpen guztiak behin betirako garbitu nahi dituzula?", "notifications.clear_confirmation": "Ziur zure jakinarazpen guztiak behin betirako garbitu nahi dituzula?",
"notifications.column_settings.alert": "Mahaigaineko jakinarazpenak", "notifications.column_settings.alert": "Mahaigaineko jakinarazpenak",
"notifications.column_settings.favourite": "Gogokoak:", "notifications.column_settings.favourite": "Gogokoak:",
"notifications.column_settings.filter_bar.advanced": "Display all categories", "notifications.column_settings.filter_bar.advanced": "Erakutsi kategoria guztiak",
"notifications.column_settings.filter_bar.category": "Quick filter bar", "notifications.column_settings.filter_bar.category": "Iragazki azkarraren barra",
"notifications.column_settings.filter_bar.show": "Show", "notifications.column_settings.filter_bar.show": "Erakutsi",
"notifications.column_settings.follow": "Jarraitzaile berriak:", "notifications.column_settings.follow": "Jarraitzaile berriak:",
"notifications.column_settings.mention": "Aipamenak:", "notifications.column_settings.mention": "Aipamenak:",
"notifications.column_settings.push": "Push jakinarazpenak", "notifications.column_settings.push": "Push jakinarazpenak",
"notifications.column_settings.reblog": "Bultzadak:", "notifications.column_settings.reblog": "Bultzadak:",
"notifications.column_settings.show": "Erakutsi zutabean", "notifications.column_settings.show": "Erakutsi zutabean",
"notifications.column_settings.sound": "Jo soinua", "notifications.column_settings.sound": "Jo soinua",
"notifications.filter.all": "All", "notifications.filter.all": "Denak",
"notifications.filter.boosts": "Boosts", "notifications.filter.boosts": "Bultzadak",
"notifications.filter.favourites": "Favourites", "notifications.filter.favourites": "Gogokoak",
"notifications.filter.follows": "Follows", "notifications.filter.follows": "Jarraipenak",
"notifications.filter.mentions": "Mentions", "notifications.filter.mentions": "Aipamenak",
"notifications.group": "{count} jakinarazpen", "notifications.group": "{count} jakinarazpen",
"privacy.change": "Doitu mezuaren pribatutasuna", "privacy.change": "Doitu mezuaren pribatutasuna",
"privacy.direct.long": "Bidali aipatutako erabiltzaileei besterik ez", "privacy.direct.long": "Bidali aipatutako erabiltzaileei besterik ez",
@ -292,6 +292,8 @@
"search_results.statuses": "Toot-ak", "search_results.statuses": "Toot-ak",
"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": "Begiradatxo bat...", "standalone.public_title": "Begiradatxo bat...",
"status.admin_account": "Open moderation interface for @{name}",
"status.admin_status": "Open this status in the moderation interface",
"status.block": "Block @{name}", "status.block": "Block @{name}",
"status.cancel_reblog_private": "Kendu bultzada", "status.cancel_reblog_private": "Kendu bultzada",
"status.cannot_reblog": "Mezu honi ezin zaio bultzada eman", "status.cannot_reblog": "Mezu honi ezin zaio bultzada eman",
@ -341,7 +343,7 @@
"upload_area.title": "Arrastatu eta jaregin igotzeko", "upload_area.title": "Arrastatu eta jaregin igotzeko",
"upload_button.label": "Gehitu multimedia (JPEG, PNG, GIF, WebM, MP4, MOV)", "upload_button.label": "Gehitu multimedia (JPEG, PNG, GIF, WebM, MP4, MOV)",
"upload_form.description": "Deskribatu ikusmen arazoak dituztenentzat", "upload_form.description": "Deskribatu ikusmen arazoak dituztenentzat",
"upload_form.focus": "Moztu", "upload_form.focus": "Aldatu aurrebista",
"upload_form.undo": "Ezabatu", "upload_form.undo": "Ezabatu",
"upload_progress.label": "Igotzen...", "upload_progress.label": "Igotzen...",
"video.close": "Itxi bideoa", "video.close": "Itxi bideoa",

@ -292,6 +292,8 @@
"search_results.statuses": "بوق‌ها", "search_results.statuses": "بوق‌ها",
"search_results.total": "{count, number} {count, plural, one {نتیجه} other {نتیجه}}", "search_results.total": "{count, number} {count, plural, one {نتیجه} other {نتیجه}}",
"standalone.public_title": "نگاهی به کاربران این سرور...", "standalone.public_title": "نگاهی به کاربران این سرور...",
"status.admin_account": "Open moderation interface for @{name}",
"status.admin_status": "Open this status in the moderation interface",
"status.block": "مسدودسازی @{name}", "status.block": "مسدودسازی @{name}",
"status.cancel_reblog_private": "حذف بازبوق", "status.cancel_reblog_private": "حذف بازبوق",
"status.cannot_reblog": "این نوشته را نمی‌شود بازبوقید", "status.cannot_reblog": "این نوشته را نمی‌شود بازبوقید",

@ -292,6 +292,8 @@
"search_results.statuses": "Tuuttaukset", "search_results.statuses": "Tuuttaukset",
"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": "Kurkistus sisälle...", "standalone.public_title": "Kurkistus sisälle...",
"status.admin_account": "Open moderation interface for @{name}",
"status.admin_status": "Open this status in the moderation interface",
"status.block": "Estä @{name}", "status.block": "Estä @{name}",
"status.cancel_reblog_private": "Peru buustaus", "status.cancel_reblog_private": "Peru buustaus",
"status.cannot_reblog": "Tätä julkaisua ei voi buustata", "status.cannot_reblog": "Tätä julkaisua ei voi buustata",

@ -132,7 +132,7 @@
"follow_request.authorize": "Accepter", "follow_request.authorize": "Accepter",
"follow_request.reject": "Rejeter", "follow_request.reject": "Rejeter",
"getting_started.developers": "Développeurs", "getting_started.developers": "Développeurs",
"getting_started.directory": "Profile directory", "getting_started.directory": "Annuaire des profils",
"getting_started.documentation": "Documentation", "getting_started.documentation": "Documentation",
"getting_started.heading": "Pour commencer", "getting_started.heading": "Pour commencer",
"getting_started.invite": "Inviter des gens", "getting_started.invite": "Inviter des gens",
@ -292,6 +292,8 @@
"search_results.statuses": "Pouets", "search_results.statuses": "Pouets",
"search_results.total": "{count, number} {count, plural, one {résultat} other {résultats}}", "search_results.total": "{count, number} {count, plural, one {résultat} other {résultats}}",
"standalone.public_title": "Un aperçu …", "standalone.public_title": "Un aperçu …",
"status.admin_account": "Open moderation interface for @{name}",
"status.admin_status": "Open this status in the moderation interface",
"status.block": "Block @{name}", "status.block": "Block @{name}",
"status.cancel_reblog_private": "Dé-booster", "status.cancel_reblog_private": "Dé-booster",
"status.cannot_reblog": "Cette publication ne peut être boostée", "status.cannot_reblog": "Cette publication ne peut être boostée",

@ -292,6 +292,8 @@
"search_results.statuses": "Toots", "search_results.statuses": "Toots",
"search_results.total": "{count, number} {count,plural,one {result} outros {results}}", "search_results.total": "{count, number} {count,plural,one {result} outros {results}}",
"standalone.public_title": "Ollada dentro...", "standalone.public_title": "Ollada dentro...",
"status.admin_account": "Open moderation interface for @{name}",
"status.admin_status": "Open this status in the moderation interface",
"status.block": "Block @{name}", "status.block": "Block @{name}",
"status.cancel_reblog_private": "Non promover", "status.cancel_reblog_private": "Non promover",
"status.cannot_reblog": "Esta mensaxe non pode ser promovida", "status.cannot_reblog": "Esta mensaxe non pode ser promovida",
@ -341,7 +343,7 @@
"upload_area.title": "Arrastre e solte para subir", "upload_area.title": "Arrastre e solte para subir",
"upload_button.label": "Engadir medios (JPEG, PNG, GIF, WebM, MP4, MOV)", "upload_button.label": "Engadir medios (JPEG, PNG, GIF, WebM, MP4, MOV)",
"upload_form.description": "Describa para deficientes visuais", "upload_form.description": "Describa para deficientes visuais",
"upload_form.focus": "Recortar", "upload_form.focus": "Cambiar vista previa",
"upload_form.undo": "Eliminar", "upload_form.undo": "Eliminar",
"upload_progress.label": "Subindo...", "upload_progress.label": "Subindo...",
"video.close": "Pechar video", "video.close": "Pechar video",

@ -292,6 +292,8 @@
"search_results.statuses": "Toots", "search_results.statuses": "Toots",
"search_results.total": "{count, number} {count, plural, one {תוצאה} other {תוצאות}}", "search_results.total": "{count, number} {count, plural, one {תוצאה} other {תוצאות}}",
"standalone.public_title": "הצצה פנימה...", "standalone.public_title": "הצצה פנימה...",
"status.admin_account": "Open moderation interface for @{name}",
"status.admin_status": "Open this status in the moderation interface",
"status.block": "Block @{name}", "status.block": "Block @{name}",
"status.cancel_reblog_private": "Unboost", "status.cancel_reblog_private": "Unboost",
"status.cannot_reblog": "לא ניתן להדהד הודעה זו", "status.cannot_reblog": "לא ניתן להדהד הודעה זו",

@ -292,6 +292,8 @@
"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.admin_account": "Open moderation interface for @{name}",
"status.admin_status": "Open this status in the moderation interface",
"status.block": "Block @{name}", "status.block": "Block @{name}",
"status.cancel_reblog_private": "Unboost", "status.cancel_reblog_private": "Unboost",
"status.cannot_reblog": "Ovaj post ne može biti boostan", "status.cannot_reblog": "Ovaj post ne može biti boostan",

@ -292,6 +292,8 @@
"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": "Betekintés...", "standalone.public_title": "Betekintés...",
"status.admin_account": "Open moderation interface for @{name}",
"status.admin_status": "Open this status in the moderation interface",
"status.block": "Block @{name}", "status.block": "Block @{name}",
"status.cancel_reblog_private": "Unboost", "status.cancel_reblog_private": "Unboost",
"status.cannot_reblog": "Ezen státusz nem rebloggolható", "status.cannot_reblog": "Ezen státusz nem rebloggolható",

@ -292,6 +292,8 @@
"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": "Այս պահին…", "standalone.public_title": "Այս պահին…",
"status.admin_account": "Open moderation interface for @{name}",
"status.admin_status": "Open this status in the moderation interface",
"status.block": "Արգելափակել @{name}֊ին", "status.block": "Արգելափակել @{name}֊ին",
"status.cancel_reblog_private": "Unboost", "status.cancel_reblog_private": "Unboost",
"status.cannot_reblog": "Այս թութը չի կարող տարածվել", "status.cannot_reblog": "Այս թութը չի կարող տարածվել",

@ -292,6 +292,8 @@
"search_results.statuses": "Toots", "search_results.statuses": "Toots",
"search_results.total": "{count, number} {count, plural, one {hasil} other {hasil}}", "search_results.total": "{count, number} {count, plural, one {hasil} other {hasil}}",
"standalone.public_title": "A look inside...", "standalone.public_title": "A look inside...",
"status.admin_account": "Open moderation interface for @{name}",
"status.admin_status": "Open this status in the moderation interface",
"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",

@ -292,6 +292,8 @@
"search_results.statuses": "Toots", "search_results.statuses": "Toots",
"search_results.total": "{count, number} {count, plural, one {rezulto} other {rezulti}}", "search_results.total": "{count, number} {count, plural, one {rezulto} other {rezulti}}",
"standalone.public_title": "A look inside...", "standalone.public_title": "A look inside...",
"status.admin_account": "Open moderation interface for @{name}",
"status.admin_status": "Open this status in the moderation interface",
"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",

@ -132,7 +132,7 @@
"follow_request.authorize": "Autorizza", "follow_request.authorize": "Autorizza",
"follow_request.reject": "Rifiuta", "follow_request.reject": "Rifiuta",
"getting_started.developers": "Sviluppatori", "getting_started.developers": "Sviluppatori",
"getting_started.directory": "Profile directory", "getting_started.directory": "Directory del profilo",
"getting_started.documentation": "Documentazione", "getting_started.documentation": "Documentazione",
"getting_started.heading": "Come iniziare", "getting_started.heading": "Come iniziare",
"getting_started.invite": "Invita qualcuno", "getting_started.invite": "Invita qualcuno",
@ -149,23 +149,23 @@
"home.column_settings.basic": "Semplice", "home.column_settings.basic": "Semplice",
"home.column_settings.show_reblogs": "Mostra post condivisi", "home.column_settings.show_reblogs": "Mostra post condivisi",
"home.column_settings.show_replies": "Mostra risposte", "home.column_settings.show_replies": "Mostra risposte",
"introduction.federation.action": "Next", "introduction.federation.action": "Avanti",
"introduction.federation.federated.headline": "Federated", "introduction.federation.federated.headline": "Federated",
"introduction.federation.federated.text": "Public posts from other servers of the fediverse will appear in the federated timeline.", "introduction.federation.federated.text": "I post pubblici provenienti da altri server del fediverse saranno mostrati nella timeline federata.",
"introduction.federation.home.headline": "Home", "introduction.federation.home.headline": "Home",
"introduction.federation.home.text": "Posts from people you follow will appear in your home feed. You can follow anyone on any server!", "introduction.federation.home.text": "I post scritti da persone che segui saranno mostrati nella timeline home. Puoi seguire chiunque su qualunque server!",
"introduction.federation.local.headline": "Local", "introduction.federation.local.headline": "Local",
"introduction.federation.local.text": "Public posts from people on the same server as you will appear in the local timeline.", "introduction.federation.local.text": "I post pubblici scritti da persone sul tuo stesso server saranno mostrati nella timeline locale.",
"introduction.interactions.action": "Finish tutorial!", "introduction.interactions.action": "Finisci il tutorial!",
"introduction.interactions.favourite.headline": "Favourite", "introduction.interactions.favourite.headline": "Apprezza",
"introduction.interactions.favourite.text": "You can save a toot for later, and let the author know that you liked it, by favouriting it.", "introduction.interactions.favourite.text": "Puoi salvare un toot e tenerlo per dopo, e far sapere all'autore che ti è piaciuto, segnandolo come apprezzato.",
"introduction.interactions.reblog.headline": "Boost", "introduction.interactions.reblog.headline": "Condividi",
"introduction.interactions.reblog.text": "You can share other people's toots with your followers by boosting them.", "introduction.interactions.reblog.text": "Con la condivisione puoi segnalare i toot di altre persone ai tuoi seguaci .",
"introduction.interactions.reply.headline": "Reply", "introduction.interactions.reply.headline": "Rispondi",
"introduction.interactions.reply.text": "You can reply to other people's and your own toots, which will chain them together in a conversation.", "introduction.interactions.reply.text": "Puoi rispondere ai toot, sia a quelli di altri sia ai tuoi, e i toot saranno collegati a formare una conversazione.",
"introduction.welcome.action": "Let's go!", "introduction.welcome.action": "Andiamo!",
"introduction.welcome.headline": "First steps", "introduction.welcome.headline": "Primi passi",
"introduction.welcome.text": "Welcome to the fediverse! In a few moments, you'll be able to broadcast messages and talk to your friends across a wide variety of servers. But this server, {domain}, is special—it hosts your profile, so remember its name.", "introduction.welcome.text": "Benvenuto/a nel fediverse! Tra poco potrai inviare messaggi e parlare con i tuoi amici su una grande varietà di server. Ma questo server, {domain}, è speciale: ospita il tuo profilo, quindi ricordati il suo nome.",
"keyboard_shortcuts.back": "per tornare indietro", "keyboard_shortcuts.back": "per tornare indietro",
"keyboard_shortcuts.blocked": "per aprire l'elenco degli utenti bloccati", "keyboard_shortcuts.blocked": "per aprire l'elenco degli utenti bloccati",
"keyboard_shortcuts.boost": "per condividere", "keyboard_shortcuts.boost": "per condividere",
@ -242,20 +242,20 @@
"notifications.clear_confirmation": "Vuoi davvero cancellare tutte le notifiche?", "notifications.clear_confirmation": "Vuoi davvero cancellare tutte le notifiche?",
"notifications.column_settings.alert": "Notifiche desktop", "notifications.column_settings.alert": "Notifiche desktop",
"notifications.column_settings.favourite": "Apprezzati:", "notifications.column_settings.favourite": "Apprezzati:",
"notifications.column_settings.filter_bar.advanced": "Display all categories", "notifications.column_settings.filter_bar.advanced": "Mostra tutte le categorie",
"notifications.column_settings.filter_bar.category": "Quick filter bar", "notifications.column_settings.filter_bar.category": "Filtro rapido",
"notifications.column_settings.filter_bar.show": "Show", "notifications.column_settings.filter_bar.show": "Mostra",
"notifications.column_settings.follow": "Nuovi seguaci:", "notifications.column_settings.follow": "Nuovi seguaci:",
"notifications.column_settings.mention": "Menzioni:", "notifications.column_settings.mention": "Menzioni:",
"notifications.column_settings.push": "Notifiche push", "notifications.column_settings.push": "Notifiche push",
"notifications.column_settings.reblog": "Post condivisi:", "notifications.column_settings.reblog": "Post condivisi:",
"notifications.column_settings.show": "Mostra in colonna", "notifications.column_settings.show": "Mostra in colonna",
"notifications.column_settings.sound": "Riproduci suono", "notifications.column_settings.sound": "Riproduci suono",
"notifications.filter.all": "All", "notifications.filter.all": "Tutti",
"notifications.filter.boosts": "Boosts", "notifications.filter.boosts": "Condivisioni",
"notifications.filter.favourites": "Favourites", "notifications.filter.favourites": "Apprezzati",
"notifications.filter.follows": "Follows", "notifications.filter.follows": "Seguaci",
"notifications.filter.mentions": "Mentions", "notifications.filter.mentions": "Menzioni",
"notifications.group": "{count} notifiche", "notifications.group": "{count} notifiche",
"privacy.change": "Modifica privacy del post", "privacy.change": "Modifica privacy del post",
"privacy.direct.long": "Invia solo a utenti menzionati", "privacy.direct.long": "Invia solo a utenti menzionati",
@ -292,6 +292,8 @@
"search_results.statuses": "Toot", "search_results.statuses": "Toot",
"search_results.total": "{count} {count, plural, one {risultato} other {risultati}}", "search_results.total": "{count} {count, plural, one {risultato} other {risultati}}",
"standalone.public_title": "Un'occhiata all'interno...", "standalone.public_title": "Un'occhiata all'interno...",
"status.admin_account": "Open moderation interface for @{name}",
"status.admin_status": "Open this status in the moderation interface",
"status.block": "Block @{name}", "status.block": "Block @{name}",
"status.cancel_reblog_private": "Annulla condivisione", "status.cancel_reblog_private": "Annulla condivisione",
"status.cannot_reblog": "Questo post non può essere condiviso", "status.cannot_reblog": "Questo post non può essere condiviso",
@ -341,7 +343,7 @@
"upload_area.title": "Trascina per caricare", "upload_area.title": "Trascina per caricare",
"upload_button.label": "Aggiungi file multimediale", "upload_button.label": "Aggiungi file multimediale",
"upload_form.description": "Descrizione per utenti con disabilità visive", "upload_form.description": "Descrizione per utenti con disabilità visive",
"upload_form.focus": "Rifila", "upload_form.focus": "Modifica anteprima",
"upload_form.undo": "Cancella", "upload_form.undo": "Cancella",
"upload_progress.label": "Sto caricando...", "upload_progress.label": "Sto caricando...",
"video.close": "Chiudi video", "video.close": "Chiudi video",

@ -297,6 +297,8 @@
"search_results.statuses": "トゥート", "search_results.statuses": "トゥート",
"search_results.total": "{count, number}件の結果", "search_results.total": "{count, number}件の結果",
"standalone.public_title": "今こんな話をしています...", "standalone.public_title": "今こんな話をしています...",
"status.admin_account": "Open moderation interface for @{name}",
"status.admin_status": "Open this status in the moderation interface",
"status.block": "@{name}さんをブロック", "status.block": "@{name}さんをブロック",
"status.cancel_reblog_private": "ブースト解除", "status.cancel_reblog_private": "ブースト解除",
"status.cannot_reblog": "この投稿はブーストできません", "status.cannot_reblog": "この投稿はブーストできません",

@ -292,6 +292,8 @@
"search_results.statuses": "ტუტები", "search_results.statuses": "ტუტები",
"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": "შიდა ხედი...", "standalone.public_title": "შიდა ხედი...",
"status.admin_account": "Open moderation interface for @{name}",
"status.admin_status": "Open this status in the moderation interface",
"status.block": "დაბლოკე @{name}", "status.block": "დაბლოკე @{name}",
"status.cancel_reblog_private": "ბუსტის მოშორება", "status.cancel_reblog_private": "ბუსტის მოშორება",
"status.cannot_reblog": "ეს პოსტი ვერ დაიბუსტება", "status.cannot_reblog": "ეს პოსტი ვერ დაიბუსტება",

@ -132,7 +132,7 @@
"follow_request.authorize": "허가", "follow_request.authorize": "허가",
"follow_request.reject": "거부", "follow_request.reject": "거부",
"getting_started.developers": "개발자", "getting_started.developers": "개발자",
"getting_started.directory": "Profile directory", "getting_started.directory": "프로필 디렉터리",
"getting_started.documentation": "문서", "getting_started.documentation": "문서",
"getting_started.heading": "시작", "getting_started.heading": "시작",
"getting_started.invite": "초대", "getting_started.invite": "초대",
@ -292,6 +292,8 @@
"search_results.statuses": "툿", "search_results.statuses": "툿",
"search_results.total": "{count, number}건의 결과", "search_results.total": "{count, number}건의 결과",
"standalone.public_title": "지금 이런 이야기를 하고 있습니다…", "standalone.public_title": "지금 이런 이야기를 하고 있습니다…",
"status.admin_account": "Open moderation interface for @{name}",
"status.admin_status": "Open this status in the moderation interface",
"status.block": "@{name} 차단", "status.block": "@{name} 차단",
"status.cancel_reblog_private": "부스트 취소", "status.cancel_reblog_private": "부스트 취소",
"status.cannot_reblog": "이 포스트는 부스트 할 수 없습니다", "status.cannot_reblog": "이 포스트는 부스트 할 수 없습니다",
@ -341,7 +343,7 @@
"upload_area.title": "드래그 & 드롭으로 업로드", "upload_area.title": "드래그 & 드롭으로 업로드",
"upload_button.label": "미디어 추가 (JPEG, PNG, GIF, WebM, MP4, MOV)", "upload_button.label": "미디어 추가 (JPEG, PNG, GIF, WebM, MP4, MOV)",
"upload_form.description": "시각장애인을 위한 설명", "upload_form.description": "시각장애인을 위한 설명",
"upload_form.focus": "크롭", "upload_form.focus": "미리보기 변경",
"upload_form.undo": "삭제", "upload_form.undo": "삭제",
"upload_progress.label": "업로드 중...", "upload_progress.label": "업로드 중...",
"video.close": "동영상 닫기", "video.close": "동영상 닫기",

@ -0,0 +1,358 @@
{
"account.add_or_remove_from_list": "Add or Remove from lists",
"account.badges.bot": "Bot",
"account.block": "Block @{name}",
"account.block_domain": "Hide everything from {domain}",
"account.blocked": "Blocked",
"account.direct": "Direct message @{name}",
"account.disclaimer_full": "Information below may reflect the user's profile incompletely.",
"account.domain_blocked": "Domain hidden",
"account.edit_profile": "Edit profile",
"account.endorse": "Feature on profile",
"account.follow": "Follow",
"account.followers": "Followers",
"account.followers.empty": "No one follows this user yet.",
"account.follows": "Follows",
"account.follows.empty": "This user doesn't follow anyone yet.",
"account.follows_you": "Follows you",
"account.hide_reblogs": "Hide boosts from @{name}",
"account.link_verified_on": "Ownership of this link was checked on {date}",
"account.locked_info": "This account privacy status is set to locked. The owner manually reviews who can follow them.",
"account.media": "Media",
"account.mention": "Mention @{name}",
"account.moved_to": "{name} has moved to:",
"account.mute": "Mute @{name}",
"account.mute_notifications": "Mute notifications from @{name}",
"account.muted": "Muted",
"account.posts": "Toots",
"account.posts_with_replies": "Toots and replies",
"account.report": "Report @{name}",
"account.requested": "Awaiting approval. Click to cancel follow request",
"account.share": "Share @{name}'s profile",
"account.show_reblogs": "Show boosts from @{name}",
"account.unblock": "Unblock @{name}",
"account.unblock_domain": "Unhide {domain}",
"account.unendorse": "Don't feature on profile",
"account.unfollow": "Unfollow",
"account.unmute": "Unmute @{name}",
"account.unmute_notifications": "Unmute notifications from @{name}",
"account.view_full_profile": "View full profile",
"alert.unexpected.message": "An unexpected error occurred.",
"alert.unexpected.title": "Oops!",
"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.retry": "Try again",
"bundle_column_error.title": "Network error",
"bundle_modal_error.close": "Close",
"bundle_modal_error.message": "Something went wrong while loading this component.",
"bundle_modal_error.retry": "Try again",
"column.blocks": "Blocked users",
"column.community": "Local timeline",
"column.direct": "Direct messages",
"column.domain_blocks": "Hidden domains",
"column.favourites": "Favourites",
"column.follow_requests": "Follow requests",
"column.home": "Home",
"column.lists": "Lists",
"column.mutes": "Muted users",
"column.notifications": "Notifications",
"column.pins": "Pinned toot",
"column.public": "Federated timeline",
"column_back_button.label": "Back",
"column_header.hide_settings": "Hide settings",
"column_header.moveLeft_settings": "Move column to the left",
"column_header.moveRight_settings": "Move column to the right",
"column_header.pin": "Pin",
"column_header.show_settings": "Show settings",
"column_header.unpin": "Unpin",
"column_subheading.settings": "Settings",
"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_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.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.placeholder": "What is on your mind?",
"compose_form.publish": "Toot",
"compose_form.publish_loud": "{publish}!",
"compose_form.sensitive.marked": "Media is 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.unmarked": "Text is not hidden",
"compose_form.spoiler_placeholder": "Write your warning here",
"confirmation_modal.cancel": "Cancel",
"confirmations.block.confirm": "Block",
"confirmations.block.message": "Are you sure you want to block {name}?",
"confirmations.delete.confirm": "Delete",
"confirmations.delete.message": "Are you sure you want to delete this status?",
"confirmations.delete_list.confirm": "Delete",
"confirmations.delete_list.message": "Are you sure you want to permanently delete this list?",
"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.mute.confirm": "Mute",
"confirmations.mute.message": "Are you sure you want to mute {name}?",
"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.reply.confirm": "Reply",
"confirmations.reply.message": "Replying now will overwrite the message you are currently composing. Are you sure you want to proceed?",
"confirmations.unfollow.confirm": "Unfollow",
"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.preview": "Here is what it will look like:",
"emoji_button.activity": "Activity",
"emoji_button.custom": "Custom",
"emoji_button.flags": "Flags",
"emoji_button.food": "Food & Drink",
"emoji_button.label": "Insert emoji",
"emoji_button.nature": "Nature",
"emoji_button.not_found": "No emojos!! (╯°□°)╯︵ ┻━┻",
"emoji_button.objects": "Objects",
"emoji_button.people": "People",
"emoji_button.recent": "Frequently used",
"emoji_button.search": "Search...",
"emoji_button.search_results": "Search results",
"emoji_button.symbols": "Symbols",
"emoji_button.travel": "Travel & Places",
"empty_column.account_timeline": "No toots here!",
"empty_column.blocks": "You haven't blocked any users yet.",
"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.domain_blocks": "There are no hidden domains yet.",
"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.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.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.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.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.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.reject": "Reject",
"getting_started.developers": "Developers",
"getting_started.directory": "Profile directory",
"getting_started.documentation": "Documentation",
"getting_started.heading": "Getting started",
"getting_started.invite": "Invite people",
"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.terms": "Terms of service",
"hashtag.column_header.tag_mode.all": "and {additional}",
"hashtag.column_header.tag_mode.any": "or {additional}",
"hashtag.column_header.tag_mode.none": "without {additional}",
"hashtag.column_settings.tag_mode.all": "All of these",
"hashtag.column_settings.tag_mode.any": "Any of these",
"hashtag.column_settings.tag_mode.none": "None of these",
"hashtag.column_settings.tag_toggle": "Include additional tags in this column",
"home.column_settings.basic": "Basic",
"home.column_settings.show_reblogs": "Show boosts",
"home.column_settings.show_replies": "Show replies",
"introduction.federation.action": "Next",
"introduction.federation.federated.headline": "Federated",
"introduction.federation.federated.text": "Public posts from other servers of the fediverse will appear in the federated timeline.",
"introduction.federation.home.headline": "Home",
"introduction.federation.home.text": "Posts from people you follow will appear in your home feed. You can follow anyone on any server!",
"introduction.federation.local.headline": "Local",
"introduction.federation.local.text": "Public posts from people on the same server as you will appear in the local timeline.",
"introduction.interactions.action": "Finish tutorial!",
"introduction.interactions.favourite.headline": "Favourite",
"introduction.interactions.favourite.text": "You can save a toot for later, and let the author know that you liked it, by favouriting it.",
"introduction.interactions.reblog.headline": "Boost",
"introduction.interactions.reblog.text": "You can share other people's toots with your followers by boosting them.",
"introduction.interactions.reply.headline": "Reply",
"introduction.interactions.reply.text": "You can reply to other people's and your own toots, which will chain them together in a conversation.",
"introduction.welcome.action": "Let's go!",
"introduction.welcome.headline": "First steps",
"introduction.welcome.text": "Welcome to the fediverse! In a few moments, you'll be able to broadcast messages and talk to your friends across a wide variety of servers. But this server, {domain}, is special—it hosts your profile, so remember its name.",
"keyboard_shortcuts.back": "to navigate back",
"keyboard_shortcuts.blocked": "to open blocked users list",
"keyboard_shortcuts.boost": "to boost",
"keyboard_shortcuts.column": "to focus a status in one of the columns",
"keyboard_shortcuts.compose": "to focus the compose textarea",
"keyboard_shortcuts.description": "Description",
"keyboard_shortcuts.direct": "to open direct messages column",
"keyboard_shortcuts.down": "to move down in the list",
"keyboard_shortcuts.enter": "to open status",
"keyboard_shortcuts.favourite": "to favourite",
"keyboard_shortcuts.favourites": "to open favourites list",
"keyboard_shortcuts.federated": "to open federated timeline",
"keyboard_shortcuts.heading": "Keyboard Shortcuts",
"keyboard_shortcuts.home": "to open home timeline",
"keyboard_shortcuts.hotkey": "Hotkey",
"keyboard_shortcuts.legend": "to display this legend",
"keyboard_shortcuts.local": "to open local timeline",
"keyboard_shortcuts.mention": "to mention author",
"keyboard_shortcuts.muted": "to open muted users list",
"keyboard_shortcuts.my_profile": "to open your profile",
"keyboard_shortcuts.notifications": "to open notifications column",
"keyboard_shortcuts.pinned": "to open pinned toots list",
"keyboard_shortcuts.profile": "to open author's profile",
"keyboard_shortcuts.reply": "to reply",
"keyboard_shortcuts.requests": "to open follow requests list",
"keyboard_shortcuts.search": "to focus search",
"keyboard_shortcuts.start": "to open \"get started\" column",
"keyboard_shortcuts.toggle_hidden": "to show/hide text behind CW",
"keyboard_shortcuts.toot": "to start a brand new toot",
"keyboard_shortcuts.unfocus": "to un-focus compose textarea/search",
"keyboard_shortcuts.up": "to move up in the list",
"lightbox.close": "Close",
"lightbox.next": "Next",
"lightbox.previous": "Previous",
"lists.account.add": "Add to list",
"lists.account.remove": "Remove from list",
"lists.delete": "Delete list",
"lists.edit": "Edit list",
"lists.new.create": "Add list",
"lists.new.title_placeholder": "New list title",
"lists.search": "Search among people you follow",
"lists.subheading": "Your lists",
"loading_indicator.label": "Loading...",
"media_gallery.toggle_visible": "Toggle visibility",
"missing_indicator.label": "Not found",
"missing_indicator.sublabel": "This resource could not be found",
"mute_modal.hide_notifications": "Hide notifications from this user?",
"navigation_bar.apps": "Mobile apps",
"navigation_bar.blocks": "Blocked users",
"navigation_bar.community_timeline": "Local timeline",
"navigation_bar.compose": "Compose new toot",
"navigation_bar.direct": "Direct messages",
"navigation_bar.discover": "Discover",
"navigation_bar.domain_blocks": "Hidden domains",
"navigation_bar.edit_profile": "Edit profile",
"navigation_bar.favourites": "Favourites",
"navigation_bar.filters": "Muted words",
"navigation_bar.follow_requests": "Follow requests",
"navigation_bar.info": "About this instance",
"navigation_bar.keyboard_shortcuts": "Hotkeys",
"navigation_bar.lists": "Lists",
"navigation_bar.logout": "Logout",
"navigation_bar.mutes": "Muted users",
"navigation_bar.personal": "Personal",
"navigation_bar.pins": "Pinned toots",
"navigation_bar.preferences": "Preferences",
"navigation_bar.public_timeline": "Federated timeline",
"navigation_bar.security": "Security",
"notification.favourite": "{name} favourited your status",
"notification.follow": "{name} followed you",
"notification.mention": "{name} mentioned you",
"notification.reblog": "{name} boosted your status",
"notifications.clear": "Clear notifications",
"notifications.clear_confirmation": "Are you sure you want to permanently clear all your notifications?",
"notifications.column_settings.alert": "Desktop notifications",
"notifications.column_settings.favourite": "Favourites:",
"notifications.column_settings.filter_bar.advanced": "Display all categories",
"notifications.column_settings.filter_bar.category": "Quick filter bar",
"notifications.column_settings.filter_bar.show": "Show",
"notifications.column_settings.follow": "New followers:",
"notifications.column_settings.mention": "Mentions:",
"notifications.column_settings.push": "Push notifications",
"notifications.column_settings.reblog": "Boosts:",
"notifications.column_settings.show": "Show in column",
"notifications.column_settings.sound": "Play sound",
"notifications.filter.all": "All",
"notifications.filter.boosts": "Boosts",
"notifications.filter.favourites": "Favourites",
"notifications.filter.follows": "Follows",
"notifications.filter.mentions": "Mentions",
"notifications.group": "{count} notifications",
"privacy.change": "Adjust status privacy",
"privacy.direct.long": "Post to mentioned users only",
"privacy.direct.short": "Direct",
"privacy.private.long": "Post to followers only",
"privacy.private.short": "Followers-only",
"privacy.public.long": "Post to public timelines",
"privacy.public.short": "Public",
"privacy.unlisted.long": "Do not show in public timelines",
"privacy.unlisted.short": "Unlisted",
"regeneration_indicator.label": "Loading…",
"regeneration_indicator.sublabel": "Your home feed is being prepared!",
"relative_time.days": "{number}d",
"relative_time.hours": "{number}h",
"relative_time.just_now": "now",
"relative_time.minutes": "{number}m",
"relative_time.seconds": "{number}s",
"reply_indicator.cancel": "Cancel",
"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.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.submit": "Submit",
"report.target": "Report {target}",
"search.placeholder": "Search",
"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.hashtag": "hashtag",
"search_popout.tips.status": "status",
"search_popout.tips.text": "Simple text returns matching display names, usernames and hashtags",
"search_popout.tips.user": "user",
"search_results.accounts": "People",
"search_results.hashtags": "Hashtags",
"search_results.statuses": "Toots",
"search_results.total": "{count, number} {count, plural, one {result} other {results}}",
"standalone.public_title": "A look inside...",
"status.admin_account": "Open moderation interface for @{name}",
"status.admin_status": "Open this status in the moderation interface",
"status.block": "Block @{name}",
"status.cancel_reblog_private": "Unboost",
"status.cannot_reblog": "This post cannot be boosted",
"status.delete": "Delete",
"status.detailed_status": "Detailed conversation view",
"status.direct": "Direct message @{name}",
"status.embed": "Embed",
"status.favourite": "Favourite",
"status.filtered": "Filtered",
"status.load_more": "Load more",
"status.media_hidden": "Media hidden",
"status.mention": "Mention @{name}",
"status.more": "More",
"status.mute": "Mute @{name}",
"status.mute_conversation": "Mute conversation",
"status.open": "Expand this status",
"status.pin": "Pin on profile",
"status.pinned": "Pinned toot",
"status.read_more": "Read more",
"status.reblog": "Boost",
"status.reblog_private": "Boost to original audience",
"status.reblogged_by": "{name} boosted",
"status.reblogs.empty": "No one has boosted this toot yet. When someone does, they will show up here.",
"status.redraft": "Delete & re-draft",
"status.reply": "Reply",
"status.replyAll": "Reply to thread",
"status.report": "Report @{name}",
"status.sensitive_toggle": "Click to view",
"status.sensitive_warning": "Sensitive content",
"status.share": "Share",
"status.show_less": "Show less",
"status.show_less_all": "Show less for all",
"status.show_more": "Show more",
"status.show_more_all": "Show more for all",
"status.show_thread": "Show thread",
"status.unmute_conversation": "Unmute conversation",
"status.unpin": "Unpin from profile",
"suggestions.dismiss": "Dismiss suggestion",
"suggestions.header": "You might be interested in…",
"tabs_bar.federated_timeline": "Federated",
"tabs_bar.home": "Home",
"tabs_bar.local_timeline": "Local",
"tabs_bar.notifications": "Notifications",
"tabs_bar.search": "Search",
"trends.count_by_accounts": "{count} {rawCount, plural, one {person} other {people}} talking",
"ui.beforeunload": "Your draft will be lost if you leave Mastodon.",
"upload_area.title": "Drag & drop to upload",
"upload_button.label": "Add media (JPEG, PNG, GIF, WebM, MP4, MOV)",
"upload_form.description": "Describe for the visually impaired",
"upload_form.focus": "Crop",
"upload_form.undo": "Delete",
"upload_progress.label": "Uploading...",
"video.close": "Close video",
"video.exit_fullscreen": "Exit full screen",
"video.expand": "Expand video",
"video.fullscreen": "Full screen",
"video.hide": "Hide video",
"video.mute": "Mute sound",
"video.pause": "Pause",
"video.play": "Play",
"video.unmute": "Unmute sound"
}

@ -292,6 +292,8 @@
"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.admin_account": "Open moderation interface for @{name}",
"status.admin_status": "Open this status in the moderation interface",
"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",

@ -132,7 +132,7 @@
"follow_request.authorize": "Goedkeuren", "follow_request.authorize": "Goedkeuren",
"follow_request.reject": "Afkeuren", "follow_request.reject": "Afkeuren",
"getting_started.developers": "Ontwikkelaars", "getting_started.developers": "Ontwikkelaars",
"getting_started.directory": "Profile directory", "getting_started.directory": "Gebruikersgids",
"getting_started.documentation": "Documentatie", "getting_started.documentation": "Documentatie",
"getting_started.heading": "Aan de slag", "getting_started.heading": "Aan de slag",
"getting_started.invite": "Mensen uitnodigen", "getting_started.invite": "Mensen uitnodigen",
@ -292,6 +292,8 @@
"search_results.statuses": "Toots", "search_results.statuses": "Toots",
"search_results.total": "{count, number} {count, plural, one {resultaat} other {resultaten}}", "search_results.total": "{count, number} {count, plural, one {resultaat} other {resultaten}}",
"standalone.public_title": "Een kijkje binnenin...", "standalone.public_title": "Een kijkje binnenin...",
"status.admin_account": "Open moderation interface for @{name}",
"status.admin_status": "Open this status in the moderation interface",
"status.block": "Blokkeer @{name}", "status.block": "Blokkeer @{name}",
"status.cancel_reblog_private": "Niet langer boosten", "status.cancel_reblog_private": "Niet langer boosten",
"status.cannot_reblog": "Deze toot kan niet geboost worden", "status.cannot_reblog": "Deze toot kan niet geboost worden",
@ -341,7 +343,7 @@
"upload_area.title": "Hierin slepen om te uploaden", "upload_area.title": "Hierin slepen om te uploaden",
"upload_button.label": "Media toevoegen (JPEG, PNG, GIF, WebM, MP4, MOV)", "upload_button.label": "Media toevoegen (JPEG, PNG, GIF, WebM, MP4, MOV)",
"upload_form.description": "Omschrijf dit voor mensen met een visuele beperking", "upload_form.description": "Omschrijf dit voor mensen met een visuele beperking",
"upload_form.focus": "Bijsnijden", "upload_form.focus": "Voorvertoning aanpassen",
"upload_form.undo": "Verwijderen", "upload_form.undo": "Verwijderen",
"upload_progress.label": "Uploaden...", "upload_progress.label": "Uploaden...",
"video.close": "Video sluiten", "video.close": "Video sluiten",

@ -292,6 +292,8 @@
"search_results.statuses": "Toots", "search_results.statuses": "Toots",
"search_results.total": "{count, number} {count, plural, one {resultat} other {resultater}}", "search_results.total": "{count, number} {count, plural, one {resultat} other {resultater}}",
"standalone.public_title": "En titt inni...", "standalone.public_title": "En titt inni...",
"status.admin_account": "Open moderation interface for @{name}",
"status.admin_status": "Open this status in the moderation interface",
"status.block": "Block @{name}", "status.block": "Block @{name}",
"status.cancel_reblog_private": "Unboost", "status.cancel_reblog_private": "Unboost",
"status.cannot_reblog": "Denne posten kan ikke fremheves", "status.cannot_reblog": "Denne posten kan ikke fremheves",

@ -132,7 +132,7 @@
"follow_request.authorize": "Acceptar", "follow_request.authorize": "Acceptar",
"follow_request.reject": "Regetar", "follow_request.reject": "Regetar",
"getting_started.developers": "Desvelopaires", "getting_started.developers": "Desvelopaires",
"getting_started.directory": "Profile directory", "getting_started.directory": "Annuari de perfils",
"getting_started.documentation": "Documentacion", "getting_started.documentation": "Documentacion",
"getting_started.heading": "Per començar", "getting_started.heading": "Per començar",
"getting_started.invite": "Convidar de monde", "getting_started.invite": "Convidar de monde",
@ -242,9 +242,9 @@
"notifications.clear_confirmation": "Volètz vertadièrament escafar totas vòstras las notificacions?", "notifications.clear_confirmation": "Volètz vertadièrament escafar totas vòstras las notificacions?",
"notifications.column_settings.alert": "Notificacions localas", "notifications.column_settings.alert": "Notificacions localas",
"notifications.column_settings.favourite": "Favorits:", "notifications.column_settings.favourite": "Favorits:",
"notifications.column_settings.filter_bar.advanced": "Display all categories", "notifications.column_settings.filter_bar.advanced": "Mostrar totas las categorias",
"notifications.column_settings.filter_bar.category": "Quick filter bar", "notifications.column_settings.filter_bar.category": "Barra de recèrca rapida",
"notifications.column_settings.filter_bar.show": "Show", "notifications.column_settings.filter_bar.show": "Mostrar",
"notifications.column_settings.follow": "Nòus seguidors:", "notifications.column_settings.follow": "Nòus seguidors:",
"notifications.column_settings.mention": "Mencions:", "notifications.column_settings.mention": "Mencions:",
"notifications.column_settings.push": "Notificacions", "notifications.column_settings.push": "Notificacions",
@ -292,6 +292,8 @@
"search_results.statuses": "Tuts", "search_results.statuses": "Tuts",
"search_results.total": "{count, number} {count, plural, one {resultat} other {resultats}}", "search_results.total": "{count, number} {count, plural, one {resultat} other {resultats}}",
"standalone.public_title": "Una ulhada dedins…", "standalone.public_title": "Una ulhada dedins…",
"status.admin_account": "Open moderation interface for @{name}",
"status.admin_status": "Open this status in the moderation interface",
"status.block": "Blocar @{name}", "status.block": "Blocar @{name}",
"status.cancel_reblog_private": "Quitar de partejar", "status.cancel_reblog_private": "Quitar de partejar",
"status.cannot_reblog": "Aqueste estatut pòt pas èsser partejat", "status.cannot_reblog": "Aqueste estatut pòt pas èsser partejat",

@ -297,6 +297,8 @@
"search_results.statuses": "Wpisy", "search_results.statuses": "Wpisy",
"search_results.total": "{count, number} {count, plural, one {wynik} few {wyniki} many {wyników} more {wyników}}", "search_results.total": "{count, number} {count, plural, one {wynik} few {wyniki} many {wyników} more {wyników}}",
"standalone.public_title": "Spojrzenie w głąb…", "standalone.public_title": "Spojrzenie w głąb…",
"status.admin_account": "Open moderation interface for @{name}",
"status.admin_status": "Open this status in the moderation interface",
"status.block": "Zablokuj @{name}", "status.block": "Zablokuj @{name}",
"status.cancel_reblog_private": "Cofnij podbicie", "status.cancel_reblog_private": "Cofnij podbicie",
"status.cannot_reblog": "Ten wpis nie może zostać podbity", "status.cannot_reblog": "Ten wpis nie może zostać podbity",
@ -346,7 +348,7 @@
"upload_area.title": "Przeciągnij i upuść aby wysłać", "upload_area.title": "Przeciągnij i upuść aby wysłać",
"upload_button.label": "Dodaj zawartość multimedialną (JPEG, PNG, GIF, WebM, MP4, MOV)", "upload_button.label": "Dodaj zawartość multimedialną (JPEG, PNG, GIF, WebM, MP4, MOV)",
"upload_form.description": "Wprowadź opis dla niewidomych i niedowidzących", "upload_form.description": "Wprowadź opis dla niewidomych i niedowidzących",
"upload_form.focus": "Przytnij", "upload_form.focus": "Dopasuj podgląd",
"upload_form.undo": "Usuń", "upload_form.undo": "Usuń",
"upload_progress.label": "Wysyłanie...", "upload_progress.label": "Wysyłanie...",
"video.close": "Zamknij film", "video.close": "Zamknij film",

@ -132,7 +132,7 @@
"follow_request.authorize": "Autorizar", "follow_request.authorize": "Autorizar",
"follow_request.reject": "Rejeitar", "follow_request.reject": "Rejeitar",
"getting_started.developers": "Desenvolvedores", "getting_started.developers": "Desenvolvedores",
"getting_started.directory": "Profile directory", "getting_started.directory": "Diretório de perfis",
"getting_started.documentation": "Documentação", "getting_started.documentation": "Documentação",
"getting_started.heading": "Primeiros passos", "getting_started.heading": "Primeiros passos",
"getting_started.invite": "Convide pessoas", "getting_started.invite": "Convide pessoas",
@ -149,23 +149,23 @@
"home.column_settings.basic": "Básico", "home.column_settings.basic": "Básico",
"home.column_settings.show_reblogs": "Mostrar compartilhamentos", "home.column_settings.show_reblogs": "Mostrar compartilhamentos",
"home.column_settings.show_replies": "Mostrar as respostas", "home.column_settings.show_replies": "Mostrar as respostas",
"introduction.federation.action": "Next", "introduction.federation.action": "Próximo",
"introduction.federation.federated.headline": "Federated", "introduction.federation.federated.headline": "Federated",
"introduction.federation.federated.text": "Public posts from other servers of the fediverse will appear in the federated timeline.", "introduction.federation.federated.text": "Posts públicos de outros servidores do fediverso vão aparecer na timeline global.",
"introduction.federation.home.headline": "Home", "introduction.federation.home.headline": "Home",
"introduction.federation.home.text": "Posts from people you follow will appear in your home feed. You can follow anyone on any server!", "introduction.federation.home.text": "Posts de pessoas que você segue vão aparecer na sua página inicial. Você pode seguir pessoas de qualquer servidor!",
"introduction.federation.local.headline": "Local", "introduction.federation.local.headline": "Local",
"introduction.federation.local.text": "Public posts from people on the same server as you will appear in the local timeline.", "introduction.federation.local.text": "Posts públicos de pessoas no mesmo servidor que você vão aparecer na timeline local.",
"introduction.interactions.action": "Finish tutorial!", "introduction.interactions.action": "Finalizar o tutorial!",
"introduction.interactions.favourite.headline": "Favourite", "introduction.interactions.favourite.headline": "Favoritos",
"introduction.interactions.favourite.text": "You can save a toot for later, and let the author know that you liked it, by favouriting it.", "introduction.interactions.favourite.text": "Você pode salvar um toot pra mais tarde, e deixar a pessoa que postou saber que você gostou, favoritando-o.",
"introduction.interactions.reblog.headline": "Boost", "introduction.interactions.reblog.headline": "Compartilhamento",
"introduction.interactions.reblog.text": "You can share other people's toots with your followers by boosting them.", "introduction.interactions.reblog.text": "Você pode mostrar toots de outras pessoas aos seus seguidores compartilhando.",
"introduction.interactions.reply.headline": "Reply", "introduction.interactions.reply.headline": "Responder",
"introduction.interactions.reply.text": "You can reply to other people's and your own toots, which will chain them together in a conversation.", "introduction.interactions.reply.text": "Você pode responder a toots de outras pessoas e aos seus, e isso vai uni-los em uma conversa.",
"introduction.welcome.action": "Let's go!", "introduction.welcome.action": "Vamos!",
"introduction.welcome.headline": "First steps", "introduction.welcome.headline": "Primeiros passos",
"introduction.welcome.text": "Welcome to the fediverse! In a few moments, you'll be able to broadcast messages and talk to your friends across a wide variety of servers. But this server, {domain}, is special—it hosts your profile, so remember its name.", "introduction.welcome.text": "Boas vindas ao fediverso! Em alguns momentos, você vai poder transmitir mensagens e falar com pessoas amigas através de uma variedade de servidores. Mas esse servidor, {domain}, é especial—é onde o seu perfil está hospedado, então lembre do nome.",
"keyboard_shortcuts.back": "para navegar de volta", "keyboard_shortcuts.back": "para navegar de volta",
"keyboard_shortcuts.blocked": "para abrir a lista de usuários bloqueados", "keyboard_shortcuts.blocked": "para abrir a lista de usuários bloqueados",
"keyboard_shortcuts.boost": "para compartilhar", "keyboard_shortcuts.boost": "para compartilhar",
@ -242,20 +242,20 @@
"notifications.clear_confirmation": "Você tem certeza de que quer limpar todas as suas notificações permanentemente?", "notifications.clear_confirmation": "Você tem certeza de que quer limpar todas as suas notificações permanentemente?",
"notifications.column_settings.alert": "Notificações no computador", "notifications.column_settings.alert": "Notificações no computador",
"notifications.column_settings.favourite": "Favoritos:", "notifications.column_settings.favourite": "Favoritos:",
"notifications.column_settings.filter_bar.advanced": "Display all categories", "notifications.column_settings.filter_bar.advanced": "Mostrar todas as categorias",
"notifications.column_settings.filter_bar.category": "Quick filter bar", "notifications.column_settings.filter_bar.category": "Barra de filtro rápido",
"notifications.column_settings.filter_bar.show": "Show", "notifications.column_settings.filter_bar.show": "Mostrar",
"notifications.column_settings.follow": "Novos seguidores:", "notifications.column_settings.follow": "Novos seguidores:",
"notifications.column_settings.mention": "Menções:", "notifications.column_settings.mention": "Menções:",
"notifications.column_settings.push": "Enviar notificações", "notifications.column_settings.push": "Enviar notificações",
"notifications.column_settings.reblog": "Compartilhamento:", "notifications.column_settings.reblog": "Compartilhamento:",
"notifications.column_settings.show": "Mostrar nas colunas", "notifications.column_settings.show": "Mostrar nas colunas",
"notifications.column_settings.sound": "Reproduzir som", "notifications.column_settings.sound": "Reproduzir som",
"notifications.filter.all": "All", "notifications.filter.all": "Tudo",
"notifications.filter.boosts": "Boosts", "notifications.filter.boosts": "Compartilhamentos",
"notifications.filter.favourites": "Favourites", "notifications.filter.favourites": "Favoritos",
"notifications.filter.follows": "Follows", "notifications.filter.follows": "Seguidores",
"notifications.filter.mentions": "Mentions", "notifications.filter.mentions": "Menções",
"notifications.group": "{count} notificações", "notifications.group": "{count} notificações",
"privacy.change": "Ajustar a privacidade da mensagem", "privacy.change": "Ajustar a privacidade da mensagem",
"privacy.direct.long": "Apenas para usuários mencionados", "privacy.direct.long": "Apenas para usuários mencionados",
@ -292,6 +292,8 @@
"search_results.statuses": "Toots", "search_results.statuses": "Toots",
"search_results.total": "{count, number} {count, plural, one {resultado} other {resultados}}", "search_results.total": "{count, number} {count, plural, one {resultado} other {resultados}}",
"standalone.public_title": "Dê uma espiada...", "standalone.public_title": "Dê uma espiada...",
"status.admin_account": "Open moderation interface for @{name}",
"status.admin_status": "Open this status in the moderation interface",
"status.block": "Block @{name}", "status.block": "Block @{name}",
"status.cancel_reblog_private": "Desfazer compartilhamento", "status.cancel_reblog_private": "Desfazer compartilhamento",
"status.cannot_reblog": "Esta postagem não pode ser compartilhada", "status.cannot_reblog": "Esta postagem não pode ser compartilhada",

@ -292,6 +292,8 @@
"search_results.statuses": "Toots", "search_results.statuses": "Toots",
"search_results.total": "{count, number} {count, plural, one {resultado} other {resultados}}", "search_results.total": "{count, number} {count, plural, one {resultado} other {resultados}}",
"standalone.public_title": "Espreitar lá dentro...", "standalone.public_title": "Espreitar lá dentro...",
"status.admin_account": "Open moderation interface for @{name}",
"status.admin_status": "Open this status in the moderation interface",
"status.block": "Block @{name}", "status.block": "Block @{name}",
"status.cancel_reblog_private": "Unboost", "status.cancel_reblog_private": "Unboost",
"status.cannot_reblog": "Este post não pode ser partilhado", "status.cannot_reblog": "Este post não pode ser partilhado",

@ -1,23 +1,23 @@
{ {
"account.add_or_remove_from_list": "Add or Remove from lists", "account.add_or_remove_from_list": "Adaugă sau Elimină din liste",
"account.badges.bot": "Bot", "account.badges.bot": "Bot",
"account.block": "Blochează @{name}", "account.block": "Blochează @{name}",
"account.block_domain": "Ascunde tot de la {domain}", "account.block_domain": "Ascunde tot de la {domain}",
"account.blocked": "Blocat", "account.blocked": "Blocat",
"account.direct": "Mesaj direct @{name}", "account.direct": "Mesaj direct @{name}",
"account.disclaimer_full": "Informațiile de mai jos pot reflecta profilul incomplet al utilizatorului.", "account.disclaimer_full": "Informațiile de mai jos pot reflecta profilul utilizatorului incomplet.",
"account.domain_blocked": "Domeniu ascuns", "account.domain_blocked": "Domeniu ascuns",
"account.edit_profile": "Editează profilul", "account.edit_profile": "Editează profilul",
"account.endorse": "Redistribuie pe profil", "account.endorse": "Redistribuie pe profil",
"account.follow": "Urmărește", "account.follow": "Urmărește",
"account.followers": "Urmăritori", "account.followers": "Urmăritori",
"account.followers.empty": "Nimeni nu urmărește acest utilizator incă.", "account.followers.empty": "Acest utilizator nu are încă urmăritori.",
"account.follows": "Urmărește", "account.follows": "Urmărește",
"account.follows.empty": "Acest utilizator nu urmărește pe nimeni incă.", "account.follows.empty": "Acest utilizator nu urmărește pe nimeni incă.",
"account.follows_you": "Te urmărește", "account.follows_you": "Te urmărește",
"account.hide_reblogs": "Ascunde redistribuirile de la @{name}", "account.hide_reblogs": "Ascunde redistribuirile de la @{name}",
"account.link_verified_on": "Ownership of this link was checked on {date}", "account.link_verified_on": "Deținerea acestui link a fost verificată la {date}",
"account.locked_info": "This account privacy status is set to locked. The owner manually reviews who can follow them.", "account.locked_info": "Acest profil este privat. Această persoană gestioneaz manual cine o urmărește.",
"account.media": "Media", "account.media": "Media",
"account.mention": "Menționează @{name}", "account.mention": "Menționează @{name}",
"account.moved_to": "{name} a fost mutat la:", "account.moved_to": "{name} a fost mutat la:",
@ -27,22 +27,22 @@
"account.posts": "Postări", "account.posts": "Postări",
"account.posts_with_replies": "Postări și replici", "account.posts_with_replies": "Postări și replici",
"account.report": "Raportează @{name}", "account.report": "Raportează @{name}",
"account.requested": "Așteaptă aprobare. Apasă pentru a anula cererea de urmărire", "account.requested": "Se așteaptă aprobarea. Apasă pentru a anula cererea de urmărire",
"account.share": "Distribuie profilul lui @{name}", "account.share": "Distribuie profilul lui @{name}",
"account.show_reblogs": "Arată redistribuirile de la @{name}", "account.show_reblogs": "Arată redistribuirile de la @{name}",
"account.unblock": "Deblochează @{name}", "account.unblock": "Deblochează @{name}",
"account.unblock_domain": "Arată {domain}", "account.unblock_domain": "Arată {domain}",
"account.unendorse": "Nu promova pe profil", "account.unendorse": "Nu promova pe profil",
"account.unfollow": "Nu mai urmări", "account.unfollow": "Nu mai urmări",
"account.unmute": "Pornește notificările @{name}", "account.unmute": "Activează notificările de la @{name}",
"account.unmute_notifications": "Pornește notificările de la @{name}", "account.unmute_notifications": "Activează notificările de la @{name}",
"account.view_full_profile": "Vezi profilul complet", "account.view_full_profile": "Vezi profilul complet",
"alert.unexpected.message": "A apărut o eroare neașteptată.", "alert.unexpected.message": "A apărut o eroare neașteptată.",
"alert.unexpected.title": "Hopa!", "alert.unexpected.title": "Hopa!",
"boost_modal.combo": "Poți apăsa {combo} pentru a sări peste asta data viitoare", "boost_modal.combo": "Poți apăsa {combo} pentru a omite asta data viitoare",
"bundle_column_error.body": "Ceva nu a funcționat la încărcarea acestui component.", "bundle_column_error.body": "Ceva nu a funcționat la încărcarea acestui component.",
"bundle_column_error.retry": "Încearcă din nou", "bundle_column_error.retry": "Încearcă din nou",
"bundle_column_error.title": "Eoare de rețea", "bundle_column_error.title": "Eroare de rețea",
"bundle_modal_error.close": "Închide", "bundle_modal_error.close": "Închide",
"bundle_modal_error.message": "Ceva nu a funcționat în timupul încărcării acestui component.", "bundle_modal_error.message": "Ceva nu a funcționat în timupul încărcării acestui component.",
"bundle_modal_error.retry": "Încearcă din nou", "bundle_modal_error.retry": "Încearcă din nou",
@ -70,16 +70,16 @@
"compose_form.direct_message_warning": "Această postare va fi trimisă doar utilizatorilor menționați.", "compose_form.direct_message_warning": "Această postare va fi trimisă doar utilizatorilor menționați.",
"compose_form.direct_message_warning_learn_more": "Află mai multe", "compose_form.direct_message_warning_learn_more": "Află mai multe",
"compose_form.hashtag_warning": "Această postare nu va fi listată sub nici un hastag. Doar postările publice pot fi găsite dupa un hastag.", "compose_form.hashtag_warning": "Această postare nu va fi listată sub nici un hastag. Doar postările publice pot fi găsite dupa un hastag.",
"compose_form.lock_disclaimer": "Contul tău nu este {locked}. Toată lumea te poate urmări pentru a vedea postările doar pentru urmăritori.", "compose_form.lock_disclaimer": "Contul tău nu este {locked}. Oricine te poate urmări fără aprobarea ta și vedea toate postările tale.",
"compose_form.lock_disclaimer.lock": "privat", "compose_form.lock_disclaimer.lock": "privat",
"compose_form.placeholder": "La ce te gândești?", "compose_form.placeholder": "La ce te gândești?",
"compose_form.publish": "Postează", "compose_form.publish": "Postează",
"compose_form.publish_loud": "{publish}!", "compose_form.publish_loud": "{publish}!",
"compose_form.sensitive.marked": "Conținutul media este marcat ca sensibil", "compose_form.sensitive.marked": "Conținutul media este marcat ca sensibil",
"compose_form.sensitive.unmarked": "Conținutul media nu este marcat ca sensibil", "compose_form.sensitive.unmarked": "Conținutul media nu este marcat ca sensibil",
"compose_form.spoiler.marked": "Textul este ascuns sub advertizare", "compose_form.spoiler.marked": "Textul este ascuns sub o avertizare",
"compose_form.spoiler.unmarked": "Textul nu este ascuns", "compose_form.spoiler.unmarked": "Textul nu este ascuns",
"compose_form.spoiler_placeholder": "Scrie adveritzarea aici", "compose_form.spoiler_placeholder": "Scrie averitzarea aici",
"confirmation_modal.cancel": "Anulează", "confirmation_modal.cancel": "Anulează",
"confirmations.block.confirm": "Blochează", "confirmations.block.confirm": "Blochează",
"confirmations.block.message": "Ești sigur că vrei să blochezi {name}?", "confirmations.block.message": "Ești sigur că vrei să blochezi {name}?",
@ -88,13 +88,13 @@
"confirmations.delete_list.confirm": "Șterge", "confirmations.delete_list.confirm": "Șterge",
"confirmations.delete_list.message": "Ești sigur că vrei să ștergi permanent această listă?", "confirmations.delete_list.message": "Ești sigur că vrei să ștergi permanent această listă?",
"confirmations.domain_block.confirm": "Ascunde tot domeniul", "confirmations.domain_block.confirm": "Ascunde tot domeniul",
"confirmations.domain_block.message": "Ești absolut sigur că vrei să blochezi complet {domain}? În cele mai multe cazuri raportarea sau oprirea anumitor lucruri este suficientă și de preferat. Nu vei mai vedea nici un conținut de la acest domeniu in nici un flux public sau în notificările tale. Urmăritorii tăi de la acele domenii vor fi retrași.", "confirmations.domain_block.message": "Ești absolut sigur că vrei să blochezi complet {domain}? În cele mai multe cazuri raportarea sau oprirea anumitor lucruri este suficientă și de preferat. Nu vei mai vedea nici un conținut de la acest domeniu in nici un flux public sau în notificările tale. Urmăritorii tăi de la acele domenii vor fi eliminați.",
"confirmations.mute.confirm": "Oprește", "confirmations.mute.confirm": "Oprește",
"confirmations.mute.message": "Ești sigur că vrei să oprești {name}?", "confirmations.mute.message": "Ești sigur că vrei să oprești {name}?",
"confirmations.redraft.confirm": "Șterge și salvează ca ciornă", "confirmations.redraft.confirm": "Șterge și salvează ca ciornă",
"confirmations.redraft.message": "Ești sigur că vrei să faci asta? Tot ce ține de această postare, inclusiv răspunsurile vor fi deconectate.", "confirmations.redraft.message": "Ești sigur că vrei să faci asta? Tot ce ține de această postare, inclusiv răspunsurile vor fi deconectate.",
"confirmations.reply.confirm": "Reply", "confirmations.reply.confirm": "Răspunde",
"confirmations.reply.message": "Replying now will overwrite the message you are currently composing. Are you sure you want to proceed?", "confirmations.reply.message": "Răspunzând la asta acum, mesajul pe care îl compui în prezent se va șterge. Ești sigur că vrei să continui?",
"confirmations.unfollow.confirm": "Nu mai urmări", "confirmations.unfollow.confirm": "Nu mai urmări",
"confirmations.unfollow.message": "Ești sigur că nu mai vrei să îl urmărești pe {name}?", "confirmations.unfollow.message": "Ești sigur că nu mai vrei să îl urmărești pe {name}?",
"embed.instructions": "Inserează această postare pe site-ul tău adăugând codul de mai jos.", "embed.instructions": "Inserează această postare pe site-ul tău adăugând codul de mai jos.",
@ -113,15 +113,15 @@
"emoji_button.search_results": "Rezultatele căutării", "emoji_button.search_results": "Rezultatele căutării",
"emoji_button.symbols": "Simboluri", "emoji_button.symbols": "Simboluri",
"emoji_button.travel": "Călătorii si Locuri", "emoji_button.travel": "Călătorii si Locuri",
"empty_column.account_timeline": "No toots here!", "empty_column.account_timeline": "Nici o postare aici!",
"empty_column.blocks": "Nu ai blocat nici un utilizator incă.", "empty_column.blocks": "Nu ai blocat nici un utilizator incă.",
"empty_column.community": "Fluxul local este gol. Scrie ceva public pentru a împinge bila la vale!", "empty_column.community": "Fluxul local este gol. Scrie ceva public pentru a împinge bila la vale!",
"empty_column.direct": "Nu ai nici un mesaj direct incă. Când trimiți sau primești unul, vor fi afișate aici.", "empty_column.direct": "Nu ai nici un mesaj direct incă. Când trimiți sau primești unul, va fi afișat aici.",
"empty_column.domain_blocks": "Nu sunt domenii ascunse incă.", "empty_column.domain_blocks": "Nu sunt domenii ascunse incă.",
"empty_column.favourited_statuses": "Nu ai nici o postare favorită încă. Când vei avea, vor fi afișate aici.", "empty_column.favourited_statuses": "Nu ai nici o postare favorită încă. Când vei avea, vor fi afișate aici.",
"empty_column.favourites": "Nimeni nu are această postare adăugată la favorite. Când cineva o va face va fi afișat aici.", "empty_column.favourites": "Nimeni nu are această postare adăugată la favorite. Când cineva o va face va fi afișat aici.",
"empty_column.follow_requests": "Nu ai încă nici o cerere de urmărire. Când vei primi una, va fi afișată aici.", "empty_column.follow_requests": "Nu ai încă nici o cerere de urmărire. Când vei primi una, va fi afișată aici.",
"empty_column.hashtag": "Acest hastag nu a fost folosit încă nicăieri.", "empty_column.hashtag": "Acest hastag nu a fost folosit încă.",
"empty_column.home": "Fluxul tău este gol. Vizitează {public} sau fă o căutare pentru a începe să cunoști oameni noi.", "empty_column.home": "Fluxul tău este gol. Vizitează {public} sau fă o căutare pentru a începe să cunoști oameni noi.",
"empty_column.home.public_timeline": "fluxul public", "empty_column.home.public_timeline": "fluxul public",
"empty_column.list": "Nu este nimic încă în această listă. Când membrii acestei liste vor începe să posteze, va apărea aici.", "empty_column.list": "Nu este nimic încă în această listă. Când membrii acestei liste vor începe să posteze, va apărea aici.",
@ -132,77 +132,77 @@
"follow_request.authorize": "Autorizează", "follow_request.authorize": "Autorizează",
"follow_request.reject": "Respinge", "follow_request.reject": "Respinge",
"getting_started.developers": "Dezvoltatori", "getting_started.developers": "Dezvoltatori",
"getting_started.directory": "Profile directory", "getting_started.directory": "Directorul profilului",
"getting_started.documentation": "Documentație", "getting_started.documentation": "Documentație",
"getting_started.heading": "Începe", "getting_started.heading": "Începe",
"getting_started.invite": "Invită oameni", "getting_started.invite": "Invită prieteni",
"getting_started.open_source_notice": "Mastodon este o rețea de socializare de tip open source. Puteți contribuii la dezvoltarea ei sau să semnalați erorile pe GitHub la {github}.", "getting_started.open_source_notice": "Mastodon este o rețea de socializare de tip open source. Puteți contribuii la dezvoltarea ei sau să semnalați erorile pe GitHub la {github}.",
"getting_started.security": "Securitate", "getting_started.security": "Securitate",
"getting_started.terms": "Termenii de Utilizare", "getting_started.terms": "Termeni de Utilizare",
"hashtag.column_header.tag_mode.all": "and {additional}", "hashtag.column_header.tag_mode.all": "și {additional}",
"hashtag.column_header.tag_mode.any": "or {additional}", "hashtag.column_header.tag_mode.any": "sau {additional}",
"hashtag.column_header.tag_mode.none": "without {additional}", "hashtag.column_header.tag_mode.none": "fără {additional}",
"hashtag.column_settings.tag_mode.all": "All of these", "hashtag.column_settings.tag_mode.all": "Toate acestea",
"hashtag.column_settings.tag_mode.any": "Any of these", "hashtag.column_settings.tag_mode.any": "Oricare din acestea",
"hashtag.column_settings.tag_mode.none": "None of these", "hashtag.column_settings.tag_mode.none": "Niciuna din aceastea",
"hashtag.column_settings.tag_toggle": "Include additional tags in this column", "hashtag.column_settings.tag_toggle": "Adaugă etichete adiționale pentru această coloană",
"home.column_settings.basic": "De bază", "home.column_settings.basic": "De bază",
"home.column_settings.show_reblogs": "Arată redistribuirile", "home.column_settings.show_reblogs": "Arată redistribuirile",
"home.column_settings.show_replies": "Arată răspunsurile", "home.column_settings.show_replies": "Arată răspunsurile",
"introduction.federation.action": "Next", "introduction.federation.action": "Următorul",
"introduction.federation.federated.headline": "Federated", "introduction.federation.federated.headline": "Federalizat",
"introduction.federation.federated.text": "Public posts from other servers of the fediverse will appear in the federated timeline.", "introduction.federation.federated.text": "Postările publice de pe alte servere din rețea vor apărea in fluxul global.",
"introduction.federation.home.headline": "Home", "introduction.federation.home.headline": "Acasă",
"introduction.federation.home.text": "Posts from people you follow will appear in your home feed. You can follow anyone on any server!", "introduction.federation.home.text": "Postările de la persoanele pe care le urmărești vor apărea in fluxul tău \"Acasă\". Poți urmări pe orice de pe orice server!",
"introduction.federation.local.headline": "Local", "introduction.federation.local.headline": "Local",
"introduction.federation.local.text": "Public posts from people on the same server as you will appear in the local timeline.", "introduction.federation.local.text": "Postările publice de la persoanele de pe acest server vor apărea în fluxul local.",
"introduction.interactions.action": "Finish tutorial!", "introduction.interactions.action": "Încheie ghidul!",
"introduction.interactions.favourite.headline": "Favourite", "introduction.interactions.favourite.headline": "Favorite",
"introduction.interactions.favourite.text": "You can save a toot for later, and let the author know that you liked it, by favouriting it.", "introduction.interactions.favourite.text": "Poți salva o postare pentru a fi citită mai târziu și poți lăsa autorul să știe că iți place adăugândo la favorite.",
"introduction.interactions.reblog.headline": "Boost", "introduction.interactions.reblog.headline": "Redistribuie",
"introduction.interactions.reblog.text": "You can share other people's toots with your followers by boosting them.", "introduction.interactions.reblog.text": "Poți împărtăși postările altora cu urmăritorii tăi redistribuindule.",
"introduction.interactions.reply.headline": "Reply", "introduction.interactions.reply.headline": "Răspunde",
"introduction.interactions.reply.text": "You can reply to other people's and your own toots, which will chain them together in a conversation.", "introduction.interactions.reply.text": "Poți răspunde la postările tale și alte altora, care se vor lărgii în discuții.",
"introduction.welcome.action": "Let's go!", "introduction.welcome.action": "Să începem!",
"introduction.welcome.headline": "First steps", "introduction.welcome.headline": "Primii pași",
"introduction.welcome.text": "Welcome to the fediverse! In a few moments, you'll be able to broadcast messages and talk to your friends across a wide variety of servers. But this server, {domain}, is special—it hosts your profile, so remember its name.", "introduction.welcome.text": "Bun Venit in federație! In câteva momente, vei putea să transmiți mesaje și să participi la discuții cu oameni noi intr-o varietate foarte largă de servere din întreaga lume. Dar în special acest server, {domain},găzduiește profilul tău, deci reține numele acestuia.",
"keyboard_shortcuts.back": "navighează inapoi", "keyboard_shortcuts.back": "navighează inapoi",
"keyboard_shortcuts.blocked": "să deschidă lista utilizatorilor blocați", "keyboard_shortcuts.blocked": "să deschidă lista utilizatorilor blocați",
"keyboard_shortcuts.boost": "să redistribuie", "keyboard_shortcuts.boost": "să redistribuie",
"keyboard_shortcuts.column": "să focuzeze o postare in una dintre coloane", "keyboard_shortcuts.column": "să focuzeze o postare in una dintre coloane",
"keyboard_shortcuts.compose": "sa focuzeze zona de compunere", "keyboard_shortcuts.compose": "sa focuzeze zona de compunere",
"keyboard_shortcuts.description": "Descriere", "keyboard_shortcuts.description": "Descriere",
"keyboard_shortcuts.direct": "sa deschida coloane de mesaje directe", "keyboard_shortcuts.direct": "să deschidă coloana de mesaje directe",
"keyboard_shortcuts.down": "sa fie mutata jos in lista", "keyboard_shortcuts.down": "să fie mutată jos in lista",
"keyboard_shortcuts.enter": "sa deschisa status", "keyboard_shortcuts.enter": "să deschidă un status",
"keyboard_shortcuts.favourite": "sa adauge la favorite", "keyboard_shortcuts.favourite": "să adauge la favorite",
"keyboard_shortcuts.favourites": "sa deschida lista cu favorite", "keyboard_shortcuts.favourites": "să deschidă lista cu favorite",
"keyboard_shortcuts.federated": "sa deschida fluxul global", "keyboard_shortcuts.federated": "să deschidă fluxul global",
"keyboard_shortcuts.heading": "Comenzi din tastatură", "keyboard_shortcuts.heading": "Comenzi rapide",
"keyboard_shortcuts.home": "sa deschida fluxul principal", "keyboard_shortcuts.home": "să deschidă fluxul Acasă",
"keyboard_shortcuts.hotkey": "Prescurtări", "keyboard_shortcuts.hotkey": "Prescurtări",
"keyboard_shortcuts.legend": "sa afiseze aceasta legenda", "keyboard_shortcuts.legend": "să afișeze această legendă",
"keyboard_shortcuts.local": "sa deschida fluxul local", "keyboard_shortcuts.local": "să deschidă fluxul local",
"keyboard_shortcuts.mention": "sa mentioneze autorul", "keyboard_shortcuts.mention": "să menționeze autorul",
"keyboard_shortcuts.muted": "sa deschida lista utilizatorilor opriti", "keyboard_shortcuts.muted": "să deschidă lista utilizatorilor opriți",
"keyboard_shortcuts.my_profile": "sa deschida profilul tau", "keyboard_shortcuts.my_profile": "să deschidă profilul tău",
"keyboard_shortcuts.notifications": "sa deschida coloana cu notificari", "keyboard_shortcuts.notifications": "să deschidă coloana cu notificări",
"keyboard_shortcuts.pinned": "sa deschida lista postarilor fixate", "keyboard_shortcuts.pinned": "să deschidă lista postărilor fixate",
"keyboard_shortcuts.profile": "sa deschida porfilul autorului", "keyboard_shortcuts.profile": "să deschidă porfilul autorului",
"keyboard_shortcuts.reply": "sa raspunda", "keyboard_shortcuts.reply": "să răspundă",
"keyboard_shortcuts.requests": "sa deschida lista cu cereri de urmarire", "keyboard_shortcuts.requests": "să deschidă lista cu cereri de urmărire",
"keyboard_shortcuts.search": "sa focuseze cautarea", "keyboard_shortcuts.search": "să focuseze căutarea",
"keyboard_shortcuts.start": "sa deschida coloana \"Incepere\"", "keyboard_shortcuts.start": "să deschidă coloana \"Începere\"",
"keyboard_shortcuts.toggle_hidden": "sa arate/ascunda textul in spatele CW", "keyboard_shortcuts.toggle_hidden": "să arate/ascundă textul in spatele CW",
"keyboard_shortcuts.toot": "sa inceapa o noua postare", "keyboard_shortcuts.toot": "să înceapă o postare nouă",
"keyboard_shortcuts.unfocus": "sa dezactiveze compunerea/cautarea", "keyboard_shortcuts.unfocus": "să dezactiveze zona de compunere/căutare",
"keyboard_shortcuts.up": "sa mute mai sus in lista", "keyboard_shortcuts.up": "să mute mai sus în listă",
"lightbox.close": "Închide", "lightbox.close": "Închide",
"lightbox.next": "Următorul", "lightbox.next": "Următorul",
"lightbox.previous": "Precedentul", "lightbox.previous": "Precedentul",
"lists.account.add": "Adaugă în listă", "lists.account.add": "Adaugă în listă",
"lists.account.remove": "Elimină din listă", "lists.account.remove": "Elimină din listă",
"lists.delete": "Șterge listă", "lists.delete": "Șterge lista",
"lists.edit": "Editează lista", "lists.edit": "Editează lista",
"lists.new.create": "Adaugă listă", "lists.new.create": "Adaugă listă",
"lists.new.title_placeholder": "Titlu pentru noua listă", "lists.new.title_placeholder": "Titlu pentru noua listă",
@ -242,20 +242,20 @@
"notifications.clear_confirmation": "Ești sigur că vrei să ștergi toate notificările?", "notifications.clear_confirmation": "Ești sigur că vrei să ștergi toate notificările?",
"notifications.column_settings.alert": "Notificări pe desktop", "notifications.column_settings.alert": "Notificări pe desktop",
"notifications.column_settings.favourite": "Favorite:", "notifications.column_settings.favourite": "Favorite:",
"notifications.column_settings.filter_bar.advanced": "Display all categories", "notifications.column_settings.filter_bar.advanced": "Afișează toate categoriile",
"notifications.column_settings.filter_bar.category": "Quick filter bar", "notifications.column_settings.filter_bar.category": "Bară de filtrare rapidă",
"notifications.column_settings.filter_bar.show": "Show", "notifications.column_settings.filter_bar.show": "Arată",
"notifications.column_settings.follow": "Noi urmăritori:", "notifications.column_settings.follow": "Noi urmăritori:",
"notifications.column_settings.mention": "Mențiuni:", "notifications.column_settings.mention": "Mențiuni:",
"notifications.column_settings.push": "Notificări push", "notifications.column_settings.push": "Notificări push",
"notifications.column_settings.reblog": "Redistribuite:", "notifications.column_settings.reblog": "Redistribuite:",
"notifications.column_settings.show": "Arată în coloană", "notifications.column_settings.show": "Arată în coloană",
"notifications.column_settings.sound": "Redă sunet", "notifications.column_settings.sound": "Redă sunet",
"notifications.filter.all": "All", "notifications.filter.all": "Toate",
"notifications.filter.boosts": "Boosts", "notifications.filter.boosts": "Redistribuiri",
"notifications.filter.favourites": "Favourites", "notifications.filter.favourites": "Favorite",
"notifications.filter.follows": "Follows", "notifications.filter.follows": "Urmărește",
"notifications.filter.mentions": "Mentions", "notifications.filter.mentions": "Menționări",
"notifications.group": "{count} notificări", "notifications.group": "{count} notificări",
"privacy.change": "Cine vede asta", "privacy.change": "Cine vede asta",
"privacy.direct.long": "Postează doar pentru utilizatorii menționați", "privacy.direct.long": "Postează doar pentru utilizatorii menționați",
@ -291,7 +291,9 @@
"search_results.hashtags": "Hashtaguri", "search_results.hashtags": "Hashtaguri",
"search_results.statuses": "Postări", "search_results.statuses": "Postări",
"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": "Se întâmplă acum", "standalone.public_title": "Se întâmplă acum...",
"status.admin_account": "Open moderation interface for @{name}",
"status.admin_status": "Open this status in the moderation interface",
"status.block": "Blochează @{name}", "status.block": "Blochează @{name}",
"status.cancel_reblog_private": "Nedistribuit", "status.cancel_reblog_private": "Nedistribuit",
"status.cannot_reblog": "Această postare nu poate fi redistribuită", "status.cannot_reblog": "Această postare nu poate fi redistribuită",
@ -310,10 +312,10 @@
"status.open": "Extinde acest status", "status.open": "Extinde acest status",
"status.pin": "Fixează pe profil", "status.pin": "Fixează pe profil",
"status.pinned": "Postare fixată", "status.pinned": "Postare fixată",
"status.read_more": "Read more", "status.read_more": "Citește mai mult",
"status.reblog": "Redistribuie", "status.reblog": "Redistribuie",
"status.reblog_private": "Redistribuie către audiența originală", "status.reblog_private": "Redistribuie către audiența originală",
"status.reblogged_by": "{name} redistribuit", "status.reblogged_by": "{name} a redistribuit",
"status.reblogs.empty": "Nimeni nu a redistribuit această postare până acum. Când cineva o va face, va apărea aici.", "status.reblogs.empty": "Nimeni nu a redistribuit această postare până acum. Când cineva o va face, va apărea aici.",
"status.redraft": "Șterge și adaugă la ciorne", "status.redraft": "Șterge și adaugă la ciorne",
"status.reply": "Răspunde", "status.reply": "Răspunde",
@ -326,11 +328,11 @@
"status.show_less_all": "Arată mai puțin pentru toți", "status.show_less_all": "Arată mai puțin pentru toți",
"status.show_more": "Arată mai mult", "status.show_more": "Arată mai mult",
"status.show_more_all": "Arată mai mult pentru toți", "status.show_more_all": "Arată mai mult pentru toți",
"status.show_thread": "Show thread", "status.show_thread": "Arată topicul",
"status.unmute_conversation": "Repornește conversația", "status.unmute_conversation": "Repornește conversația",
"status.unpin": "Eliberează din profil", "status.unpin": "Eliberează din profil",
"suggestions.dismiss": "Dismiss suggestion", "suggestions.dismiss": "Omite sugestia",
"suggestions.header": "You might be interested in…", "suggestions.header": "Ai putea fi interesat de…",
"tabs_bar.federated_timeline": "Global", "tabs_bar.federated_timeline": "Global",
"tabs_bar.home": "Acasă", "tabs_bar.home": "Acasă",
"tabs_bar.local_timeline": "Local", "tabs_bar.local_timeline": "Local",
@ -341,7 +343,7 @@
"upload_area.title": "Trage și eliberează pentru a încărca", "upload_area.title": "Trage și eliberează pentru a încărca",
"upload_button.label": "Adaugă media (JPEG, PNG, GIF, WebM, MP4, MOV)", "upload_button.label": "Adaugă media (JPEG, PNG, GIF, WebM, MP4, MOV)",
"upload_form.description": "Adaugă o descriere pentru persoanele cu deficiențe de vedere", "upload_form.description": "Adaugă o descriere pentru persoanele cu deficiențe de vedere",
"upload_form.focus": "Taie", "upload_form.focus": "Schimbă previzualizarea",
"upload_form.undo": "Șterge", "upload_form.undo": "Șterge",
"upload_progress.label": "Se Încarcă...", "upload_progress.label": "Se Încarcă...",
"video.close": "Închide video", "video.close": "Închide video",

@ -292,6 +292,8 @@
"search_results.statuses": "Посты", "search_results.statuses": "Посты",
"search_results.total": "{count, number} {count, plural, one {результат} few {результата} many {результатов} other {результатов}}", "search_results.total": "{count, number} {count, plural, one {результат} few {результата} many {результатов} other {результатов}}",
"standalone.public_title": "Прямо сейчас", "standalone.public_title": "Прямо сейчас",
"status.admin_account": "Open moderation interface for @{name}",
"status.admin_status": "Open this status in the moderation interface",
"status.block": "Заблокировать @{name}", "status.block": "Заблокировать @{name}",
"status.cancel_reblog_private": "Не продвигать", "status.cancel_reblog_private": "Не продвигать",
"status.cannot_reblog": "Этот статус не может быть продвинут", "status.cannot_reblog": "Этот статус не может быть продвинут",

@ -33,11 +33,11 @@
"account.unblock": "Odblokuj @{name}", "account.unblock": "Odblokuj @{name}",
"account.unblock_domain": "Prestaň skrývať {domain}", "account.unblock_domain": "Prestaň skrývať {domain}",
"account.unendorse": "Nezobrazuj na profile", "account.unendorse": "Nezobrazuj na profile",
"account.unfollow": "Prestať nasledovať", "account.unfollow": "Prestaň následovať",
"account.unmute": "Prestať ignorovať @{name}", "account.unmute": "Prestaň ignorovať @{name}",
"account.unmute_notifications": "Odtĺmiť notifikácie od @{name}", "account.unmute_notifications": "Odtĺm oboznámenia od @{name}",
"account.view_full_profile": "Pozri celý profil", "account.view_full_profile": "Pozri celý profil",
"alert.unexpected.message": "Vyskytla sa neočakávaná chyba.", "alert.unexpected.message": "Vyskytla sa nečakaná chyba.",
"alert.unexpected.title": "Oops!", "alert.unexpected.title": "Oops!",
"boost_modal.combo": "Nabudúce môžeš kliknúť {combo} pre preskočenie", "boost_modal.combo": "Nabudúce môžeš kliknúť {combo} pre preskočenie",
"bundle_column_error.body": "Pri načítaní tohto prvku nastala nejaká chyba.", "bundle_column_error.body": "Pri načítaní tohto prvku nastala nejaká chyba.",
@ -127,12 +127,12 @@
"empty_column.list": "Tento zoznam je ešte prázdny. Keď ale členovia tohoto zoznamu napíšu nové správy, tak tie sa objavia priamo tu.", "empty_column.list": "Tento zoznam je ešte prázdny. Keď ale členovia tohoto zoznamu napíšu nové správy, tak tie sa objavia priamo tu.",
"empty_column.lists": "Nemáš ešte žiadne zoznamy. Keď nejaký vytvoríš, bude zobrazený práve tu.", "empty_column.lists": "Nemáš ešte žiadne zoznamy. Keď nejaký vytvoríš, bude zobrazený práve tu.",
"empty_column.mutes": "Ešte si nestĺmil žiadných užívateľov.", "empty_column.mutes": "Ešte si nestĺmil žiadných užívateľov.",
"empty_column.notifications": "Nemáš ešte žiadne oznámenia. Zapoj sa s niekym do debaty a komunikuj s ostatnými aby diskusia mohla začať.", "empty_column.notifications": "Ešte nemáš žiadne oznámenia. Začni komunikovať s ostatnými, aby diskusia mohla začať.",
"empty_column.public": "Ešte tu nič nie je. Napíš niečo verejne alebo začnite sledovať užívateľov z iných Mastodon serverov, aby tu tak niečo pribudlo", "empty_column.public": "Ešte tu nič nie je. Napíš niečo verejne, alebo začni sledovať užívateľov z iných Mastodon serverov, aby tu niečo pribudlo",
"follow_request.authorize": "Povoľ prístup", "follow_request.authorize": "Povoľ prístup",
"follow_request.reject": "Odmietni", "follow_request.reject": "Odmietni",
"getting_started.developers": "Vývojári", "getting_started.developers": "Vývojári",
"getting_started.directory": "Profile directory", "getting_started.directory": "Databáza profilov",
"getting_started.documentation": "Dokumentácia", "getting_started.documentation": "Dokumentácia",
"getting_started.heading": "Začni tu", "getting_started.heading": "Začni tu",
"getting_started.invite": "Pozvať ľudí", "getting_started.invite": "Pozvať ľudí",
@ -292,6 +292,8 @@
"search_results.statuses": "Hlášky", "search_results.statuses": "Hlášky",
"search_results.total": "{count, number} {count, plural, one {výsledok} many {výsledkov} other {výsledky}}", "search_results.total": "{count, number} {count, plural, one {výsledok} many {výsledkov} other {výsledky}}",
"standalone.public_title": "Náhľad dovnútra...", "standalone.public_title": "Náhľad dovnútra...",
"status.admin_account": "Open moderation interface for @{name}",
"status.admin_status": "Open this status in the moderation interface",
"status.block": "Blokovať @{name}", "status.block": "Blokovať @{name}",
"status.cancel_reblog_private": "Nezdieľaj", "status.cancel_reblog_private": "Nezdieľaj",
"status.cannot_reblog": "Tento príspevok nemôže byť re-tootnutý", "status.cannot_reblog": "Tento príspevok nemôže byť re-tootnutý",
@ -341,7 +343,7 @@
"upload_area.title": "Pretiahni a pusť pre nahratie", "upload_area.title": "Pretiahni a pusť pre nahratie",
"upload_button.label": "Pridať médiálny súbor (JPEG, PNG, GIF, WebM, MP4, MOV)", "upload_button.label": "Pridať médiálny súbor (JPEG, PNG, GIF, WebM, MP4, MOV)",
"upload_form.description": "Opis pre slabo vidiacich", "upload_form.description": "Opis pre slabo vidiacich",
"upload_form.focus": "Vystrihni", "upload_form.focus": "Pozmeň náhľad",
"upload_form.undo": "Vymaž", "upload_form.undo": "Vymaž",
"upload_progress.label": "Nahráva sa...", "upload_progress.label": "Nahráva sa...",
"video.close": "Zavrieť video", "video.close": "Zavrieť video",

@ -292,6 +292,8 @@
"search_results.statuses": "Tuti", "search_results.statuses": "Tuti",
"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.admin_account": "Open moderation interface for @{name}",
"status.admin_status": "Open this status in the moderation interface",
"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",

@ -292,6 +292,8 @@
"search_results.statuses": "Toots", "search_results.statuses": "Toots",
"search_results.total": "{count, number} {count, plural, one {rezultat} few {rezultata} other {rezultata}}", "search_results.total": "{count, number} {count, plural, one {rezultat} few {rezultata} other {rezultata}}",
"standalone.public_title": "Pogled iznutra...", "standalone.public_title": "Pogled iznutra...",
"status.admin_account": "Open moderation interface for @{name}",
"status.admin_status": "Open this status in the moderation interface",
"status.block": "Block @{name}", "status.block": "Block @{name}",
"status.cancel_reblog_private": "Unboost", "status.cancel_reblog_private": "Unboost",
"status.cannot_reblog": "Ovaj status ne može da se podrži", "status.cannot_reblog": "Ovaj status ne može da se podrži",

@ -292,6 +292,8 @@
"search_results.statuses": "Трубе", "search_results.statuses": "Трубе",
"search_results.total": "{count, number} {count, plural, one {резултат} few {резултата} other {резултата}}", "search_results.total": "{count, number} {count, plural, one {резултат} few {резултата} other {резултата}}",
"standalone.public_title": "Поглед изнутра...", "standalone.public_title": "Поглед изнутра...",
"status.admin_account": "Open moderation interface for @{name}",
"status.admin_status": "Open this status in the moderation interface",
"status.block": "Блокирај @{name}", "status.block": "Блокирај @{name}",
"status.cancel_reblog_private": "Уклони подршку", "status.cancel_reblog_private": "Уклони подршку",
"status.cannot_reblog": "Овај статус не може да се подржи", "status.cannot_reblog": "Овај статус не може да се подржи",

@ -292,6 +292,8 @@
"search_results.statuses": "Toots", "search_results.statuses": "Toots",
"search_results.total": "{count, number} {count, plural, ett {result} andra {results}}", "search_results.total": "{count, number} {count, plural, ett {result} andra {results}}",
"standalone.public_title": "En titt inuti...", "standalone.public_title": "En titt inuti...",
"status.admin_account": "Open moderation interface for @{name}",
"status.admin_status": "Open this status in the moderation interface",
"status.block": "Block @{name}", "status.block": "Block @{name}",
"status.cancel_reblog_private": "Ta bort knuff", "status.cancel_reblog_private": "Ta bort knuff",
"status.cannot_reblog": "Detta inlägg kan inte knuffas", "status.cannot_reblog": "Detta inlägg kan inte knuffas",

@ -292,6 +292,8 @@
"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.admin_account": "Open moderation interface for @{name}",
"status.admin_status": "Open this status in the moderation interface",
"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",

@ -1,5 +1,5 @@
{ {
"account.add_or_remove_from_list": "Add or Remove from lists", "account.add_or_remove_from_list": "జాబితాల నుండి చేర్చు లేదా తీసివేయి",
"account.badges.bot": "బాట్", "account.badges.bot": "బాట్",
"account.block": "@{name} ను బ్లాక్ చేయి", "account.block": "@{name} ను బ్లాక్ చేయి",
"account.block_domain": "{domain} నుంచి అన్నీ దాచిపెట్టు", "account.block_domain": "{domain} నుంచి అన్నీ దాచిపెట్టు",
@ -17,7 +17,7 @@
"account.follows_you": "మిమ్మల్ని అనుసరిస్తున్నారు", "account.follows_you": "మిమ్మల్ని అనుసరిస్తున్నారు",
"account.hide_reblogs": "@{name} నుంచి బూస్ట్ లను దాచిపెట్టు", "account.hide_reblogs": "@{name} నుంచి బూస్ట్ లను దాచిపెట్టు",
"account.link_verified_on": "ఈ లంకె యొక్క యాజమాన్యం {date}న పరీక్షించబడింది", "account.link_verified_on": "ఈ లంకె యొక్క యాజమాన్యం {date}న పరీక్షించబడింది",
"account.locked_info": "This account privacy status is set to locked. The owner manually reviews who can follow them.", "account.locked_info": "ఈ ఖాతా యొక్క గోప్యత స్థితి లాక్ చేయబడి వుంది. ఈ ఖాతాను ఎవరు అనుసరించవచ్చో యజమానే నిర్ణయం తీసుకుంటారు.",
"account.media": "మీడియా", "account.media": "మీడియా",
"account.mention": "@{name}ను ప్రస్తావించు", "account.mention": "@{name}ను ప్రస్తావించు",
"account.moved_to": "{name} ఇక్కడికి మారారు:", "account.moved_to": "{name} ఇక్కడికి మారారు:",
@ -113,7 +113,7 @@
"emoji_button.search_results": "శోధన ఫలితాలు", "emoji_button.search_results": "శోధన ఫలితాలు",
"emoji_button.symbols": "చిహ్నాలు", "emoji_button.symbols": "చిహ్నాలు",
"emoji_button.travel": "ప్రయాణం & ప్రదేశాలు", "emoji_button.travel": "ప్రయాణం & ప్రదేశాలు",
"empty_column.account_timeline": "No toots here!", "empty_column.account_timeline": "ఇక్కడ ఏ టూట్లూ లేవు!No toots here!",
"empty_column.blocks": "మీరు ఇంకా ఏ వినియోగదారులనూ బ్లాక్ చేయలేదు.", "empty_column.blocks": "మీరు ఇంకా ఏ వినియోగదారులనూ బ్లాక్ చేయలేదు.",
"empty_column.community": "స్థానిక కాలక్రమం ఖాళీగా ఉంది. మొదలుపెట్టడానికి బహిరంగంగా ఏదో ఒకటి వ్రాయండి!", "empty_column.community": "స్థానిక కాలక్రమం ఖాళీగా ఉంది. మొదలుపెట్టడానికి బహిరంగంగా ఏదో ఒకటి వ్రాయండి!",
"empty_column.direct": "మీకు ఇంకా ఏ ప్రత్యక్ష సందేశాలు లేవు. మీరు ఒకదాన్ని పంపినప్పుడు లేదా స్వీకరించినప్పుడు, అది ఇక్కడ చూపబడుతుంది.", "empty_column.direct": "మీకు ఇంకా ఏ ప్రత్యక్ష సందేశాలు లేవు. మీరు ఒకదాన్ని పంపినప్పుడు లేదా స్వీకరించినప్పుడు, అది ఇక్కడ చూపబడుతుంది.",
@ -132,40 +132,40 @@
"follow_request.authorize": "అనుమతించు", "follow_request.authorize": "అనుమతించు",
"follow_request.reject": "తిరస్కరించు", "follow_request.reject": "తిరస్కరించు",
"getting_started.developers": "డెవలపర్లు", "getting_started.developers": "డెవలపర్లు",
"getting_started.directory": "Profile directory", "getting_started.directory": "ప్రొఫైల్ డైరెక్టరీProfile directory",
"getting_started.documentation": "డాక్యుమెంటేషన్", "getting_started.documentation": "డాక్యుమెంటేషన్",
"getting_started.heading": "మొదలుపెడదాం", "getting_started.heading": "మొదలుపెడదాం",
"getting_started.invite": "వ్యక్తులను ఆహ్వానించండి", "getting_started.invite": "వ్యక్తులను ఆహ్వానించండి",
"getting_started.open_source_notice": "మాస్టొడొన్ ఓపెన్ సోర్స్ సాఫ్ట్వేర్. మీరు {github} వద్ద GitHub పై సమస్యలను నివేదించవచ్చు లేదా తోడ్పడచ్చు.", "getting_started.open_source_notice": "మాస్టొడొన్ ఓపెన్ సోర్స్ సాఫ్ట్వేర్. మీరు {github} వద్ద GitHub పై సమస్యలను నివేదించవచ్చు లేదా తోడ్పడచ్చు.",
"getting_started.security": "భద్రత", "getting_started.security": "భద్రత",
"getting_started.terms": "సేవా నిబంధనలు", "getting_started.terms": "సేవా నిబంధనలు",
"hashtag.column_header.tag_mode.all": "and {additional}", "hashtag.column_header.tag_mode.all": "మరియు {additional}",
"hashtag.column_header.tag_mode.any": "or {additional}", "hashtag.column_header.tag_mode.any": "లేదా {additional}",
"hashtag.column_header.tag_mode.none": "without {additional}", "hashtag.column_header.tag_mode.none": "{additional} లేకుండా",
"hashtag.column_settings.tag_mode.all": "All of these", "hashtag.column_settings.tag_mode.all": "ఇవన్నీAll of these",
"hashtag.column_settings.tag_mode.any": "Any of these", "hashtag.column_settings.tag_mode.any": "వీటిలో ఏవైనా",
"hashtag.column_settings.tag_mode.none": "None of these", "hashtag.column_settings.tag_mode.none": "ఇవేవీ కావు",
"hashtag.column_settings.tag_toggle": "Include additional tags in this column", "hashtag.column_settings.tag_toggle": "Include additional tags in this column",
"home.column_settings.basic": "ప్రాథమిక", "home.column_settings.basic": "ప్రాథమిక",
"home.column_settings.show_reblogs": "బూస్ట్ లను చూపించు", "home.column_settings.show_reblogs": "బూస్ట్ లను చూపించు",
"home.column_settings.show_replies": "ప్రత్యుత్తరాలను చూపించు", "home.column_settings.show_replies": "ప్రత్యుత్తరాలను చూపించు",
"introduction.federation.action": "Next", "introduction.federation.action": "తరువాత",
"introduction.federation.federated.headline": "Federated", "introduction.federation.federated.headline": "Federated",
"introduction.federation.federated.text": "Public posts from other servers of the fediverse will appear in the federated timeline.", "introduction.federation.federated.text": "ఫెడివర్స్ లోని ఇతర సర్వర్లకు చెందిన పబ్లిక్ టూట్లు ఫెడరేటెడ్ టైంలైన్ లో కనిపిస్తాయి.",
"introduction.federation.home.headline": "Home", "introduction.federation.home.headline": "Home",
"introduction.federation.home.text": "Posts from people you follow will appear in your home feed. You can follow anyone on any server!", "introduction.federation.home.text": "మీరు అనుసరిస్తున్న ఖాతాల టూట్లు హోం ఫీడ్ లో కనిపిస్తాయి. ఏ సర్వర్లో ఎవరినైనా మీరు అనుసరించవచ్చు!",
"introduction.federation.local.headline": "Local", "introduction.federation.local.headline": "Local",
"introduction.federation.local.text": "Public posts from people on the same server as you will appear in the local timeline.", "introduction.federation.local.text": "ఈ సర్వరుకు చెందిన ఖాతాల పబ్లిక్ టూట్లు లోకల్ టైంలైన్ లో కనిపిస్తాయి.",
"introduction.interactions.action": "Finish tutorial!", "introduction.interactions.action": "బోధనను ముగించు!",
"introduction.interactions.favourite.headline": "Favourite", "introduction.interactions.favourite.headline": "ఇష్టం",
"introduction.interactions.favourite.text": "You can save a toot for later, and let the author know that you liked it, by favouriting it.", "introduction.interactions.favourite.text": "మీరు ఏదైనా టూట్‌ను భవిష్యత్తు కోసం దాచుకోవచ్చు మరియు మీకు ఆ టూట్ నచ్చినందని తెలియజేయడం కోసం \"ఇష్టం\" ను నొక్కి రచయితకు తెలియజేయవచ్చు.",
"introduction.interactions.reblog.headline": "Boost", "introduction.interactions.reblog.headline": "బూస్ట్",
"introduction.interactions.reblog.text": "You can share other people's toots with your followers by boosting them.", "introduction.interactions.reblog.text": "వేరే వ్యక్తుల టూట్లను బూస్ట్ చేయడం ద్వారా ఆ టూట్‌ను మీ అనుచరులతో పంచుకోవచ్చు.",
"introduction.interactions.reply.headline": "Reply", "introduction.interactions.reply.headline": "ప్రత్యుత్తరం",
"introduction.interactions.reply.text": "You can reply to other people's and your own toots, which will chain them together in a conversation.", "introduction.interactions.reply.text": "మీరు ఇతర వ్యక్తుల టూట్లకు, మీ స్వంత టూత్లకు ప్రత్యుత్తరం ఇవ్వడం వల్ల గొలుసు చర్చ ప్రారంభమవుతుంది.",
"introduction.welcome.action": "Let's go!", "introduction.welcome.action": "ఇక ప్రారంభించు!",
"introduction.welcome.headline": "First steps", "introduction.welcome.headline": "మొదటి మెట్లు",
"introduction.welcome.text": "Welcome to the fediverse! In a few moments, you'll be able to broadcast messages and talk to your friends across a wide variety of servers. But this server, {domain}, is special—it hosts your profile, so remember its name.", "introduction.welcome.text": "ఫెడివర్స్ కు స్వాగతం! మరి కొంతసేపట్లో మీరు సందేశాలను ప్రసారం చేయవచ్చు మరియు వేర్వేరు సర్వర్లలో వున్న మీ స్నేహితులతో మాట్లాడవచ్చు. కానీ ఈ సర్వరు, {domain}, ప్రత్యేకమైనది - ఇది మీ ప్రొఫైలును హోస్టు చేస్తుంది, కాబట్టి ఈ సర్వరు పేరును గుర్తుంచుకోండి.",
"keyboard_shortcuts.back": "వెనక్కి తిరిగి వెళ్ళడానికి", "keyboard_shortcuts.back": "వెనక్కి తిరిగి వెళ్ళడానికి",
"keyboard_shortcuts.blocked": "బ్లాక్ చేయబడిన వినియోగదారుల జాబితాను తెరవడానికి", "keyboard_shortcuts.blocked": "బ్లాక్ చేయబడిన వినియోగదారుల జాబితాను తెరవడానికి",
"keyboard_shortcuts.boost": "బూస్ట్ చేయడానికి", "keyboard_shortcuts.boost": "బూస్ట్ చేయడానికి",
@ -242,20 +242,20 @@
"notifications.clear_confirmation": "మీరు మీ అన్ని నోటిఫికేషన్లను శాశ్వతంగా తొలగించాలనుకుంటున్నారా?", "notifications.clear_confirmation": "మీరు మీ అన్ని నోటిఫికేషన్లను శాశ్వతంగా తొలగించాలనుకుంటున్నారా?",
"notifications.column_settings.alert": "డెస్క్టాప్ నోటిఫికేషన్లు", "notifications.column_settings.alert": "డెస్క్టాప్ నోటిఫికేషన్లు",
"notifications.column_settings.favourite": "ఇష్టపడినవి:", "notifications.column_settings.favourite": "ఇష్టపడినవి:",
"notifications.column_settings.filter_bar.advanced": "Display all categories", "notifications.column_settings.filter_bar.advanced": "అన్ని విభాగాలను చూపించు",
"notifications.column_settings.filter_bar.category": "Quick filter bar", "notifications.column_settings.filter_bar.category": "క్విక్ ఫిల్టర్ బార్",
"notifications.column_settings.filter_bar.show": "Show", "notifications.column_settings.filter_bar.show": "చూపించు",
"notifications.column_settings.follow": "క్రొత్త అనుచరులు:", "notifications.column_settings.follow": "క్రొత్త అనుచరులు:",
"notifications.column_settings.mention": "ప్రస్తావనలు:", "notifications.column_settings.mention": "ప్రస్తావనలు:",
"notifications.column_settings.push": "పుష్ ప్రకటనలు", "notifications.column_settings.push": "పుష్ ప్రకటనలు",
"notifications.column_settings.reblog": "బూస్ట్ లు:", "notifications.column_settings.reblog": "బూస్ట్ లు:",
"notifications.column_settings.show": "నిలువు వరుసలో చూపు", "notifications.column_settings.show": "నిలువు వరుసలో చూపు",
"notifications.column_settings.sound": "ధ్వనిని ప్లే చేయి", "notifications.column_settings.sound": "ధ్వనిని ప్లే చేయి",
"notifications.filter.all": "All", "notifications.filter.all": "అన్నీ",
"notifications.filter.boosts": "Boosts", "notifications.filter.boosts": "బూస్ట్లు",
"notifications.filter.favourites": "Favourites", "notifications.filter.favourites": "ఇష్టాలు",
"notifications.filter.follows": "Follows", "notifications.filter.follows": "అనుసరిస్తున్నవి",
"notifications.filter.mentions": "Mentions", "notifications.filter.mentions": "పేర్కొన్నవి",
"notifications.group": "{count} ప్రకటనలు", "notifications.group": "{count} ప్రకటనలు",
"privacy.change": "స్టేటస్ గోప్యతను సర్దుబాటు చేయండి", "privacy.change": "స్టేటస్ గోప్యతను సర్దుబాటు చేయండి",
"privacy.direct.long": "పేర్కొన్న వినియోగదారులకు మాత్రమే పోస్ట్ చేయి", "privacy.direct.long": "పేర్కొన్న వినియోగదారులకు మాత్రమే పోస్ట్ చేయి",
@ -292,6 +292,8 @@
"search_results.statuses": "టూట్లు", "search_results.statuses": "టూట్లు",
"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": "లోపలికి ఒక చూపు...", "standalone.public_title": "లోపలికి ఒక చూపు...",
"status.admin_account": "Open moderation interface for @{name}",
"status.admin_status": "Open this status in the moderation interface",
"status.block": "@{name} ను బ్లాక్ చేయి", "status.block": "@{name} ను బ్లాక్ చేయి",
"status.cancel_reblog_private": "బూస్ట్ను తొలగించు", "status.cancel_reblog_private": "బూస్ట్ను తొలగించు",
"status.cannot_reblog": "ఈ పోస్ట్ను బూస్ట్ చేయడం సాధ్యం కాదు", "status.cannot_reblog": "ఈ పోస్ట్ను బూస్ట్ చేయడం సాధ్యం కాదు",
@ -326,7 +328,7 @@
"status.show_less_all": "అన్నిటికీ తక్కువ చూపించు", "status.show_less_all": "అన్నిటికీ తక్కువ చూపించు",
"status.show_more": "ఇంకా చూపించు", "status.show_more": "ఇంకా చూపించు",
"status.show_more_all": "అన్నిటికీ ఇంకా చూపించు", "status.show_more_all": "అన్నిటికీ ఇంకా చూపించు",
"status.show_thread": "Show thread", "status.show_thread": "గొలుసును చూపించు",
"status.unmute_conversation": "సంభాషణను అన్మ్యూట్ చేయి", "status.unmute_conversation": "సంభాషణను అన్మ్యూట్ చేయి",
"status.unpin": "ప్రొఫైల్ నుండి పీకివేయు", "status.unpin": "ప్రొఫైల్ నుండి పీకివేయు",
"suggestions.dismiss": "సూచనను రద్దు చేయి", "suggestions.dismiss": "సూచనను రద్దు చేయి",
@ -341,7 +343,7 @@
"upload_area.title": "అప్లోడ్ చేయడానికి డ్రాగ్ & డ్రాప్ చేయండి", "upload_area.title": "అప్లోడ్ చేయడానికి డ్రాగ్ & డ్రాప్ చేయండి",
"upload_button.label": "మీడియాను జోడించండి (JPEG, PNG, GIF, WebM, MP4, MOV)", "upload_button.label": "మీడియాను జోడించండి (JPEG, PNG, GIF, WebM, MP4, MOV)",
"upload_form.description": "దృష్టి లోపమున్న వారి కోసం వివరించండి", "upload_form.description": "దృష్టి లోపమున్న వారి కోసం వివరించండి",
"upload_form.focus": "కత్తిరించు", "upload_form.focus": "ప్రివ్యూను మార్చు",
"upload_form.undo": "తొలగించు", "upload_form.undo": "తొలగించు",
"upload_progress.label": "అప్లోడ్ అవుతోంది...", "upload_progress.label": "అప్లోడ్ అవుతోంది...",
"video.close": "వీడియోని మూసివేయి", "video.close": "వీడియోని మూసివేయి",

@ -292,6 +292,8 @@
"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.admin_account": "Open moderation interface for @{name}",
"status.admin_status": "Open this status in the moderation interface",
"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",

@ -292,6 +292,8 @@
"search_results.statuses": "Toots", "search_results.statuses": "Toots",
"search_results.total": "{count, number} {count, plural, one {sonuç} other {sonuçlar}}", "search_results.total": "{count, number} {count, plural, one {sonuç} other {sonuçlar}}",
"standalone.public_title": "A look inside...", "standalone.public_title": "A look inside...",
"status.admin_account": "Open moderation interface for @{name}",
"status.admin_status": "Open this status in the moderation interface",
"status.block": "Block @{name}", "status.block": "Block @{name}",
"status.cancel_reblog_private": "Unboost", "status.cancel_reblog_private": "Unboost",
"status.cannot_reblog": "Bu gönderi boost edilemez", "status.cannot_reblog": "Bu gönderi boost edilemez",

@ -292,6 +292,8 @@
"search_results.statuses": "Toots", "search_results.statuses": "Toots",
"search_results.total": "{count, number} {count, plural, one {результат} few {результати} many {результатів} other {результатів}}", "search_results.total": "{count, number} {count, plural, one {результат} few {результати} many {результатів} other {результатів}}",
"standalone.public_title": "A look inside...", "standalone.public_title": "A look inside...",
"status.admin_account": "Open moderation interface for @{name}",
"status.admin_status": "Open this status in the moderation interface",
"status.block": "Block @{name}", "status.block": "Block @{name}",
"status.cancel_reblog_private": "Unboost", "status.cancel_reblog_private": "Unboost",
"status.cannot_reblog": "Цей допис не може бути передмухнутий", "status.cannot_reblog": "Цей допис не може бути передмухнутий",

@ -292,6 +292,8 @@
"search_results.statuses": "嘟文", "search_results.statuses": "嘟文",
"search_results.total": "共 {count, number} 个结果", "search_results.total": "共 {count, number} 个结果",
"standalone.public_title": "大家都在干啥?", "standalone.public_title": "大家都在干啥?",
"status.admin_account": "Open moderation interface for @{name}",
"status.admin_status": "Open this status in the moderation interface",
"status.block": "屏蔽 @{name}", "status.block": "屏蔽 @{name}",
"status.cancel_reblog_private": "取消转嘟", "status.cancel_reblog_private": "取消转嘟",
"status.cannot_reblog": "无法转嘟这条嘟文", "status.cannot_reblog": "无法转嘟这条嘟文",

@ -292,6 +292,8 @@
"search_results.statuses": "文章", "search_results.statuses": "文章",
"search_results.total": "{count, number} 項結果", "search_results.total": "{count, number} 項結果",
"standalone.public_title": "站點一瞥…", "standalone.public_title": "站點一瞥…",
"status.admin_account": "Open moderation interface for @{name}",
"status.admin_status": "Open this status in the moderation interface",
"status.block": "封鎖 @{name}", "status.block": "封鎖 @{name}",
"status.cancel_reblog_private": "取消轉推", "status.cancel_reblog_private": "取消轉推",
"status.cannot_reblog": "這篇文章無法被轉推", "status.cannot_reblog": "這篇文章無法被轉推",

@ -292,6 +292,8 @@
"search_results.statuses": "嘟文", "search_results.statuses": "嘟文",
"search_results.total": "{count, number} 項結果", "search_results.total": "{count, number} 項結果",
"standalone.public_title": "站點一瞥…", "standalone.public_title": "站點一瞥…",
"status.admin_account": "Open moderation interface for @{name}",
"status.admin_status": "Open this status in the moderation interface",
"status.block": "封鎖 @{name}", "status.block": "封鎖 @{name}",
"status.cancel_reblog_private": "取消轉嘟", "status.cancel_reblog_private": "取消轉嘟",
"status.cannot_reblog": "這篇嘟文無法被轉嘟", "status.cannot_reblog": "這篇嘟文無法被轉嘟",

@ -16,6 +16,17 @@ function main() {
const Rellax = require('rellax'); const Rellax = require('rellax');
const createHistory = require('history').createBrowserHistory; const createHistory = require('history').createBrowserHistory;
const scrollToDetailedStatus = () => {
const history = createHistory();
const detailedStatuses = document.querySelectorAll('.public-layout .detailed-status');
const location = history.location;
if (detailedStatuses.length === 1 && (!location.state || !location.state.scrolledToDetailedStatus)) {
detailedStatuses[0].scrollIntoView();
history.replace(location.pathname, { ...location.state, scrolledToDetailedStatus: true });
}
};
ready(() => { ready(() => {
const locale = document.documentElement.lang; const locale = document.documentElement.lang;
@ -59,8 +70,14 @@ function main() {
ReactDOM.render(<MediaContainer locale={locale} components={reactComponents} />, content); ReactDOM.render(<MediaContainer locale={locale} components={reactComponents} />, content);
document.body.appendChild(content); document.body.appendChild(content);
scrollToDetailedStatus();
}) })
.catch(error => console.error(error)); .catch(error => {
console.error(error);
scrollToDetailedStatus();
});
} else {
scrollToDetailedStatus();
} }
const parallaxComponents = document.querySelectorAll('.parallax'); const parallaxComponents = document.querySelectorAll('.parallax');
@ -68,15 +85,6 @@ function main() {
if (parallaxComponents.length > 0 ) { if (parallaxComponents.length > 0 ) {
new Rellax('.parallax', { speed: -1 }); new Rellax('.parallax', { speed: -1 });
} }
const history = createHistory();
const detailedStatuses = document.querySelectorAll('.public-layout .detailed-status');
const location = history.location;
if (detailedStatuses.length === 1 && (!location.state || !location.state.scrolledToDetailedStatus)) {
detailedStatuses[0].scrollIntoView();
history.replace(location.pathname, { ...location.state, scrolledToDetailedStatus: true });
}
}); });
} }

@ -151,6 +151,20 @@ $no-columns-breakpoint: 600px;
font-weight: 500; font-weight: 500;
} }
.directory__tag a {
box-shadow: none;
}
.directory__tag h4 {
font-size: 18px;
font-weight: 700;
color: $primary-text-color;
text-transform: none;
padding-bottom: 0;
margin-bottom: 0;
border-bottom: none;
}
& > p { & > p {
font-size: 14px; font-size: 14px;
line-height: 18px; line-height: 18px;

@ -2587,6 +2587,15 @@ a.status-card {
flex: 0 0 100px; flex: 0 0 100px;
background: lighten($ui-base-color, 8%); background: lighten($ui-base-color, 8%);
position: relative; position: relative;
& > .fa {
font-size: 21px;
position: absolute;
transform-origin: 50% 50%;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
}
} }
.status-card.horizontal { .status-card.horizontal {
@ -4046,6 +4055,7 @@ a.status-card.compact:hover {
color: $highlight-text-color; color: $highlight-text-color;
} }
.status__content,
.status__content p { .status__content p {
color: $inverted-text-color; color: $inverted-text-color;
} }

@ -39,6 +39,7 @@
color: $primary-text-color; color: $primary-text-color;
font-family: $font-display, sans-serif; font-family: $font-display, sans-serif;
margin-bottom: 20px; margin-bottom: 20px;
line-height: 30px;
} }
&__text { &__text {

@ -79,7 +79,7 @@ class Account < ApplicationRecord
validates_with UniqueUsernameValidator, if: -> { local? && will_save_change_to_username? } validates_with UniqueUsernameValidator, if: -> { local? && will_save_change_to_username? }
validates_with UnreservedUsernameValidator, if: -> { local? && will_save_change_to_username? } validates_with UnreservedUsernameValidator, if: -> { local? && will_save_change_to_username? }
validates :display_name, length: { maximum: MAX_DISPLAY_NAME_LENGTH }, if: -> { local? && will_save_change_to_display_name? } validates :display_name, length: { maximum: MAX_DISPLAY_NAME_LENGTH }, if: -> { local? && will_save_change_to_display_name? }
validate :note_length_does_not_exceed_length_limit, if: -> { local? && will_save_change_to_note? } validates :note, note_length: { maximum: MAX_NOTE_LENGTH }, if: -> { local? && will_save_change_to_note? }
validates :fields, length: { maximum: MAX_FIELDS }, if: -> { local? && will_save_change_to_fields? } validates :fields, length: { maximum: MAX_FIELDS }, if: -> { local? && will_save_change_to_fields? }
scope :remote, -> { where.not(domain: nil) } scope :remote, -> { where.not(domain: nil) }
@ -488,22 +488,6 @@ class Account < ApplicationRecord
self.public_key = keypair.public_key.to_pem self.public_key = keypair.public_key.to_pem
end end
YAML_START = "---\r\n"
YAML_END = "\r\n...\r\n"
def note_length_does_not_exceed_length_limit
note_without_metadata = note
if note.start_with? YAML_START
idx = note.index YAML_END
unless idx.nil?
note_without_metadata = note[(idx + YAML_END.length) .. -1]
end
end
if note_without_metadata.mb_chars.grapheme_length > MAX_NOTE_LENGTH
errors.add(:note, "can't be longer than 500 graphemes")
end
end
def normalize_domain def normalize_domain
return if local? return if local?

@ -15,6 +15,7 @@ module AccountAssociations
has_many :mentions, inverse_of: :account, dependent: :destroy has_many :mentions, inverse_of: :account, dependent: :destroy
has_many :notifications, inverse_of: :account, dependent: :destroy has_many :notifications, inverse_of: :account, dependent: :destroy
has_many :conversations, class_name: 'AccountConversation', dependent: :destroy, inverse_of: :account has_many :conversations, class_name: 'AccountConversation', dependent: :destroy, inverse_of: :account
has_many :scheduled_statuses, inverse_of: :account, dependent: :destroy
# Pinned statuses # Pinned statuses
has_many :status_pins, inverse_of: :account, dependent: :destroy has_many :status_pins, inverse_of: :account, dependent: :destroy

@ -12,6 +12,10 @@ module AccountFinderConcern
find_remote(username, domain) || raise(ActiveRecord::RecordNotFound) find_remote(username, domain) || raise(ActiveRecord::RecordNotFound)
end end
def representative
find_local(Setting.site_contact_username.gsub(/\A@/, '')) || Account.local.find_by(suspended: false)
end
def find_local(username) def find_local(username)
find_remote(username, nil) find_remote(username, nil)
end end

@ -3,10 +3,23 @@
class Instance class Instance
include ActiveModel::Model include ActiveModel::Model
attr_accessor :domain, :accounts_count attr_accessor :domain, :accounts_count, :domain_block
def initialize(account) def initialize(resource)
@domain = account.domain @domain = resource.domain
@accounts_count = account.accounts_count @accounts_count = resource.accounts_count
@domain_block = resource.is_a?(DomainBlock) ? resource : DomainBlock.find_by(domain: domain)
end
def cached_sample_accounts
Rails.cache.fetch("#{cache_key}/sample_accounts", expires_in: 12.hours) { Account.where(domain: domain).searchable.joins(:account_stat).popular.limit(3) }
end
def to_param
domain
end
def cache_key
domain
end end
end end

@ -8,21 +8,10 @@ class InstanceFilter
end end
def results def results
scope = Account.remote.by_domain_accounts if params[:limited].present?
params.each do |key, value| DomainBlock.order(id: :desc)
scope.merge!(scope_for(key, value)) if value.present?
end
scope
end
private
def scope_for(key, value)
case key.to_s
when 'domain_name'
Account.matches_domain(value)
else else
raise "Unknown filter: #{key}" Account.remote.by_domain_accounts
end end
end end
end end

@ -17,6 +17,7 @@
# file_meta :json # file_meta :json
# account_id :bigint(8) # account_id :bigint(8)
# description :text # description :text
# scheduled_status_id :bigint(8)
# #
class MediaAttachment < ApplicationRecord class MediaAttachment < ApplicationRecord
@ -96,6 +97,7 @@ class MediaAttachment < ApplicationRecord
belongs_to :account, inverse_of: :media_attachments, optional: true belongs_to :account, inverse_of: :media_attachments, optional: true
belongs_to :status, inverse_of: :media_attachments, optional: true belongs_to :status, inverse_of: :media_attachments, optional: true
belongs_to :scheduled_status, inverse_of: :media_attachments, optional: true
has_attached_file :file, has_attached_file :file,
styles: ->(f) { file_styles f }, styles: ->(f) { file_styles f },
@ -112,8 +114,8 @@ class MediaAttachment < ApplicationRecord
validates :account, presence: true validates :account, presence: true
validates :description, length: { maximum: 420 }, if: :local? validates :description, length: { maximum: 420 }, if: :local?
scope :attached, -> { where.not(status_id: nil) } scope :attached, -> { where.not(status_id: nil).or(where.not(scheduled_status_id: nil)) }
scope :unattached, -> { where(status_id: nil) } scope :unattached, -> { where(status_id: nil, scheduled_status_id: nil) }
scope :local, -> { where(remote_url: '') } scope :local, -> { where(remote_url: '') }
scope :remote, -> { where.not(remote_url: '') } scope :remote, -> { where.not(remote_url: '') }

@ -68,7 +68,7 @@ class Relay < ApplicationRecord
end end
def some_local_account def some_local_account
@some_local_account ||= Account.local.find_by(suspended: false) @some_local_account ||= Account.representative
end end
def ensure_disabled def ensure_disabled

@ -0,0 +1,39 @@
# frozen_string_literal: true
# == Schema Information
#
# Table name: scheduled_statuses
#
# id :bigint(8) not null, primary key
# account_id :bigint(8)
# scheduled_at :datetime
# params :jsonb
#
class ScheduledStatus < ApplicationRecord
include Paginable
TOTAL_LIMIT = 300
DAILY_LIMIT = 25
belongs_to :account, inverse_of: :scheduled_statuses
has_many :media_attachments, inverse_of: :scheduled_status, dependent: :nullify
validate :validate_future_date
validate :validate_total_limit
validate :validate_daily_limit
private
def validate_future_date
errors.add(:scheduled_at, I18n.t('scheduled_statuses.too_soon')) if scheduled_at.present? && scheduled_at <= Time.now.utc + PostStatusService::MIN_SCHEDULE_OFFSET
end
def validate_total_limit
errors.add(:base, I18n.t('scheduled_statuses.over_total_limit', limit: TOTAL_LIMIT)) if account.scheduled_statuses.count >= TOTAL_LIMIT
end
def validate_daily_limit
errors.add(:base, I18n.t('scheduled_statuses.over_daily_limit', limit: DAILY_LIMIT)) if account.scheduled_statuses.where('scheduled_at::date = ?::date', scheduled_at).count >= DAILY_LIMIT
end
end

@ -5,7 +5,7 @@ class InstancePolicy < ApplicationPolicy
admin? admin?
end end
def resubscribe? def show?
admin? admin?
end end
end end

@ -0,0 +1,15 @@
# frozen_string_literal: true
class REST::ScheduledStatusSerializer < ActiveModel::Serializer
attributes :id, :scheduled_at, :params
has_many :media_attachments, serializer: REST::MediaAttachmentSerializer
def id
object.id.to_s
end
def params
object.params.without(:application_id)
end
end

@ -5,8 +5,8 @@ class ActivityPub::FetchRemoteAccountService < BaseService
SUPPORTED_TYPES = %w(Application Group Organization Person Service).freeze SUPPORTED_TYPES = %w(Application Group Organization Person Service).freeze
# Does a WebFinger roundtrip on each call # Does a WebFinger roundtrip on each call, unless `only_key` is true
def call(uri, id: true, prefetched_body: nil, break_on_redirect: false) def call(uri, id: true, prefetched_body: nil, break_on_redirect: false, only_key: false)
return ActivityPub::TagManager.instance.uri_to_resource(uri, Account) if ActivityPub::TagManager.instance.local_uri?(uri) return ActivityPub::TagManager.instance.uri_to_resource(uri, Account) if ActivityPub::TagManager.instance.local_uri?(uri)
@json = if prefetched_body.nil? @json = if prefetched_body.nil?
@ -21,9 +21,9 @@ class ActivityPub::FetchRemoteAccountService < BaseService
@username = @json['preferredUsername'] @username = @json['preferredUsername']
@domain = Addressable::URI.parse(@uri).normalized_host @domain = Addressable::URI.parse(@uri).normalized_host
return unless verified_webfinger? return unless only_key || verified_webfinger?
ActivityPub::ProcessAccountService.new.call(@username, @domain, @json) ActivityPub::ProcessAccountService.new.call(@username, @domain, @json, only_key: only_key)
rescue Oj::ParseError rescue Oj::ParseError
nil nil
end end

@ -33,8 +33,10 @@ class ActivityPub::ProcessAccountService < BaseService
after_protocol_change! if protocol_changed? after_protocol_change! if protocol_changed?
after_key_change! if key_changed? && !@options[:signed_with_known_key] after_key_change! if key_changed? && !@options[:signed_with_known_key]
unless @options[:only_key]
check_featured_collection! if @account.featured_collection_url.present? check_featured_collection! if @account.featured_collection_url.present?
check_links! unless @account.fields.empty? check_links! unless @account.fields.empty?
end
@account @account
rescue Oj::ParseError rescue Oj::ParseError
@ -54,11 +56,11 @@ class ActivityPub::ProcessAccountService < BaseService
end end
def update_account def update_account
@account.last_webfingered_at = Time.now.utc @account.last_webfingered_at = Time.now.utc unless @options[:only_key]
@account.protocol = :activitypub @account.protocol = :activitypub
set_immediate_attributes! set_immediate_attributes!
set_fetchable_attributes! set_fetchable_attributes! unless @options[:only_keys]
@account.save_with_optional_media! @account.save_with_optional_media!
end end

@ -4,7 +4,7 @@ class AppSignUpService < BaseService
def call(app, params) def call(app, params)
return unless allowed_registrations? return unless allowed_registrations?
user_params = params.slice(:email, :password, :agreement) user_params = params.slice(:email, :password, :agreement, :locale)
account_params = params.slice(:username) account_params = params.slice(:username)
user = User.create!(user_params.merge(created_by_application: app, password_confirmation: user_params[:password], account_attributes: account_params)) user = User.create!(user_params.merge(created_by_application: app, password_confirmation: user_params[:password], account_attributes: account_params))

@ -1,77 +1,101 @@
# frozen_string_literal: true # frozen_string_literal: true
class PostStatusService < BaseService class PostStatusService < BaseService
MIN_SCHEDULE_OFFSET = 5.minutes.freeze
# Post a text status update, fetch and notify remote users mentioned # Post a text status update, fetch and notify remote users mentioned
# @param [Account] account Account from which to post # @param [Account] account Account from which to post
# @param [String] text Message
# @param [Status] in_reply_to Optional status to reply to
# @param [Hash] options # @param [Hash] options
# @option [String] :text Message
# @option [Status] :thread Optional status to reply to
# @option [Boolean] :sensitive # @option [Boolean] :sensitive
# @option [String] :visibility # @option [String] :visibility
# @option [String] :spoiler_text # @option [String] :spoiler_text
# @option [String] :language
# @option [String] :scheduled_at
# @option [Enumerable] :media_ids Optional array of media IDs to attach # @option [Enumerable] :media_ids Optional array of media IDs to attach
# @option [Doorkeeper::Application] :application # @option [Doorkeeper::Application] :application
# @option [String] :idempotency Optional idempotency key # @option [String] :idempotency Optional idempotency key
# @return [Status] # @return [Status]
def call(account, text, in_reply_to = nil, **options) def call(account, options = {})
if options[:idempotency].present? @account = account
existing_id = redis.get("idempotency:status:#{account.id}:#{options[:idempotency]}") @options = options
return Status.find(existing_id) if existing_id @text = @options[:text] || ''
@in_reply_to = @options[:thread]
return idempotency_duplicate if idempotency_given? && idempotency_duplicate?
validate_media!
preprocess_attributes!
if scheduled?
schedule_status!
else
process_status!
postprocess_status!
bump_potential_friendship!
end end
media = validate_media!(options[:media_ids]) redis.setex(idempotency_key, 3_600, @status.id) if idempotency_given?
status = nil
if text.blank? && options[:spoiler_text].present? @status
text = '.'
text = media.find(&:video?) ? '📹' : '🖼' if media.size > 0
end end
visibility = options[:visibility] || account.user&.setting_default_privacy private
visibility = :unlisted if visibility == :public && account.silenced
ApplicationRecord.transaction do def preprocess_attributes!
status = account.statuses.create!(text: text, if @text.blank? && @options[:spoiler_text].present?
media_attachments: media || [], @text = '.'
thread: in_reply_to, @text = @media.find(&:video?) ? '📹' : '🖼' if @media.size > 0
sensitive: (options[:sensitive].nil? ? account.user&.setting_default_sensitive : options[:sensitive]) || options[:spoiler_text].present?, end
spoiler_text: options[:spoiler_text] || '', @visibility = @options[:visibility] || @account.user&.setting_default_privacy
visibility: visibility, @visibility = :unlisted if @visibility == :public && @account.silenced
language: language_from_option(options[:language]) || account.user&.setting_default_language&.presence || LanguageDetector.instance.detect(text, account), @scheduled_at = @options[:scheduled_at]&.to_datetime
application: options[:application]) @scheduled_at = nil if scheduled_in_the_past?
end end
process_hashtags_service.call(status) def process_status!
process_mentions_service.call(status) # The following transaction block is needed to wrap the UPDATEs to
# the media attachments when the status is created
LinkCrawlWorker.perform_async(status.id) unless status.spoiler_text?
DistributionWorker.perform_async(status.id)
unless status.local_only? ApplicationRecord.transaction do
Pubsubhubbub::DistributionWorker.perform_async(status.stream_entry.id) @status = @account.statuses.create!(status_attributes)
ActivityPub::DistributionWorker.perform_async(status.id)
end end
if options[:idempotency].present? process_hashtags_service.call(@status)
redis.setex("idempotency:status:#{account.id}:#{options[:idempotency]}", 3_600, status.id) process_mentions_service.call(@status)
end end
bump_potential_friendship(account, status) def schedule_status!
if @account.statuses.build(status_attributes).valid?
# The following transaction block is needed to wrap the UPDATEs to
# the media attachments when the scheduled status is created
status ApplicationRecord.transaction do
@status = @account.scheduled_statuses.create!(scheduled_status_attributes)
end
else
raise ActiveRecord::RecordInvalid
end
end end
private def postprocess_status!
LinkCrawlWorker.perform_async(@status.id) unless @status.spoiler_text?
def validate_media!(media_ids) DistributionWorker.perform_async(@status.id)
return if media_ids.blank? || !media_ids.is_a?(Enumerable) unless @status.local_only?
Pubsubhubbub::DistributionWorker.perform_async(@status.stream_entry.id)
ActivityPub::DistributionWorker.perform_async(@status.id)
end
end
raise Mastodon::ValidationError, I18n.t('media_attachments.validations.too_many') if media_ids.size > 4 def validate_media!
return if @options[:media_ids].blank? || !@options[:media_ids].is_a?(Enumerable)
media = MediaAttachment.where(status_id: nil).where(id: media_ids.take(4).map(&:to_i)) raise Mastodon::ValidationError, I18n.t('media_attachments.validations.too_many') if @options[:media_ids].size > 4
raise Mastodon::ValidationError, I18n.t('media_attachments.validations.images_and_video') if media.size > 1 && media.find(&:video?) @media = MediaAttachment.where(status_id: nil).where(id: @options[:media_ids].take(4).map(&:to_i))
media raise Mastodon::ValidationError, I18n.t('media_attachments.validations.images_and_video') if @media.size > 1 && @media.find(&:video?)
end end
def language_from_option(str) def language_from_option(str)
@ -90,10 +114,68 @@ class PostStatusService < BaseService
Redis.current Redis.current
end end
def bump_potential_friendship(account, status) def scheduled?
return if !status.reply? || account.id == status.in_reply_to_account_id @scheduled_at.present?
end
def idempotency_key
"idempotency:status:#{@account.id}:#{@options[:idempotency]}"
end
def idempotency_given?
@options[:idempotency].present?
end
def idempotency_duplicate
if scheduled?
@account.schedule_statuses.find(@idempotency_duplicate)
else
@account.statuses.find(@idempotency_duplicate)
end
end
def idempotency_duplicate?
@idempotency_duplicate = redis.get(idempotency_key)
end
def scheduled_in_the_past?
@scheduled_at.present? && @scheduled_at <= Time.now.utc + MIN_SCHEDULE_OFFSET
end
def bump_potential_friendship!
return if !@status.reply? || @account.id == @status.in_reply_to_account_id
ActivityTracker.increment('activity:interactions') ActivityTracker.increment('activity:interactions')
return if account.following?(status.in_reply_to_account_id) return if @account.following?(@status.in_reply_to_account_id)
PotentialFriendshipTracker.record(account.id, status.in_reply_to_account_id, :reply) PotentialFriendshipTracker.record(@account.id, @status.in_reply_to_account_id, :reply)
end
def status_attributes
{
text: @text,
media_attachments: @media || [],
thread: @in_reply_to,
sensitive: (@options[:sensitive].nil? ? @account.user&.setting_default_sensitive : @options[:sensitive]) || @options[:spoiler_text].present?,
spoiler_text: @options[:spoiler_text] || '',
visibility: @visibility,
language: language_from_option(@options[:language]) || @account.user&.setting_default_language&.presence || LanguageDetector.instance.detect(@text, @account),
application: @options[:application],
}
end
def scheduled_status_attributes
{
scheduled_at: @scheduled_at,
media_attachments: @media || [],
params: scheduled_options,
}
end
def scheduled_options
@options.tap do |options_hash|
options_hash[:in_reply_to_id] = options_hash.delete(:thread)&.id
options_hash[:application_id] = options_hash.delete(:application)&.id
options_hash[:scheduled_at] = nil
options_hash[:idempotency] = nil
end
end end
end end

@ -52,6 +52,6 @@ class ReportService < BaseService
end end
def some_local_account def some_local_account
@some_local_account ||= Account.local.where(suspended: false).first @some_local_account ||= Account.representative
end end
end end

@ -20,6 +20,7 @@ class SuspendAccountService < BaseService
owned_lists owned_lists
passive_relationships passive_relationships
report_notes report_notes
scheduled_statuses
status_pins status_pins
stream_entries stream_entries
subscriptions subscriptions

@ -0,0 +1,22 @@
# frozen_string_literal: true
class NoteLengthValidator < ActiveModel::EachValidator
def validate_each(record, attribute, value)
record.errors.add(attribute, I18n.t('statuses.over_character_limit', max: options[:maximum])) if too_long?(value)
end
private
def too_long?(value)
countable_text(value).mb_chars.grapheme_length > options[:maximum]
end
def countable_text(value)
return '' if value.nil?
value.dup.tap do |new_text|
new_text.gsub!(FetchLinkCardService::URL_PATTERN, 'x' * 23)
new_text.gsub!(Account::MENTION_RE, '@\2')
end
end
end

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

Loading…
Cancel
Save