diff options
174 files changed, 2013 insertions, 1185 deletions
diff --git a/.github/workflows/test-chart.yml b/.github/workflows/test-chart.yml new file mode 100644 index 000000000..b9ff80855 --- /dev/null +++ b/.github/workflows/test-chart.yml @@ -0,0 +1,138 @@ +# This is a GitHub workflow defining a set of jobs with a set of steps. +# ref: https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions +# +name: Test chart + +on: + pull_request: + paths: + - "chart/**" + - "!**.md" + - ".github/workflows/test-chart.yml" + push: + paths: + - "chart/**" + - "!**.md" + - ".github/workflows/test-chart.yml" + branches-ignore: + - "dependabot/**" + workflow_dispatch: + +permissions: + contents: read + +defaults: + run: + working-directory: chart + +jobs: + lint-templates: + runs-on: ubuntu-22.04 + + steps: + - uses: actions/checkout@v3 + - uses: actions/setup-python@v4 + with: + python-version: "3.x" + + - name: Install dependencies (yamllint) + run: pip install yamllint + + - run: helm dependency update + + - name: helm lint + run: | + helm lint . \ + --values dev-values.yaml + + - name: helm template + run: | + helm template . \ + --values dev-values.yaml \ + --output-dir rendered-templates + + - name: yamllint (only on templates we manage) + run: | + rm -rf rendered-templates/mastodon/charts + + yamllint rendered-templates \ + --config-data "{rules: {indentation: {spaces: 2}, line-length: disable}}" + + # This job helps us validate that rendered templates are valid k8s resources + # against a k8s api-server, via "helm template --validate", but also that a + # basic configuration can be used to successfully startup mastodon. + # + test-install: + runs-on: ubuntu-22.04 + timeout-minutes: 15 + + strategy: + fail-fast: false + matrix: + include: + # k3s-channel reference: https://update.k3s.io/v1-release/channels + - k3s-channel: latest + - k3s-channel: stable + + # This represents the oldest configuration we test against. + # + # The k8s version chosen is based on the oldest still supported k8s + # version among two managed k8s services, GKE, EKS. + # - GKE: https://endoflife.date/google-kubernetes-engine + # - EKS: https://endoflife.date/amazon-eks + # + # The helm client's version can influence what helper functions is + # available for use in the templates, currently we need v3.6.0 or + # higher. + # + - k3s-channel: v1.21 + helm-version: v3.6.0 + + steps: + - uses: actions/checkout@v3 + + # This action starts a k8s cluster with NetworkPolicy enforcement and + # installs both kubectl and helm. + # + # ref: https://github.com/jupyterhub/action-k3s-helm#readme + # + - uses: jupyterhub/action-k3s-helm@v3 + with: + k3s-channel: ${{ matrix.k3s-channel }} + helm-version: ${{ matrix.helm-version }} + metrics-enabled: false + traefik-enabled: false + docker-enabled: false + + - run: helm dependency update + + # Validate rendered helm templates against the k8s api-server + - name: helm template --validate + run: | + helm template --validate mastodon . \ + --values dev-values.yaml + + - name: helm install + run: | + helm install mastodon . \ + --values dev-values.yaml \ + --timeout 10m + + # This actions provides a report about the state of the k8s cluster, + # providing logs etc on anything that has failed and workloads marked as + # important. + # + # ref: https://github.com/jupyterhub/action-k8s-namespace-report#readme + # + - name: Kubernetes namespace report + uses: jupyterhub/action-k8s-namespace-report@v1 + if: always() + with: + important-workloads: >- + deploy/mastodon-sidekiq + deploy/mastodon-streaming + deploy/mastodon-web + job/mastodon-assets-precompile + job/mastodon-chewy-upgrade + job/mastodon-create-admin + job/mastodon-db-migrate diff --git a/AUTHORS.md b/AUTHORS.md index 9fc5f44f1..18b9f2d70 100644 --- a/AUTHORS.md +++ b/AUTHORS.md @@ -15,32 +15,32 @@ and provided thanks to the work of the following contributors: * [noellabo](https://github.com/noellabo) * [abcang](https://github.com/abcang) * [yiskah](https://github.com/yiskah) +* [tribela](https://github.com/tribela) * [mayaeh](https://github.com/mayaeh) * [nolanlawson](https://github.com/nolanlawson) * [ysksn](https://github.com/ysksn) -* [tribela](https://github.com/tribela) * [sorin-davidoi](https://github.com/sorin-davidoi) * [lynlynlynx](https://github.com/lynlynlynx) * [m4sk1n](mailto:me@m4sk.in) * [Marcin Mikołajczak](mailto:me@m4sk.in) -* [renatolond](https://github.com/renatolond) * [shleeable](https://github.com/shleeable) -* [alpaca-tc](https://github.com/alpaca-tc) +* [renatolond](https://github.com/renatolond) * [zunda](https://github.com/zunda) +* [alpaca-tc](https://github.com/alpaca-tc) * [nclm](https://github.com/nclm) * [ineffyble](https://github.com/ineffyble) * [ariasuni](https://github.com/ariasuni) * [Masoud Abkenar](mailto:ampbox@gmail.com) * [blackle](https://github.com/blackle) * [Quent-in](https://github.com/Quent-in) -* [JantsoP](https://github.com/JantsoP) * [Brawaru](https://github.com/Brawaru) +* [JantsoP](https://github.com/JantsoP) +* [trwnh](https://github.com/trwnh) * [nullkal](https://github.com/nullkal) * [yookoala](https://github.com/yookoala) * [dunn](https://github.com/dunn) * [Aditoo17](https://github.com/Aditoo17) * [Quenty31](https://github.com/Quenty31) -* [marek-lach](https://github.com/marek-lach) * [shuheiktgw](https://github.com/shuheiktgw) * [ashfurrow](https://github.com/ashfurrow) * [danhunsaker](https://github.com/danhunsaker) @@ -48,7 +48,6 @@ and provided thanks to the work of the following contributors: * [Jeroen](mailto:jeroenpraat@users.noreply.github.com) * [takayamaki](https://github.com/takayamaki) * [masarakki](https://github.com/masarakki) -* [trwnh](https://github.com/trwnh) * [ticky](https://github.com/ticky) * [ThisIsMissEm](https://github.com/ThisIsMissEm) * [hinaloe](https://github.com/hinaloe) @@ -57,16 +56,19 @@ and provided thanks to the work of the following contributors: * [Wonderfall](https://github.com/Wonderfall) * [matteoaquila](https://github.com/matteoaquila) * [yukimochi](https://github.com/yukimochi) -* [palindromordnilap](https://github.com/palindromordnilap) +* [nightpool](https://github.com/nightpool) +* [alixrossi](https://github.com/alixrossi) * [rkarabut](https://github.com/rkarabut) * [jeroenpraat](mailto:jeroenpraat@users.noreply.github.com) -* [nightpool](https://github.com/nightpool) +* [marek-lach](https://github.com/marek-lach) * [Artoria2e5](https://github.com/Artoria2e5) +* [rinsuki](https://github.com/rinsuki) * [marrus-sh](https://github.com/marrus-sh) * [krainboltgreene](https://github.com/krainboltgreene) * [pfigel](https://github.com/pfigel) * [BoFFire](https://github.com/BoFFire) * [Aldarone](https://github.com/Aldarone) +* [deepy](https://github.com/deepy) * [clworld](https://github.com/clworld) * [MasterGroosha](https://github.com/MasterGroosha) * [dracos](https://github.com/dracos) @@ -75,7 +77,6 @@ and provided thanks to the work of the following contributors: * [Sylvhem](https://github.com/Sylvhem) * [koyuawsmbrtn](https://github.com/koyuawsmbrtn) * [MitarashiDango](https://github.com/MitarashiDango) -* [rinsuki](https://github.com/rinsuki) * [angristan](https://github.com/angristan) * [JeanGauthier](https://github.com/JeanGauthier) * [kschaper](https://github.com/kschaper) @@ -87,14 +88,15 @@ and provided thanks to the work of the following contributors: * [MightyPork](https://github.com/MightyPork) * [ashleyhull-versent](https://github.com/ashleyhull-versent) * [yhirano55](https://github.com/yhirano55) +* [mashirozx](https://github.com/mashirozx) * [devkral](https://github.com/devkral) * [camponez](https://github.com/camponez) * [Hugo Gameiro](mailto:hmgameiro@gmail.com) +* [Marek Ľach](mailto:graweeld@googlemail.com) * [SerCom_KC](mailto:szescxz@gmail.com) * [aschmitz](https://github.com/aschmitz) * [mfmfuyu](https://github.com/mfmfuyu) * [kedamaDQ](https://github.com/kedamaDQ) -* [mashirozx](https://github.com/mashirozx) * [fpiesche](https://github.com/fpiesche) * [gandaro](https://github.com/gandaro) * [johnsudaar](https://github.com/johnsudaar) @@ -106,8 +108,10 @@ and provided thanks to the work of the following contributors: * [hikari-no-yume](https://github.com/hikari-no-yume) * [seefood](https://github.com/seefood) * [jackjennings](https://github.com/jackjennings) +* [sunny](https://github.com/sunny) * [puckipedia](https://github.com/puckipedia) -* [spla](mailto:spla@mastodont.cat) +* [splaGit](https://github.com/splaGit) +* [tateisu](https://github.com/tateisu) * [walf443](https://github.com/walf443) * [JoelQ](https://github.com/JoelQ) * [mistydemeo](https://github.com/mistydemeo) @@ -118,13 +122,15 @@ and provided thanks to the work of the following contributors: * [tsuwatch](https://github.com/tsuwatch) * [progval](https://github.com/progval) * [victorhck](https://github.com/victorhck) +* [Izorkin](https://github.com/Izorkin) * [manuelviens](mailto:manuelviens@users.noreply.github.com) -* [tateisu](https://github.com/tateisu) * [fvh-P](https://github.com/fvh-P) * [lfuelling](https://github.com/lfuelling) * [rtucker](https://github.com/rtucker) * [Anna e só](mailto:contraexemplos@gmail.com) +* [danieljakots](https://github.com/danieljakots) * [dariusk](https://github.com/dariusk) +* [Gomasy](https://github.com/Gomasy) * [kazu9su](https://github.com/kazu9su) * [komic](https://github.com/komic) * [lmorchard](https://github.com/lmorchard) @@ -137,6 +143,7 @@ and provided thanks to the work of the following contributors: * [goofy-bz](mailto:goofy@babelzilla.org) * [kadiix](https://github.com/kadiix) * [kodacs](https://github.com/kodacs) +* [luzpaz](https://github.com/luzpaz) * [marcin mikołajczak](mailto:me@m4sk.in) * [berkes](https://github.com/berkes) * [KScl](https://github.com/KScl) @@ -145,23 +152,26 @@ and provided thanks to the work of the following contributors: * [AA4ch1](https://github.com/AA4ch1) * [alexgleason](https://github.com/alexgleason) * [cpytel](https://github.com/cpytel) +* [cutls](https://github.com/cutls) * [northerner](https://github.com/northerner) * [weex](https://github.com/weex) +* [erbridge](https://github.com/erbridge) * [fhemberger](https://github.com/fhemberger) -* [Gomasy](https://github.com/Gomasy) * [greysteil](https://github.com/greysteil) * [henrycatalinismith](https://github.com/henrycatalinismith) +* [HolgerHuo](https://github.com/HolgerHuo) * [d6rkaiz](https://github.com/d6rkaiz) * [ladyisatis](https://github.com/ladyisatis) * [JMendyk](https://github.com/JMendyk) +* [kescherCode](https://github.com/kescherCode) * [JohnD28](https://github.com/JohnD28) * [znz](https://github.com/znz) * [saper](https://github.com/saper) * [Naouak](https://github.com/Naouak) * [pawelngei](https://github.com/pawelngei) +* [rgroothuijsen](https://github.com/rgroothuijsen) * [reneklacan](https://github.com/reneklacan) * [ekiru](https://github.com/ekiru) -* [Izorkin](https://github.com/Izorkin) * [unasuke](https://github.com/unasuke) * [geta6](https://github.com/geta6) * [happycoloredbanana](https://github.com/happycoloredbanana) @@ -174,7 +184,6 @@ and provided thanks to the work of the following contributors: * [aji-su](https://github.com/aji-su) * [ikuradon](https://github.com/ikuradon) * [nzws](https://github.com/nzws) -* [duxovni](https://github.com/duxovni) * [SuperSandro2000](https://github.com/SuperSandro2000) * [178inaba](https://github.com/178inaba) * [acid-chicken](https://github.com/acid-chicken) @@ -183,7 +192,6 @@ and provided thanks to the work of the following contributors: * [aablinov](https://github.com/aablinov) * [stalker314314](https://github.com/stalker314314) * [cohosh](https://github.com/cohosh) -* [cutls](https://github.com/cutls) * [huertanix](https://github.com/huertanix) * [eleboucher](https://github.com/eleboucher) * [halkeye](https://github.com/halkeye) @@ -191,6 +199,7 @@ and provided thanks to the work of the following contributors: * [treby](https://github.com/treby) * [jpdevries](https://github.com/jpdevries) * [gdpelican](https://github.com/gdpelican) +* [pbzweihander](https://github.com/pbzweihander) * [MonaLisaOverrdrive](https://github.com/MonaLisaOverrdrive) * [Kurtis Rainbolt-Greene](mailto:me@kurtisrainboltgreene.name) * [panarom](https://github.com/panarom) @@ -201,7 +210,6 @@ and provided thanks to the work of the following contributors: * [pierreozoux](https://github.com/pierreozoux) * [qguv](https://github.com/qguv) * [Ram Lmn](mailto:ramlmn@users.noreply.github.com) -* [rgroothuijsen](https://github.com/rgroothuijsen) * [Sascha](mailto:sascha@serenitylabs.cloud) * [harukasan](https://github.com/harukasan) * [stamak](https://github.com/stamak) @@ -217,11 +225,14 @@ and provided thanks to the work of the following contributors: * [chr-1x](https://github.com/chr-1x) * [esetomo](https://github.com/esetomo) * [foxiehkins](https://github.com/foxiehkins) +* [gol-cha](https://github.com/gol-cha) * [highemerly](https://github.com/highemerly) * [hoodie](mailto:hoodiekitten@outlook.com) * [kaiyou](https://github.com/kaiyou) * [007lva](https://github.com/007lva) * [luzi82](https://github.com/luzi82) +* [prplecake](https://github.com/prplecake) +* [duxovni](https://github.com/duxovni) * [slice](https://github.com/slice) * [tmm576](https://github.com/tmm576) * [unsmell](mailto:unsmell@users.noreply.github.com) @@ -251,25 +262,27 @@ and provided thanks to the work of the following contributors: * [cdutson](https://github.com/cdutson) * [farlistener](https://github.com/farlistener) * [baby-gnu](https://github.com/baby-gnu) -* [danieljakots](https://github.com/danieljakots) * [divergentdave](https://github.com/divergentdave) * [DavidLibeau](https://github.com/DavidLibeau) * [dmerejkowsky](https://github.com/dmerejkowsky) * [ddevault](https://github.com/ddevault) +* [emilyst](https://github.com/emilyst) +* [consideRatio](https://github.com/consideRatio) * [Fjoerfoks](https://github.com/Fjoerfoks) * [fmauNeko](https://github.com/fmauNeko) * [gloaec](https://github.com/gloaec) * [unstabler](https://github.com/unstabler) * [potato4d](https://github.com/potato4d) * [h-izumi](https://github.com/h-izumi) -* [HolgerHuo](https://github.com/HolgerHuo) * [ErikXXon](https://github.com/ErikXXon) * [ian-kelling](https://github.com/ian-kelling) * [eltociear](https://github.com/eltociear) * [immae](https://github.com/immae) * [J0WI](https://github.com/J0WI) -* [vahnj](https://github.com/vahnj) +* [koboldunderlord](https://github.com/koboldunderlord) * [foozmeat](https://github.com/foozmeat) +* [jgsmith](https://github.com/jgsmith) +* [raggi](https://github.com/raggi) * [jasonrhodes](https://github.com/jasonrhodes) * [Jason Snell](mailto:jason@newrelic.com) * [jviide](https://github.com/jviide) @@ -287,21 +300,25 @@ and provided thanks to the work of the following contributors: * [Markus Amalthea Magnuson](mailto:markus.magnuson@gmail.com) * [madmath03](https://github.com/madmath03) * [mig5](https://github.com/mig5) +* [mohe2015](https://github.com/mohe2015) * [moritzheiber](https://github.com/moritzheiber) * [Nathaniel Suchy](mailto:me@lunorian.is) * [ndarville](https://github.com/ndarville) * [NimaBoscarino](https://github.com/NimaBoscarino) * [aquarla](https://github.com/aquarla) * [Abzol](https://github.com/Abzol) +* [unextro](https://github.com/unextro) * [PatOnTheBack](https://github.com/PatOnTheBack) * [xPaw](https://github.com/xPaw) * [petzah](https://github.com/petzah) * [PeterDaveHello](https://github.com/PeterDaveHello) * [ignisf](https://github.com/ignisf) +* [postmodern](https://github.com/postmodern) * [lumenwrites](https://github.com/lumenwrites) * [remram44](https://github.com/remram44) * [sts10](https://github.com/sts10) * [u1-liquid](https://github.com/u1-liquid) +* [SISheogorath](https://github.com/SISheogorath) * [rosylilly](https://github.com/rosylilly) * [withshubh](https://github.com/withshubh) * [sim6](https://github.com/sim6) @@ -328,23 +345,23 @@ and provided thanks to the work of the following contributors: * [bsky](mailto:me@imbsky.net) * [codl](https://github.com/codl) * [cpsdqs](https://github.com/cpsdqs) +* [dogelover911](https://github.com/dogelover911) * [barzamin](https://github.com/barzamin) -* [gol-cha](https://github.com/gol-cha) * [gunchleoc](https://github.com/gunchleoc) * [fhalna](https://github.com/fhalna) * [haoyayoi](https://github.com/haoyayoi) +* [helloworldstack](https://github.com/helloworldstack) * [ik11235](https://github.com/ik11235) * [kawax](https://github.com/kawax) * [shrft](https://github.com/shrft) * [luigi](mailto:lvargas@rankia.com) -* [luzpaz](https://github.com/luzpaz) * [mbajur](https://github.com/mbajur) * [matsurai25](https://github.com/matsurai25) * [mecab](https://github.com/mecab) * [nicobz25](https://github.com/nicobz25) * [niwatori24](https://github.com/niwatori24) * [noiob](https://github.com/noiob) -* [oliverkeeble](https://github.com/oliverkeeble) +* [oliverkeeble](mailto:oliverkeeble@users.noreply.github.com) * [partev](https://github.com/partev) * [pinfort](https://github.com/pinfort) * [rbaumert](https://github.com/rbaumert) @@ -360,7 +377,7 @@ and provided thanks to the work of the following contributors: * [clarfonthey](https://github.com/clarfonthey) * [cygnan](https://github.com/cygnan) * [Awea](https://github.com/Awea) -* [eai04191](https://github.com/eai04191) +* [single-right-quote](https://github.com/single-right-quote) * [8398a7](https://github.com/8398a7) * [857b](https://github.com/857b) * [insom](https://github.com/insom) @@ -373,9 +390,10 @@ and provided thanks to the work of the following contributors: * [unleashed](https://github.com/unleashed) * [alxrcs](https://github.com/alxrcs) * [console-cowboy](https://github.com/console-cowboy) +* [Saiv46](https://github.com/Saiv46) * [Alkarex](https://github.com/Alkarex) * [a2](https://github.com/a2) -* [alfiedotwtf](https://github.com/alfiedotwtf) +* [Alfie John](mailto:33c6c91f3bb4a391082e8a29642cafaf@alfie.wtf) * [0xa](https://github.com/0xa) * [ashpieboop](https://github.com/ashpieboop) * [virtualpain](https://github.com/virtualpain) @@ -391,24 +409,34 @@ and provided thanks to the work of the following contributors: * [orlea](https://github.com/orlea) * [armandfardeau](https://github.com/armandfardeau) * [raboof](https://github.com/raboof) +* [v-aisac](https://github.com/v-aisac) +* [gi-yt](https://github.com/gi-yt) +* [boahc077](https://github.com/boahc077) * [aldatsa](https://github.com/aldatsa) * [jumbosushi](https://github.com/jumbosushi) * [acuteaura](https://github.com/acuteaura) * [ayumin](https://github.com/ayumin) * [bzg](https://github.com/bzg) * [BastienDurel](https://github.com/BastienDurel) +* [bearice](https://github.com/bearice) * [li-bei](https://github.com/li-bei) +* [hardillb](https://github.com/hardillb) * [Benedikt Geißler](mailto:benedikt@g5r.eu) * [BenisonSebastian](https://github.com/BenisonSebastian) * [Blake](mailto:blake.barnett@postmates.com) * [Brad Janke](mailto:brad.janke@gmail.com) +* [braydofficial](https://github.com/braydofficial) * [bclindner](https://github.com/bclindner) * [brycied00d](https://github.com/brycied00d) * [carlosjs23](https://github.com/carlosjs23) +* [WyriHaximus](https://github.com/WyriHaximus) * [cgxxx](https://github.com/cgxxx) * [kibitan](https://github.com/kibitan) +* [cdzombak](https://github.com/cdzombak) * [chrisheninger](https://github.com/chrisheninger) * [chris-martin](https://github.com/chris-martin) +* [offbyone](https://github.com/offbyone) +* [cclauss](https://github.com/cclauss) * [DoubleMalt](https://github.com/DoubleMalt) * [Moosh-be](https://github.com/Moosh-be) * [cchoi12](https://github.com/cchoi12) @@ -417,6 +445,8 @@ and provided thanks to the work of the following contributors: * [csu](https://github.com/csu) * [kklleemm](https://github.com/kklleemm) * [colindean](https://github.com/colindean) +* [CommanderRoot](https://github.com/CommanderRoot) +* [connorshea](https://github.com/connorshea) * [DeeUnderscore](https://github.com/DeeUnderscore) * [dachinat](https://github.com/dachinat) * [Daggertooth](mailto:dev@monsterpit.net) @@ -428,35 +458,40 @@ and provided thanks to the work of the following contributors: * [dar5hak](https://github.com/dar5hak) * [kant](https://github.com/kant) * [maxolasersquad](https://github.com/maxolasersquad) -* [singingwolfboy](https://github.com/singingwolfboy) -* [caldwell](https://github.com/caldwell) -* [davidcelis](https://github.com/davidcelis) -* [davefp](https://github.com/davefp) -* [hannahwhy](https://github.com/hannahwhy) -* [debanshuk](https://github.com/debanshuk) -* [mascali33](https://github.com/mascali33) -* [DerekNonGeneric](https://github.com/DerekNonGeneric) -* [dblandin](https://github.com/dblandin) -* [Aranaur](https://github.com/Aranaur) -* [dtschust](https://github.com/dtschust) -* [Dryusdan](https://github.com/Dryusdan) -* [d3vgru](https://github.com/d3vgru) -* [Elizafox](https://github.com/Elizafox) -* [enewhuis](https://github.com/enewhuis) -* [ericblade](https://github.com/ericblade) -* [mikoim](https://github.com/mikoim) -* [espenronnevik](https://github.com/espenronnevik) +* [David Baumgold](mailto:david@davidbaumgold.com) +* [David Caldwell](mailto:david+github@porkrind.org) +* [David Celis](mailto:me@davidcel.is) +* [David Hewitt](mailto:davidmhewitt@users.noreply.github.com) +* [David Underwood](mailto:davefp@gmail.com) +* [David Yip](mailto:yipdw@member.fsf.org) +* [Debanshu Kundu](mailto:debanshu.kundu@joshtechnologygroup.com) +* [Denis Teyssier](mailto:admin@mascali.ovh) +* [Derek Lewis](mailto:derekcecillewis@gmail.com) +* [Devon Blandin](mailto:dblandin@gmail.com) +* [Drew Gates](mailto:aranaur@users.noreply.github.com) +* [Drew Schuster](mailto:dtschust@gmail.com) +* [Dryusdan](mailto:dryusdan@dryusdan.fr) +* [Eai](mailto:eai@mizle.net) +* [Ed Knutson](mailto:knutsoned@gmail.com) +* [Effy Elden](mailto:effy@effy.space) +* [Elizabeth Myers](mailto:elizabeth@interlinked.me) +* [Eric](mailto:enewhuis@gmail.com) +* [Eric Blade](mailto:blade.eric@gmail.com) +* [Eshin Kunishima](mailto:mikoim@users.noreply.github.com) +* [Espen Rønnevik](mailto:espen@ronnevik.net) * [Expenses](mailto:expenses@airmail.cc) -* [fabianonline](https://github.com/fabianonline) -* [shello](https://github.com/shello) -* [Finariel](https://github.com/Finariel) -* [siuying](https://github.com/siuying) -* [zoc](https://github.com/zoc) -* [fwenzel](https://github.com/fwenzel) -* [gabrielrumiranda](https://github.com/gabrielrumiranda) -* [GenbuHase](https://github.com/GenbuHase) -* [nilsding](https://github.com/nilsding) -* [hattori6789](https://github.com/hattori6789) +* [Fabian Schlenz](mailto:mail@fabianonline.de) +* [Faye Duxovni](mailto:duxovni@duxovni.org) +* [Filipe Rodrigues](mailto:shello@shello.org) +* [Finariel](mailto:finariel@gmail.com) +* [Francis Chong](mailto:francis@ignition.hk) +* [Franck Zoccolo](mailto:franck@zoccolo.com) +* [Fred Wenzel](mailto:fwenzel@users.noreply.github.com) +* [Gabriel Rubens](mailto:gabrielrumiranda@gmail.com) +* [Gaelan Steele](mailto:gbs@canishe.com) +* [Genbu Hase](mailto:hasegenbu@gmail.com) +* [Georg Gadinger](mailto:nilsding@nilsding.org) +* [George Hattori](mailto:hattori6789@users.noreply.github.com) * [Gergely Nagy](mailto:algernon@users.noreply.github.com) * [Giuseppe Pignataro](mailto:rogepix@gmail.com) * [Greg V](mailto:greg@unrelenting.technology) @@ -466,7 +501,9 @@ and provided thanks to the work of the following contributors: * [György Nádudvari](mailto:reedcourty@users.noreply.github.com) * [HIKARU KOBORI](mailto:hk.uec.univ@gmail.com) * [Haelwenn Monnier](mailto:lanodan@users.noreply.github.com) +* [Hampton Lintorn-Catlin](mailto:hcatlin@gmail.com) * [Harmon](mailto:harmon758@gmail.com) +* [Hayden](mailto:contact@winisreallybored.com) * [HellPie](mailto:hellpie@users.noreply.github.com) * [Herbert Kagumba](mailto:habukagumba@gmail.com) * [Hiroe Jun](mailto:jun.hiroe@gmail.com) @@ -479,6 +516,7 @@ and provided thanks to the work of the following contributors: * [Ian McDowell](mailto:me@ianmcdowell.net) * [Iijima Yasushi](mailto:kurage.cc@gmail.com) * [Ingo Blechschmidt](mailto:iblech@web.de) +* [Irie Aoi](mailto:eai@mizle.net) * [J Yeary](mailto:usbsnowcrash@users.noreply.github.com) * [Jack Michaud](mailto:jack-michaud@users.noreply.github.com) * [Jakub Mendyk](mailto:jakubmendyk.szkola@gmail.com) @@ -493,6 +531,7 @@ and provided thanks to the work of the following contributors: * [Jo Decker](mailto:trolldecker@users.noreply.github.com) * [Joan Montané](mailto:jmontane@users.noreply.github.com) * [Joe](mailto:401283+htmlbyjoe@users.noreply.github.com) +* [Joe Friedl](mailto:stuff@joefriedl.net) * [Jonathan Klee](mailto:klee.jonathan@gmail.com) * [Jordan Guerder](mailto:jguerder@fr.pulseheberg.net) * [Joseph Mingrone](mailto:jehops@users.noreply.github.com) @@ -502,6 +541,7 @@ and provided thanks to the work of the following contributors: * [Julien](mailto:tiwy57@users.noreply.github.com) * [Julien Deswaef](mailto:juego@requiem4tv.com) * [June Sallou](mailto:jnsll@users.noreply.github.com) +* [Justin Thomas](mailto:justin@jdt.io) * [Jérémy Benoist](mailto:j0k3r@users.noreply.github.com) * [KEINOS](mailto:github@keinos.com) * [Kairui Song | 宋恺睿](mailto:ryncsn@gmail.com) @@ -522,6 +562,7 @@ and provided thanks to the work of the following contributors: * [Mantas](mailto:mistermantas@users.noreply.github.com) * [Mareena Kunjachan](mailto:mareenakunjachan@gmail.com) * [Marek Lach](mailto:marek.brohatwack.lach@gmail.com) +* [Markus Petzsch](mailto:markus@petzsch.eu) * [Markus R](mailto:wirehack7@users.noreply.github.com) * [Marty McGuire](mailto:schmartissimo@gmail.com) * [Marvin Kopf](mailto:marvinkopf@posteo.de) @@ -531,12 +572,15 @@ and provided thanks to the work of the following contributors: * [Mathias B](mailto:10813340+mathias-b@users.noreply.github.com) * [Mathieu Brunot](mailto:mb.mathieu.brunot@gmail.com) * [Matt](mailto:matt-auckland@users.noreply.github.com) +* [Matt Corallo](mailto:649246+thebluematt@users.noreply.github.com) * [Matt Sweetman](mailto:webroo@gmail.com) +* [Matthias Bethke](mailto:matthias@towiski.de) * [Matthias Beyer](mailto:mail@beyermatthias.de) * [Matthias Jouan](mailto:matthias.jouan@gmail.com) * [Matthieu Paret](mailto:matthieuparet69@gmail.com) * [Maxime BORGES](mailto:maxime.borges@gmail.com) * [Mayu Laierlence](mailto:minacle@live.com) +* [Meisam](mailto:39205857+mftabriz@users.noreply.github.com) * [Michael Deeb](mailto:michaeldeeb@me.com) * [Michael Vieira](mailto:dtox94@gmail.com) * [Michel](mailto:michel@cyweo.com) @@ -558,6 +602,7 @@ and provided thanks to the work of the following contributors: * [Nanamachi](mailto:town7.haruki@gmail.com) * [Nathaniel Ekoniak](mailto:nekoniak@ennate.tech) * [NecroTechno](mailto:necrotechno@riseup.net) +* [Nicholas La Roux](mailto:larouxn@gmail.com) * [Nick Gerakines](mailto:nick@gerakines.net) * [Nicolai von Neudeck](mailto:nicolai@vonneudeck.com) * [Ninetailed](mailto:ninetailed@gmail.com) @@ -575,18 +620,25 @@ and provided thanks to the work of the following contributors: * [PatrickRWells](mailto:32802366+patrickrwells@users.noreply.github.com) * [Paul](mailto:naydex.mc+github@gmail.com) * [Pete Keen](mailto:pete@petekeen.net) +* [Pierre Bourdon](mailto:delroth@gmail.com) * [Pierre-Morgan Gate](mailto:pgate@users.noreply.github.com) * [Ratmir Karabut](mailto:rkarabut@sfmodern.ru) * [Reto Kromer](mailto:retokromer@users.noreply.github.com) +* [Rob Petti](mailto:rob.petti@gmail.com) * [Rob Watson](mailto:rfwatson@users.noreply.github.com) +* [Robert Laurenz](mailto:8169746+laurenzcodes@users.noreply.github.com) * [Rohan Sharma](mailto:i.am.lone.survivor@protonmail.com) +* [Roni Laukkarinen](mailto:roni@laukkarinen.info) * [Ryan Freebern](mailto:ryan@freebern.org) * [Ryan Wade](mailto:ryan.wade@protonmail.com) * [Ryo Kajiwara](mailto:kfe-fecn6.prussian@s01.info) * [S.H](mailto:gamelinks007@gmail.com) +* [SJang1](mailto:git@sjang.dev) * [Sadiq Saif](mailto:staticsafe@users.noreply.github.com) * [Sam Hewitt](mailto:hewittsamuel@gmail.com) +* [Samuel Kaiser](mailto:sk22@mailbox.org) * [Sara Aimée Smiseth](mailto:51710585+sarasmiseth@users.noreply.github.com) +* [Sara Golemon](mailto:pollita@php.net) * [Satoshi KOJIMA](mailto:skoji@mac.com) * [ScienJus](mailto:i@scienjus.com) * [Scott Larkin](mailto:scott@codeclimate.com) @@ -607,6 +659,7 @@ and provided thanks to the work of the following contributors: * [Spanky](mailto:2788886+spankyworks@users.noreply.github.com) * [Stanislas](mailto:stanislas.lange@pm.me) * [StefOfficiel](mailto:pichard.stephane@free.fr) +* [Stefano Pigozzi](mailto:ste.pigozzi@gmail.com) * [Steven Tappert](mailto:admin@dark-it.net) * [Stéphane Guillou](mailto:stephane.guillou@member.fsf.org) * [Su Yang](mailto:soulteary@users.noreply.github.com) @@ -619,13 +672,16 @@ and provided thanks to the work of the following contributors: * [TakesxiSximada](mailto:takesxi.sximada@gmail.com) * [Tao Bror Bojlén](mailto:brortao@users.noreply.github.com) * [Taras Gogol](mailto:taras2358@gmail.com) +* [The Stranjer](mailto:791672+thestranjer@users.noreply.github.com) * [TheInventrix](mailto:theinventrix@users.noreply.github.com) * [TheMainOne](mailto:50847364+theevilskeleton@users.noreply.github.com) * [Thomas Alberola](mailto:thomas@needacoffee.fr) +* [Thomas Citharel](mailto:github@tcit.fr) * [Toby Deshane](mailto:fortyseven@users.noreply.github.com) * [Toby Pinder](mailto:gigitrix@gmail.com) * [Tomonori Murakami](mailto:crosslife777@gmail.com) * [TomoyaShibata](mailto:wind.of.hometown@gmail.com) +* [Tony Jiang](mailto:yujiang99@gmail.com) * [Treyssat-Vincent Nino](mailto:treyssatvincent@users.noreply.github.com) * [Truong Nguyen](mailto:truongnmt.dev@gmail.com) * [Udo Kramer](mailto:optik@fluffel.io) @@ -634,6 +690,7 @@ and provided thanks to the work of the following contributors: * [Ushitora Anqou](mailto:ushitora_anqou@yahoo.co.jp) * [Valentin Lorentz](mailto:progval+git@progval.net) * [Vladimir Mincev](mailto:vladimir@canicinteractive.com) +* [Vyr Cossont](mailto:vyrcossont@users.noreply.github.com) * [Waldir Pimenta](mailto:waldyrious@gmail.com) * [Wenceslao Páez Chávez](mailto:wcpaez@gmail.com) * [Wesley Ellis](mailto:tahnok@gmail.com) @@ -648,10 +705,12 @@ and provided thanks to the work of the following contributors: * [YaQ](mailto:i_k_o_m_a_7@yahoo.co.jp) * [Yanaken](mailto:yanakend@gmail.com) * [Yann Klis](mailto:yann.klis@gmail.com) +* [Yarden Shoham](mailto:hrsi88@gmail.com) * [Yağızhan](mailto:35808275+yagizhan49@users.noreply.github.com) * [Yeechan Lu](mailto:wz.bluesnow@gmail.com) * [Your Name](mailto:lorenzd@gmail.com) * [Yusuke Abe](mailto:moonset20@gmail.com) +* [Zach Flanders](mailto:zachflanders@gmail.com) * [Zach Neill](mailto:neillz@berea.edu) * [Zachary Spector](mailto:logicaldash@gmail.com) * [ZiiX](mailto:ziix@users.noreply.github.com) @@ -666,8 +725,8 @@ and provided thanks to the work of the following contributors: * [chrolis](mailto:chrolis@users.noreply.github.com) * [cormo](mailto:cormorant2+github@gmail.com) * [d0p1](mailto:dopi-sama@hush.com) -* [dogelover911](mailto:84288771+dogelover911@users.noreply.github.com) * [dxwc](mailto:dxwc@users.noreply.github.com) +* [eai04191](mailto:eai@mizle.net) * [evilny0](mailto:evilny0@moomoocamp.net) * [febrezo](mailto:felixbrezo@gmail.com) * [fsubal](mailto:fsubal@users.noreply.github.com) @@ -678,7 +737,6 @@ and provided thanks to the work of the following contributors: * [hakoai](mailto:hk--76@qa2.so-net.ne.jp) * [haosbvnker](mailto:github@chaosbunker.com) * [heguro](mailto:65112898+heguro@users.noreply.github.com) -* [helloworldstack](mailto:66512512+helloworldstack@users.noreply.github.com) * [ichi_i](mailto:51489410+ichi-i@users.noreply.github.com) * [isati](mailto:phil@juchnowi.cz) * [jacob](mailto:jacobherringtondeveloper@gmail.com) @@ -688,15 +746,18 @@ and provided thanks to the work of the following contributors: * [jooops](mailto:joops@autistici.org) * [jukper](mailto:jukkaperanto@gmail.com) * [jumoru](mailto:jumoru@mailbox.org) +* [k.bigwheel (kazufumi nishida)](mailto:k.bigwheel+eng@gmail.com) * [kaias1jp](mailto:kaias1jp@gmail.com) * [karlyeurl](mailto:karl.yeurl@gmail.com) * [kawaguchi](mailto:jiikko@users.noreply.github.com) * [kedama](mailto:32974885+kedamadq@users.noreply.github.com) +* [keiya](mailto:keiya_21@yahoo.co.jp) * [kuro5hin](mailto:rusty@kuro5hin.org) * [leo60228](mailto:leo@60228.dev) * [matildepark](mailto:matilde.park@pm.me) * [maxypy](mailto:maxime@mpigou.fr) * [mhe](mailto:mail@marcus-herrmann.com) +* [mickkael](mailto:19755421+mickkael@users.noreply.github.com) * [mike castleman](mailto:m@mlcastle.net) * [mimikun](mailto:dzdzble_effort_311@outlook.jp) * [mohemohe](mailto:mohemohe@users.noreply.github.com) @@ -707,9 +768,11 @@ and provided thanks to the work of the following contributors: * [notozeki](mailto:notozeki@users.noreply.github.com) * [ntl-purism](mailto:57806346+ntl-purism@users.noreply.github.com) * [nzws](mailto:git-yuzu@svk.jp) +* [pea-sys](mailto:49807271+pea-sys@users.noreply.github.com) * [potpro](mailto:pptppctt@gmail.com) * [proxy](mailto:51172302+3n-k1@users.noreply.github.com) * [rch850](mailto:rich850@gmail.com) +* [rcombs](mailto:rcombs@rcombs.me) * [roikale](mailto:roikale@users.noreply.github.com) * [rysiekpl](mailto:rysiek@hackerspace.pl) * [sasanquaneuf](mailto:sasanquaneuf@gmail.com) @@ -726,13 +789,13 @@ and provided thanks to the work of the following contributors: * [tmyt](mailto:shigure@refy.net) * [trevDev()](mailto:trev@trevdev.ca) * [tsia](mailto:github@tsia.de) +* [txt-file](mailto:44214237+txt-file@users.noreply.github.com) * [utam0k](mailto:k0ma@utam0k.jp) * [vpzomtrrfrt](mailto:vpzomtrrfrt@gmail.com) * [walfie](mailto:walfington@gmail.com) * [y-temp4](mailto:y.temp4@gmail.com) * [ymmtmdk](mailto:ymmtmdk@gmail.com) * [yoshipc](mailto:yoooo@yoshipc.net) -* [zunda](mailto:zundan@gmail.com) * [Özcan Zafer AYAN](mailto:ozcanzaferayan@gmail.com) * [ばん](mailto:detteiu0321@gmail.com) * [ふるふる](mailto:frfs@users.noreply.github.com) @@ -752,599 +815,951 @@ This document is provided for informational purposes only. Since it is only upda Following people have contributed to translation of Mastodon: - GunChleoc (*Scottish Gaelic*) -- ケインツロ 👾 (KNTRO) (*Spanish, Argentina*) -- Sveinn í Felli (sveinki) (*Icelandic*) +- ケインツロ ⚧️👾🛸 (KNTRO) (*Spanish, Argentina*) - Hồ Nhất Duy (honhatduy) (*Vietnamese*) +- Sveinn í Felli (sveinki) (*Icelandic*) +- Kristaps (Kristaps_M) (*Latvian*) +- NCAA (*Danish, French*) - Zoltán Gera (gerazo) (*Hungarian*) -- Kristaps_M (*Latvian*) -- NCAA (*French, Danish*) -- adrmzz (*Sardinian*) -- Xosé M. (XoseM) (*Spanish, Galician*) -- Ramdziana F Y (rafeyu) (*Indonesian*) -- Jeong Arm (Kjwon15) (*Spanish, Japanese, Korean, Esperanto*) +- ghose (XoseM) (*Galician, Spanish*) +- Jeong Arm (Kjwon15) (*Korean, Esperanto, Japanese, Spanish*) - Emanuel Pina (emanuelpina) (*Portuguese*) -- qezwan (*Persian, Sorani (Kurdish)*) -- Besnik_b (*Albanian*) -- ButterflyOfFire (BoFFire) (*French, Arabic, Kabyle*) +- Reyzadren (*Ido, Malay*) - Thai Localization (thl10n) (*Thai*) +- Besnik_b (*Albanian*) +- Joene (joenepraat) (*Dutch*) - Cyax (Cyaxares) (*Kurmanji (Kurdish)*) +- adrmzz (*Sardinian*) +- Ramdziana F Y (rafeyu) (*Indonesian*) +- xatier (*Chinese Traditional, Chinese Traditional, Hong Kong*) +- qezwan (*Sorani (Kurdish), Persian*) +- spla (*Catalan, Spanish*) +- ButterflyOfFire (BoFFire) (*Arabic, French, Kabyle*) +- Martin (miles) (*Slovenian*) +- නාමල් ජයසිංහ (nimnaya) (*Sinhala*) +- Asier Iturralde Sarasola (aldatsa) (*Basque*) +- Ondřej Pokorný (unextro) (*Czech*) +- Roboron (*Spanish*) - taicv (*Vietnamese*) +- koyu (*German*) - Daniele Lira Mereb (danilmereb) (*Portuguese, Brazilian*) -- spla (*Spanish, Catalan*) +- T. E. Kalaycı (tekrei) (*Turkish*) - Evert Prants (IcyDiamond) (*Estonian*) -- koyu (*German*) -- Alix Rossi (palindromordnilap) (*French, Esperanto, Corsican*) -- Joene (joenepraat) (*Dutch*) +- Yair Mahalalel (yairm) (*Hebrew*) +- Ihor Hordiichuk (ihor_ck) (*Ukrainian*) +- Alessandro Levati (Oct326) (*Italian*) +- Kimmo Kujansuu (mrkujansuu) (*Finnish*) +- Alix Rossi (palindromordnilap) (*Corsican, Esperanto, French*) +- Danial Behzadi (danialbehzadi) (*Persian*) - stan ionut (stanionut12) (*Romanian*) - Mastodon 中文译者 (mastodon-linguist) (*Chinese Simplified*) - Kristijan Tkalec (lapor) (*Slovenian*) -- Danial Behzadi (danialbehzadi) (*Persian*) -- Asier Iturralde Sarasola (aldatsa) (*Basque*) +Alexander Sorokin (Brawaru) (*Russian, Vietnamese, Swedish, Portuguese, Tamil, Kabyle, Polish, Italian, Catalan, Armenian, Hungarian, Albanian, Greek, Galician, Korean, Ukrainian, German, Danish, French*) - ManeraKai (*Arabic*) - мачко (ma4ko) (*Bulgarian*) -- Roboron (*Spanish*) -- Alessandro Levati (Oct326) (*Italian*) -- xatier (*Chinese Traditional, Chinese Traditional, Hong Kong*) -- Ondřej Pokorný (unextro) (*Czech*) -- Alexander Sorokin (Brawaru) (*French, Catalan, Danish, German, Greek, Hungarian, Armenian, Korean, Portuguese, Russian, Albanian, Swedish, Ukrainian, Vietnamese, Galician*) - kamee (*Armenian*) -- Michal Stanke (mstanke) (*Czech*) +- Yamagishi Kazutoshi (ykzts) (*Japanese, Icelandic, Sorani (Kurdish), Albanian, Vietnamese, Chinese Simplified*) +- Takeçi (polygoat) (*French, Italian*) +- REMOVED_USER (*Czech*) - borys_sh (*Ukrainian*) - Imre Kristoffer Eilertsen (DandelionSprout) (*Norwegian*) -- yeft (*Chinese Traditional, Chinese Traditional, Hong Kong*) +- Marek Ľach (mareklach) (*Slovak, Polish*) +- yeft (*Chinese Traditional, Hong Kong, Chinese Traditional*) +- D. Cederberg (cederberget) (*Swedish*) - Miguel Mayol (mitcoes) (*Spanish, Catalan*) -- Marek Ľach (mareklach) (*Polish, Slovak*) +- enolp (*Asturian*) - Manuel Viens (manuelviens) (*French*) -- Kimmo Kujansuu (mrkujansuu) (*Finnish*) +- cybergene (*Japanese*) +- REMOVED_USER (*Turkish*) +- xpil (*Polish, Scottish Gaelic*) +- Balázs Meskó (mesko.balazs) (*Hungarian, Czech*) - Koala Yeung (yookoala) (*Chinese Traditional, Hong Kong*) -- enolp (*Asturian*) - Osoitz (*Basque*) -- Peterandre (*Norwegian, Norwegian Nynorsk*) -- tzium (*Sardinian*) +- Amir Rubinstein - TAU (AmirrTAU) (*Hebrew, Indonesian*) - Maya Minatsuki (mayaeh) (*Japanese*) -- Mélanie Chauvel (ariasuni) (*French, Arabic, Czech, German, Greek, Hungarian, Slovenian, Ukrainian, Chinese Simplified, Portuguese, Brazilian, Persian, Norwegian Nynorsk, Esperanto, Breton, Corsican, Sardinian, Kabyle*) -- T. E. Kalaycı (tekrei) (*Turkish*) -- Takeçi (polygoat) (*French, Italian*) +- Peterandre (*Norwegian Nynorsk, Norwegian*) +Mélanie Chauvel (ariasuni) (*French, Esperanto, Norwegian Nynorsk, Persian, Kabyle, Sardinian, Corsican, Breton, Portuguese, Brazilian, Arabic, Chinese Simplified, Ukrainian, Slovenian, Greek, German, Czech, Hungarian*) +- tzium (*Sardinian*) +- Diluns (*Occitan*) - Galician Translator (Galician_translator) (*Galician*) +- Marcin Mikołajczak (mkljczkk) (*Polish, Czech, Russian*) +- Jeff Huang (s8321414) (*Chinese Traditional*) +- Pixelcode (realpixelcode) (*German*) +- Allen Zhong (AstroProfundis) (*Chinese Simplified*) - lamnatos (*Greek*) - Sean Young (assanges) (*Chinese Traditional*) +- retiolus (*Catalan, French, Spanish*) - tolstoevsky (*Russian*) -- Ihor Hordiichuk (ihor_ck) (*Ukrainian*) - Ali Demirtaş (alidemirtas) (*Turkish*) -- Jasmine Cam Andrever (gourmas) (*Cornish*) +- J. Cam Andrever-Wright (gourmas) (*Cornish*) - coxde (*Chinese Simplified*) +- Dremski (*Bulgarian*) - gagik_ (*Armenian*) - Masoud Abkenar (mabkenar) (*Persian*) - arshat (*Kazakh*) -- Marcin Mikołajczak (mkljczkk) (*Czech, Polish, Russian*) -- Jeff Huang (s8321414) (*Chinese Traditional*) +- Ira (seefood) (*Hebrew*) +- Linerly (*Indonesian*) - Blak Ouille (BlakOuille16) (*French*) - e (diveedd) (*Kurmanji (Kurdish)*) - Em St Cenydd (cancennau) (*Welsh*) -- Diluns (*Occitan*) +- Tigran (tigransimonyan) (*Armenian*) +- Draacoun (*Portuguese, Brazilian*) +- REMOVED_USER (*Turkish*) - Nurul Azeera Hidayah @ Muhammad Nur Hidayat Yasuyoshi (MNH48.moe) (mnh48) (*Malay*) -- Tagomago (tagomago) (*French, Spanish*) -- Jurica (ahjk) (*Croatian*) +- Tagomago (tagomago) (*Spanish, French*) +- Ashun (ashune) (*Croatian*) - Aditoo17 (*Czech*) -- Tigran (tigransimonyan) (*Armenian*) - vishnuvaratharajan (*Tamil*) - pulmonarycosignerkindness (*Swedish*) - calypsoopenmail (*French*) -- cybergene (cyber-gene) (*Japanese*) +- REMOVED_USER (*Kabyle*) +- snerk (*Norwegian Nynorsk*) +- Sebastian (SebastianBerlin) (*German*) +- lisawe (*Norwegian*) +- serratrad (*Catalan*) - Bran_Ruz (*Breton*) +- ViktorOn (*Russian, Danish*) - Gearguy (*Finnish*) +- Andi Chandler (andibing) (*English, United Kingdom*) +- Tor Egil Hoftun Kvæstad (Taloran) (*Norwegian Nynorsk*) - GiorgioHerbie (*Italian*) -- Balázs Meskó (mesko.balazs) (*Czech, Hungarian*) -- Martin (miles) (*Slovenian*) +- හෙළබස සමූහය (HelaBasa) (*Sinhala*) +- kat (katktv) (*Ukrainian, Russian*) +- Yi-Jyun Pan (pan93412) (*Chinese Traditional*) +- Fjoerfoks (fryskefirefox) (*Frisian, Dutch*) +- Eshagh (eshagh79) (*Persian*) - regulartranslator (*Portuguese, Brazilian*) - Saederup92 (*Danish*) -- ozzii (*French, Serbian (Cyrillic)*) +- ozzii (Serbian (Cyrillic), French) - Irfan (Irfan_Radz) (*Malay*) -- Yi-Jyun Pan (pan93412) (*Chinese Traditional*) - ClearlyClaire (*French, Icelandic*) +- Sokratis Alichanidis (alichani) (*Greek*) +- Jiří Podhorecký (trendspotter) (*Czech*) - Akarshan Biswas (biswasab) (*Bengali, Sanskrit*) +- Robert Wolniak (Szkodnix) (*Polish*) +- Jan Lindblom (janlindblom) (*Swedish*) +- Dewi (Unkorneg) (*Breton, French*) - Kristoffer Grundström (Umeaboy) (*Swedish*) - Rafael H L Moretti (Moretti) (*Portuguese, Brazilian*) - d5Ziif3K (*Ukrainian*) -- හෙළබස (HelaBasa) (*Sinhala*) -- xpil (*Polish*) -- Rojdayek (*Kurmanji (Kurdish)*) +- Nemu (Dormemulo) (*Esperanto, French, Italian, Ido, Afrikaans*) +- Johan Mynhardt (johanmynhardt) (*Afrikaans*) +- Rojdayek (Kurmanji (Kurdish)) +- REMOVED_USER (*Portuguese, Brazilian*) +- GCardo (*Portuguese, Brazilian*) - christalleras (*Norwegian Nynorsk*) -- Allen Zhong (AstroProfundis) (*Chinese Simplified*) -- Taloran (*Norwegian Nynorsk*) -- Sokratis Alichanidis (alichani) (*Greek*) +- diorama (*Italian*) +- Jaz-Michael King (jazmichaelking) (*Welsh*) - Catalina (catalina.st) (*Romanian*) -- otrapersona (*Spanish, Spanish, Mexico*) - Ryo (DrRyo) (*Korean*) -- Mauzi (*German, Swedish*) +- otrapersona (*Spanish, Mexico, Spanish*) +- Frontier Translation Ltd. (frontier-translation) (*Chinese Simplified*) +- Mauzi (*Swedish, German*) +- Clopsy87 (*Italian*) - atarashiako (*Chinese Simplified*) - erictapen (*German*) +- zhen liao (az0189re) (*Chinese Simplified*) - 101010 (101010pl) (*Polish*) -- Jaz-Michael King (jazmichaelking) (*Welsh*) +- REMOVED_USER (*Norwegian*) - axi (*Finnish*) - silkevicious (*Italian*) - Floxu (fredrikdim1) (*Norwegian Nynorsk*) -- NadieAishi (*Spanish, Spanish, Mexico*) +- Nic Dafis (nicdafis) (*Welsh*) +- NadieAishi (*Spanish, Mexico, Spanish*) +- 戸渡生野 (aomyouza2543) (*Thai*) +- Tjipke van der Heide (vancha) (*Frisian*) +- Erik Mogensen (mogsie) (*Norwegian*) +- pomoch (*Chinese Traditional, Hong Kong*) +- Alexandre Brito (alexbrito) (*Portuguese, Brazilian*) - Bertil Hedkvist (Berrahed) (*Swedish*) - William(ѕ)ⁿ (wmlgr) (*Spanish*) -- Eshagh (eshagh79) (*Persian*) - LNDDYL (*Chinese Traditional*) +- tanketom (*Norwegian Nynorsk*) - norayr (*Armenian*) +- l3ycle (*German*) +- strubbl (*German*) - Satnam S Virdi (pika10singh) (*Punjabi*) - Tiago Epifânio (tfve) (*Portuguese*) - Mentor Gashi (mentorgashi.com) (*Albanian*) +- Sid (autinerd1) (*Dutch, German*) - carolinagiorno (*Portuguese, Brazilian*) +- Em_i (emiliencoss) (*French*) +- Liam O (liamoshan) (*Irish*) - Hayk Khachatryan (brutusromanus123) (*Armenian*) - Roby Thomas (roby.thomas) (*Malayalam*) +- ThonyVezbe (*Breton*) +- Percy (kecrily) (*Chinese Simplified*) - Bharat Kumar (Marwari) (*Hindi*) - Austra Muizniece (aus_m) (*Latvian*) -- ThonyVezbe (*Breton*) +- Urubu Lageano (urubulageano) (*Portuguese, Brazilian*) - Just Spanish (7_7) (*Spanish, Mexico*) - v4vachan (*Malayalam*) - bilfri (*Danish*) +- IamHappy (mrmx2013) (*Ukrainian*) - dkdarshan760 (*Sanskrit*) - Timur Seber (seber) (*Tatar*) - Slimane Selyan AMIRI (SelyanKab) (*Kabyle*) - VaiTon (*Italian*) -- Vik (ViktorOn) (*Danish, Russian*) - tykayn (*French*) -- GCardo (*Portuguese, Brazilian*) +- Abdulaziz Aljaber (kuwaitna) (*Arabic*) - taoxvx (*Danish*) -- Hrach Mkrtchyan (mhrach87) (*Armenian*) +- Hrach Mkrtchyan (hrachmk) (*Armenian*) - sabri (thetomatoisavegetable) (*Spanish, Spanish, Argentina*) -- Dewi (Unkorneg) (*French, Breton*) - CoelacanthusHex (*Chinese Simplified*) - Rhys Harrison (rhedders) (*Esperanto*) -- syncopams (*Chinese Simplified, Chinese Traditional, Chinese Traditional, Hong Kong*) +- syncopams (*Chinese Traditional, Hong Kong, Chinese Traditional, Chinese Simplified*) - SteinarK (*Norwegian Nynorsk*) +- REMOVED_USER (*Standard Moroccan Tamazight*) - Maxine B. Vågnes (vagnes) (*Norwegian, Norwegian Nynorsk*) -- Hakim Oubouali (zenata1) (*Standard Moroccan Tamazight*) +- Rikard Linde (rikardlinde) (*Swedish*) - ahangarha (*Persian*) - Lalo Tafolla (lalotafo) (*Spanish, Spanish, Mexico*) -- dashersyed (*Urdu (Pakistan)*) +- Larissa Cruz (larissacruz) (*Portuguese, Brazilian*) +- dashersyed (Urdu (Pakistan)) +- camerongreer21 (*English, United Kingdom*) +- REMOVED_USER (*Ukrainian*) - Conight Wang (xfddwhh) (*Chinese Simplified*) - liffon (*Swedish*) - Damjan Dimitrioski (gnud) (*Macedonian*) -- Rikard Linde (rikardlinde) (*Swedish*) - rondnunes (*Portuguese, Brazilian*) -- strubbl (*German*) - PPNplus (*Thai*) -- Frontier Translation Ltd. (frontier-translation) (*Chinese Simplified*) +- Steven Ritchie (Steaph38) (*Scottish Gaelic*) +- 游荡 (MamaShip) (*Chinese Simplified*) +- Edward Navarro (EdwardNavarro) (*Spanish*) - shioko (*Chinese Simplified*) +- gnu-ewm (*Polish*) - Kahina Mess (K_hina) (*Kabyle*) +- Hexandcube (hexandcube) (*Polish*) +- Scott Starkey (yekrats) (*Esperanto*) - ZiriSut (*Kabyle*) +- FreddyG (*Esperanto*) +- mynameismonkey (*Welsh*) - Groosha (groosha) (*Russian*) -- Hexandcube (hexandcube) (*Polish*) - Gwenn (Belvar) (*Breton*) -- 游荡 (MamaShip) (*Chinese Simplified*) - StanleyFrew (*French*) -- mynameismonkey (*Welsh*) -- Edward Navarro (EdwardNavarro) (*Spanish*) +- cathalgarvey (*Irish*) - Nikita Epifanov (Nikets) (*Russian*) +- REMOVED_USER (*Finnish*) - jaranta (*Finnish*) - Slobodan Simić (Слободан Симић) (slsimic) (*Serbian (Cyrillic)*) -- retiolus (*Catalan*) -- iVampireSP (*Chinese Simplified, Chinese Traditional*) +- iVampireSP (*Chinese Traditional, Chinese Simplified*) - Felicia Jongleur (midsommar) (*Swedish*) - Denys (dector) (*Ukrainian*) - Mo_der Steven (SakuraPuare) (*Chinese Simplified*) +- REMOVED_USER (*German*) +- Kishin Sagume (kishinsagi) (*Chinese Simplified*) +- bennepharaoh (*Chinese Simplified*) - Vanege (*Esperanto*) +- hibiya inemuri (hibiya) (*Korean*) - Jess Rafn (therealyez) (*Danish*) - Stasiek Michalski (hellcp) (*Polish*) - dxwc (*Bengali*) -- Filbert Salim (gamesbert6) (*Indonesian*) +- Heran Membingung (heranmembingung) (*Indonesian*) +- Parodper (*Galician*) +- rbnval (*Catalan*) - Liboide (*Spanish*) +- hemnaren (*Norwegian Nynorsk*) - jmontane (*Catalan*) +- Andy Kleinert (AndyKl) (*German*) - Chris Kay (chriskarasoulis) (*Greek*) +- CrowdinBRUH (*Vietnamese*) +- Rhoslyn Prys (Rhoslyn) (*Welsh*) +- abidin toumi (Zet24) (*Arabic*) - Johan Schiff (schyffel) (*Swedish*) - Rex_sa (rex07) (*Arabic*) +- amedcj (*Kurmanji (Kurdish)*) - Arunmozhi (tecoholic) (*Tamil*) - zer0-x (ZER0-X) (*Arabic*) -- kat (katktv) (*Russian, Ukrainian*) +- staticnoisexyz (*Czech*) - Lauren Liberda (selfisekai) (*Polish*) +- Michael Zeevi (maze88) (*Hebrew*) - oti4500 (*Hungarian, Ukrainian*) - Delta (Delta-Time) (*Japanese*) -- Michael Zeevi (maze88) (*Hebrew*) +- Marc Antoine Thevenet (MATsxm) (*French*) +- AlexKoala (alexkoala) (*Korean*) - SarfarazAhmed (*Urdu (Pakistan)*) +- Ahmad Dakhlallah (MIUIArabia) (*Arabic*) - Mats Gunnar Ahlqvist (goqbi) (*Swedish*) - diazepan (*Spanish, Spanish, Argentina*) +- Tiger:blank (tsagaanbar) (*Chinese Simplified*) +- REMOVED_USER (*Chinese Simplified*) - marzuquccen (*Kabyle*) - atriix (*Swedish*) +- Laur (melaur) (*Romanian*) - VictorCorreia (victorcorreia1984) (*Afrikaans*) - Remito (remitocat) (*Japanese*) -- AlexKoala (alexkoala) (*Korean*) - Juan José Salvador Piedra (JuanjoSalvador) (*Spanish*) -- BurekzFinezt (*Serbian (Cyrillic)*) +- REMOVED_USER (*Norwegian*) - 森の子リスのミーコの大冒険 (Phroneris) (*Japanese*) +- Gim_Garam (*Korean*) +- BurekzFinezt (*Serbian (Cyrillic)*) +- Pēteris Caune (cuu508) (*Latvian*) - asnomgtu (*Hungarian*) +- bendigeidfran (*Welsh*) - SHeija (*Finnish*) - Врабац (Slovorad) (*Serbian (Cyrillic)*) - Dženan (Dzenan) (*Swedish*) -- Jack R (isaac.97_WT) (*Spanish*) +- Gabriel Beecham (lancet) (*Irish*) - antonyho (*Chinese Traditional, Hong Kong*) -- FreddyG (*Esperanto*) -- andruhov (*Russian, Ukrainian*) +- Jack R (isaac.97_WT) (*Spanish*) +- Henrik Mattsson-Mårn (rchk) (*Swedish*) +- Oguzhan Aydin (aoguzhan) (*Turkish*) +- Soran730 (*Chinese Simplified*) +- andruhov (*Ukrainian, Russian*) +- 北䑓如法 (Nyoho) (*Japanese*) - phena109 (*Chinese Traditional, Hong Kong*) -- Aryamik Sharma (Aryamik) (*Swedish, Hindi*) +- Aryamik Sharma (Aryamik) (*Hindi, Swedish*) - Unmual (*Spanish*) +- Tobias Bannert (toba) (*German*) - Adrián Graña (alaris83) (*Spanish*) -- cruz2020 (*Portuguese*) - vpei (*Chinese Simplified*) +- cruz2020 (*Portuguese*) +- papapep (h9f2ycHh-ktOd6_Y) (*Catalan*) +- Roj (roj1512) (*Sorani (Kurdish), Kurmanji (Kurdish)*) - るいーね (ruine) (*Japanese*) +- aujawindar (*Norwegian Nynorsk*) +- irithys (*Chinese Simplified*) - Sam Tux (imahbub) (*Bengali*) - igordrozniak (*Polish*) +- Johannes Nilsson (nlssn) (*Swedish*) - Michał Sidor (michcioperz) (*Polish*) - Isaac Huang (caasih) (*Chinese Traditional*) - AW Unad (awcodify) (*Indonesian*) - 1Alino (*Slovak*) - Cutls (cutls) (*Japanese*) -- Goudarz Jafari (Goudarz) (*Persian*) -- Parodper (*Galician*) +- Goudarz Jafari (GoudarzJafari) (*Persian*) +- Daniel Strömholm (stromholm) (*Swedish*) - 1 (Ipsumry) (*Spanish*) - Falling Snowdin (tghgg) (*Vietnamese*) +- Paulino Michelazzo (pmichelazzo) (*Portuguese, Brazilian*) +- Y.Yamashiro (uist1idrju3i) (*Japanese*) - Rasmus Lindroth (RasmusLindroth) (*Swedish*) - Gianfranco Fronteddu (gianfro.gianfro) (*Sardinian*) - Andrea Lo Iacono (niels0n) (*Italian*) - fucsia (*Italian*) - Vedran Serbu (SerenoXGen) (*Croatian*) +- Raphael Das Gupta (das-g) (*Esperanto, German*) +- yanchan09 (*Estonian*) +- ainmeolai (*Irish*) +- REMOVED_USER (*Norwegian*) +- mian42 (*Bulgarian*) - Kinshuk Sunil (kinshuksunil) (*Hindi*) -- Ullas Joseph (ullasjoseph) (*Malayalam*) - al_._ (*German, Russian*) +- Ullas Joseph (ullasjoseph) (*Malayalam*) +- sanoth (*Swedish*) +- Aftab Alam (iaftabalam) (*Hindi*) +- frumble (*German*) +- juanda097 (juanda-097) (*Spanish*) - Matthías Páll Gissurarson (icetritlo) (*Icelandic*) -- Percy (kecrily) (*Chinese Simplified*) -- Yu-Pai Liu (tedliou) (*Chinese Traditional*) +- Russian Retro (retrograde) (*Russian*) - KcKcZi (*Chinese Simplified*) +- Yu-Pai Liu (tedliou) (*Chinese Traditional*) - Amarin Cemthong (acitmaster) (*Thai*) -- Johannes Nilsson (nlssn) (*Swedish*) -- juanda097 (juanda-097) (*Spanish*) +- Etinew (*Hebrew*) - xsml (*Chinese Simplified*) +- S.J. L. (samijuhanilii) (*Finnish*) - Anunnakey (*Macedonian*) - erikkemp (*Dutch*) +- Tsl (muun) (*Chinese Simplified*) +- Renato "Lond" Cerqueira (renatolond) (*Portuguese, Brazilian*) +- Úna-Minh Kavanagh (yunitex) (*Irish*) +- kongk (*Norwegian Nynorsk*) - erikstl (*Esperanto*) - twpenguin (*Chinese Traditional*) +- JeremyStarTM (*German*) - Po-chiang Chao (bobchao) (*Chinese Traditional*) - Marcus Myge (mygg-priv) (*Norwegian*) - Esther (esthermations) (*Portuguese*) +- Jiri Grönroos (spammemoreplease) (*Finnish*) - MadeInSteak (*Finnish*) +- witoharmuth (*Swedish*) +- MESHAL45 (*Arabic*) +- mcdutchie (*Dutch*) +- Michal Špondr (michalspondr) (*Czech*) - t_aus_m (*German*) -- serapolis (*Japanese, Chinese Simplified, Chinese Traditional, Chinese Traditional, Hong Kong*) +- kaki7777 (*Japanese, Chinese Traditional*) - Heimen Stoffels (Vistaus) (*Dutch*) +- serapolis (*Chinese Traditional, Hong Kong, Chinese Traditional, Japanese, Chinese Simplified*) - Rajarshi Guha (rajarshiguha) (*Bengali*) +- Amir Reza (ElAmir) (*Persian*) +- REMOVED_USER (*Norwegian*) +- MohammadSaleh Kamyab (mskf1383) (*Persian*) +- REMOVED_USER (*Romanian*) - Gopal Sharma (gopalvirat) (*Hindi*) +- Вероніка Някшу (pampushkaveronica) (*Russian, Romanian*) - Linnéa (lesbian_subnet) (*Swedish*) -- 北䑓如法 (Nyoho) (*Japanese*) -- abidin toumi (Zet24) (*Arabic*) -- Tofiq Abdula (Xwla) (*Sorani (Kurdish)*) +- Valentin (HDValentin) (*German*) +- dragnucs2 (*Arabic*) - Carlos Solís (csolisr) (*Esperanto*) -- Yamagishi Kazutoshi (ykzts) (*Japanese, Vietnamese, Icelandic, Sorani (Kurdish)*) +- Tofiq Abdula (Xwla) (*Sorani (Kurdish)*) +- halcek (*Slovak*) +- Tobias Kunze (rixxian) (*German*) - Parthan S Ramanujam (parthan) (*Tamil*) - Kasper Nymand (KasperNymand) (*Danish*) -- subram (*Turkish*) - TS (morte) (*Finnish*) -- SensDeViata (*Ukrainian*) +- REMOVED_USER (*German*) +- REMOVED_USER (*Basque*) +- subram (*Turkish*) +- Gudwin (*Spanish, Mexico, Spanish*) - Ptrcmd (ptrcmd) (*Chinese Traditional*) +- shmuelHal (*Hebrew*) +- SensDeViata (*Ukrainian*) - megaleo (*Portuguese, Brazilian*) +- Acursen (*German*) +- NurKai Kai (nurkaiyttv) (*German*) +- Guttorm (ghveem) (*Norwegian Nynorsk*) - SergioFMiranda (*Portuguese, Brazilian*) -- hiroTS (*Chinese Traditional*) +- Danni Lundgren (dannilundgren) (*Danish*) - Vivek K J (Vivekkj) (*Malayalam*) -- arielcostas3 (*Galician*) +- hiroTS (*Chinese Traditional*) +- teadesu (*Portuguese, Brazilian*) +- petartrajkov (*Macedonian*) +- Ariel Costas (arielcostas3) (*Galician*) +- Ch. (sftblw) (*Korean*) +- Rintan (*Japanese*) +- Jair Henrique (jairhenrique) (*Portuguese, Brazilian*) +- sorcun (*Turkish*) +- filippodb (*Italian*) - johne32rus23 (*Russian*) -- AzureNya (*Chinese Simplified*) - OctolinGamer (octolingamer) (*Portuguese, Brazilian*) -- filippodb (*Italian*) +- AzureNya (*Chinese Simplified*) - Ram varma (ram4varma) (*Tamil*) +- REMOVED_USER (Sorani (Kurdish)) +- REMOVED_USER (*Portuguese, Brazilian*) +- seanmhade (*Irish*) - sanser (*Russian*) -- Y.Yamashiro (uist1idrju3i) (*Japanese*) +- Vijay (vijayatmin) (*Tamil*) +- Anomalion (*German*) - Pukima (Pukimaa) (*German*) -- diorama (*Italian*) -- frumble (*German*) +- Curtis Lee (CansCurtis) (*Chinese Traditional*) +- โบโลน่าไวรัส (nullxyz_) (*Thai*) +- ふぁーらんど (farland1717) (*Japanese*) +- 3wen (*Breton*) +- rlafuente (*Portuguese*) +- Ильзира Рахматуллина (rahmatullinailzira53) (*Tatar*) +- Code Man (codemansrc) (*Russian*) +- Philip Gillißen (guerda) (*German*) - Daniel Dimitrov (daniel.dimitrov) (*Bulgarian*) +- Anton (atjn) (*Danish*) - kekkepikkuni (*Tamil*) - MODcraft (*Chinese Simplified*) - oorsutri (*Tamil*) +- wortfeld (*German*) - Neo_Chen (NeoChen1024) (*Chinese Traditional*) +- Stereopolex (*Polish*) +- NxOne14 (*Bulgarian*) +- Juan Ortiz (Kloido) (*Spanish, Catalan*) - Nithin V (Nithin896) (*Tamil*) +- strikeCunny2245 (*Icelandic*) - Miro Rauhala (mirorauhala) (*Finnish*) +- nicoduesing (duconi) (*German, Esperanto*) +- Gnonthgol (*Norwegian Nynorsk*) +- WKobes (*Dutch*) - Oymate (*Bengali*) +- mikwee (*Hebrew*) +- EzigboOmenana (*Igbo, Cornish*) +- yan Wato (janWato) (*Hindi*) +- Papuass (*Latvian*) +- Vincent Orback (vincentorback) (*Swedish*) +- chettoy (*Chinese Simplified*) +- 19 (nineteen) (*Chinese Simplified*) - ಚಿರಾಗ್ ನಟರಾಜ್ (chiraag-nataraj) (*Kannada*) +- Layik Hama (layik) (*Sorani (Kurdish)*) - Guillaume Turchini (orion78fr) (*French*) +- Andri Yngvason (andryng) (*Icelandic*) - Aswin C (officialcjunior) (*Malayalam*) -- Ganesh D (auntgd) (*Marathi*) - Yuval Nehemia (yuvalne) (*Hebrew*) - mawoka-myblock (mawoka) (*German*) -- dragnucs2 (*Arabic*) +- Ganesh D (auntgd) (*Marathi*) +- Lens0021 (lens0021) (*Korean*) +- An Gafraíoch (angafraioch) (*Irish*) +- Michael Smith (michaelshmitty) (*Dutch*) - Ryan Ho (koungho) (*Chinese Traditional*) -- Tejas Harad (h_tejas) (*Marathi*) +- tunisiano187 (*French*) +- Peter van Mever (SpacemanSpiff) (*Dutch*) - Pedro Henrique (exploronauta) (*Portuguese, Brazilian*) -- Amir Reza (ElAmir) (*Persian*) -- Tatsuto "Laminne" Yamamoto (laminne) (*Japanese*) +- REMOVED_USER (*Esperanto, Italian, Japanese*) +- Tejas Harad (h_tejas) (*Marathi*) +- Balázs Meskó (meskobalazs) (*Hungarian*) - Vasanthan (vasanthan) (*Tamil*) +- Tatsuto "Laminne" Yamamoto (laminne) (*Japanese*) +- slbtty (shenlebantongying) (*Chinese Simplified*) - 硫酸鶏 (acid_chicken) (*Japanese*) - programizer (*German*) +- guessimmaterialgrl (*Chinese Simplified*) - clarmin b8 (clarminb8) (*Sorani (Kurdish)*) +- Maria Riegler (riegler3m) (*German*) - manukp (*Malayalam*) -- psymyn (*Hebrew*) - earth dweller (sanethoughtyt) (*Marathi*) +- psymyn (*Hebrew*) +- Aaraon Thomas (aaraon) (*Portuguese, Brazilian*) +- Rafael Viana (rafacnec) (*Portuguese, Brazilian*) - Marek Ľach (marek-lach) (*Slovak*) - meijerivoi (toilet) (*Finnish*) - essaar (*Tamil*) -- Nemuj (Dentrado) (*Japanese, Esperanto*) - serubeena (*Swedish*) -- Rintan (*Japanese*) -- Karol Kosek (krkkPL) (*Polish*) +- RqndomHax (*French*) +- REMOVED_USER (*Polish*) +- ギャラ (gyara) (*Chinese Simplified, Japanese*) - Khó͘ Tiatlêng (khotiatleng) (*Chinese Traditional, Taigi*) -- valarivan (*Tamil*) -- Hernik (hernik27) (*Czech*) - revarioba (*Spanish*) - friedbeans (*Croatian*) +- An (AnTheMaker) (*German*) - kuchengrab (*German*) +- Hernik (hernik27) (*Czech*) +- valarivan (*Tamil*) +- אדם לוין (adamlevin) (*Hebrew*) +- Vít Horčička (legvita123) (*Czech*) - Abi Turi (abi123) (*Georgian*) +- Thomas Munkholt (munkholt) (*Danish*) +- pparescasellas (*Catalan*) - Hinaloe (hinaloe) (*Japanese*) -- Sebastián Andil (Selrond) (*Slovak*) - Ifnuth (*German*) -- Asbjørn Olling (a2) (*Danish*) +- Sebastián Andil (Selrond) (*Slovak*) +- boni777 (*Chinese Simplified*) - KEINOS (*Japanese*) -- Balázs Meskó (meskobalazs) (*Hungarian*) -- Artem Mikhalitsin (artemmikhalitsin) (*Russian*) -- Algustionesa Yoshi (algustionesa) (*Indonesian*) -- Bottle (suryasalem2010) (*Tamil*) +- Asbjørn Olling (a2) (*Danish*) +- REMOVED_USER (*Chinese Traditional, Hong Kong*) +- DarkShy Community (ponyfrost.mc) (*Russian*) +- Dennis Reimund (reimunddennis7) (*German*) +- jocafeli (*Spanish, Mexico*) - Wrya ali (John12) (*Sorani (Kurdish)*) +- Bottle (suryasalem2010) (*Tamil*) +- Algustionesa Yoshi (algustionesa) (*Indonesian*) - JzshAC (*Chinese Simplified*) +- Artem Mikhalitsin (artemmikhalitsin) (*Russian*) - siamano (*Thai, Esperanto*) -- gnu-ewm (*Polish*) -- Antillion (antillion99) (*Spanish*) +- KARARTI44 (kararti44) (*Turkish*) +- c0c (*Irish*) +- Stefano S. (Sting1_JP) (*Italian*) +- tommil (*Finnish*) +- Ignacio Lis (ilis) (*Galician*) - Steven Tappert (sammy8806) (*German*) -- Reg3xp (*Persian*) +- Antillion (antillion99) (*Spanish*) +- K.B.Dharun Krishna (kbdharun) (*Tamil*) - Wassim EL BOUHAMIDI (elbouhamidiw) (*Arabic*) +- Reg3xp (*Persian*) +- florentVgn (*French*) +- Matt (Exbu) (*Dutch*) - Maciej Błędkowski (mble) (*Polish*) - gowthamanb (*Tamil*) - hiphipvargas (*Portuguese*) -- tunisiano187 (*French*) +- GabuVictor (*Portuguese, Brazilian*) +- Pverte (*French*) +- REMOVED_USER (*Spanish*) +- Surindaku (*Chinese Simplified*) - Arttu Ylhävuori (arttu.ylhavuori) (*Finnish*) -- Ch. (sftblw) (*Korean*) -- eorn (*Breton*) +- Pabllo Soares (pabllosoarez) (*Portuguese, Brazilian*) - Jona (88wcJoWl) (*Spanish*) -- Mikkel B. Goldschmidt (mikkelbjoern) (*Danish*) -- Timo Tijhof (Krinkle) (*Dutch*) - Ka2n (kaanmetu) (*Turkish*) - tctovsli (*Norwegian Nynorsk*) -- mecqor labi (mecqorlabi) (*Persian*) +- Timo Tijhof (Krinkle) (*Dutch*) +- SamitiMed (samiti3d) (*Thai*) +- Mikkel B. Goldschmidt (mikkelbjoern) (*Danish*) - Odyssey346 (alexader612) (*Norwegian*) +- mecqor labi (mecqorlabi) (*Persian*) +- Cù Huy Phúc Khang (taamee) (*Vietnamese*) +- Oskari Lavinto (olavinto) (*Finnish*) +- Philippe Lemaire (philippe-lemaire) (*Esperanto*) - vjasiegd (*Polish*) -- Eban (ebanDev) (*French, Esperanto*) -- SamitiMed (samiti3d) (*Thai*) +- Eban (ebanDev) (*Esperanto, French*) - Nícolas Lavinicki (nclavinicki) (*Portuguese, Brazilian*) +- REMOVED_USER (*Portuguese, Brazilian*) - Rekan Adl (rekan-adl1) (*Sorani (Kurdish)*) -- Antara2Cinta (Se7enTime) (*Indonesian*) -- Yassine Aït-El-Mouden (yaitelmouden) (*Standard Moroccan Tamazight*) - VSx86 (*Russian*) - umelard (*Hebrew*) +- Antara2Cinta (Se7enTime) (*Indonesian*) +- Lucas_NL (*Dutch*) +- Yassine Aït-El-Mouden (yaitelmouden) (*Standard Moroccan Tamazight*) +- Mathieu Marquer (slasherfun) (*French*) +- Haerul Fuad (Dokuwiki) (*Indonesian*) - parnikkapore (*Thai*) -- Lagash (lagash) (*Esperanto*) +- Michelle M (MichelleMMM) (*Dutch*) +- malbona (*Esperanto*) - Sherwan Othman (sherwanothman11) (*Sorani (Kurdish)*) -- SKELET (*Danish*) -- Exbu (*Dutch*) +- Lagash (lagash) (*Esperanto*) - Chine Sebastien (chine.sebastien) (*French*) -- Fei Yang (Fei1Yang) (*Chinese Traditional*) +- bgme (*Chinese Simplified*) +- Rafael V. (Rafaeeel) (*Portuguese, Brazilian*) +- SKELET (*Danish*) - A A (sebastien.chine) (*French*) +- Project Z (projectz.1338) (*German*) +- Fei Yang (Fei1Yang) (*Chinese Traditional*) - Ğani (freegnu) (*Tatar*) -- enipra (*Armenian*) -- Renato "Lond" Cerqueira (renatolond) (*Portuguese, Brazilian*) - musix (*Persian*) -- ギャラ (gyara) (*Japanese, Chinese Simplified*) +- REMOVED_USER (*German*) - ALEM FARID (faridatcemlulaqbayli) (*Kabyle*) +- Jean-Pierre MÉRESSE (Jipem) (*French*) +- enipra (*Armenian*) +- Serhiy Dmytryshyn (dies) (*Ukrainian*) +- Eric Brulatout (ebrulato) (*Esperanto*) - Hougo (hougo) (*French*) -- Mordi Sacks (MordiSacks) (*Hebrew*) -- Trinsec (*Dutch*) -- Adrián Lattes (haztecaso) (*Spanish*) +- Sonstwer (*German*) +- Pedro Fernandes (djprmf) (*Portuguese*) +- REMOVED_USER (*Norwegian*) - Tigran's Tips (tigrank08) (*Armenian*) - 亜緯丹穂 (ayiniho) (*Japanese*) +- maisui (*Chinese Simplified*) +- Trinsec (*Dutch*) +- Adrián Lattes (haztecaso) (*Spanish*) +- webkinzfrog (*Polish*) - ybardapurkar (*Marathi*) +- Mordi Sacks (MordiSacks) (*Hebrew*) +- Manuel Tassi (Mannivu) (*Italian*) - Szabolcs Gál (galszabolcs810624) (*Hungarian*) -- Vladislav Săcrieriu (vladislavs14) (*Romanian*) +- rikrise (*Swedish*) +- when_hurts (*German*) +- Wojciech Bigosinski (wbigos2) (*Polish*) +- Vladislav S (vladislavs) (*Romanian*) +- mikslatvis (*Latvian*) +- MartinAlstad (*Norwegian*) - TracyJacks (*Chinese Simplified*) - rasheedgm (*Kannada*) -- danreznik (*Hebrew*) - Cirelli (cirelli94) (*Italian*) +- danreznik (*Hebrew*) +- iraline (*Portuguese, Brazilian*) +- Seán Mór (seanmor3) (*Irish*) +- vianaweb (*Portuguese, Brazilian*) - Siddharastro Doraku (sidharastro) (*Spanish, Mexico*) -- lexxai (*Ukrainian*) +- REMOVED_USER (*Spanish*) - omquylzu (*Latvian*) +- Arthegor (*French*) - Navjot Singh (nspeaks) (*Hindi*) - mkljczk (*Polish*) - Belkacem Mohammed (belkacem77) (*Kabyle*) +- Showfom (*Chinese Simplified*) +- xemyst (*Catalan*) +- lexxai (*Ukrainian*) - c6ristian (*German*) -- damascene (*Arabic*) +- svetlozaurus (*Bulgarian*) - Ozai (*German*) +- damascene (*Arabic*) +- Jan Ainali (Ainali) (*Swedish*) - Sahak Petrosyan (petrosyan) (*Armenian*) +- Metehan Özyürek (MetehanOzyurek) (*Turkish*) +- Сау Рэмсон (sawrams) (*Russian*) +- metehan-arslan (*Turkish*) - Viorel-Cătălin Răpițeanu (rapiteanu) (*Romanian*) -- Siddhartha Sarathi Basu (quinoa_biryani) (*Bengali*) +- Sébastien SERRE (sebastienserre) (*French*) +- Eugen Caruntu (eugencaruntu) (*Romanian*) +- Kevin Scannell (kscanne) (*Irish*) - Pachara Chantawong (pachara2202) (*Thai*) -- Skew (noan.perrot) (*French*) +- bensch.dev (*German*) +- LIZH (*French*) +- Siddhartha Sarathi Basu (quinoa_biryani) (*Bengali*) +- Overflow Cat (OverflowCat) (*Chinese Traditional, Chinese Simplified*) +- Stephan Voeth (svoeth) (*German*) - Zijian Zhao (jobs2512821228) (*Chinese Simplified*) -- Overflow Cat (OverflowCat) (*Chinese Simplified, Chinese Traditional*) +- bugboy-20 (*Esperanto, Italian*) +- SouthFox (*Chinese Simplified*) +- Noan (SkewRam) (*French*) - dbeaver (*German*) -- zordsdavini (*Lithuanian*) -- Guru Prasath Anandapadmanaban (guruprasath) (*Tamil*) - turtle836 (*German*) +- Guru Prasath Anandapadmanaban (guruprasath) (*Tamil*) +- zordsdavini (*Lithuanian*) +- Susanna Ånäs (susanna.anas) (*Finnish*) +- Alessandro (alephoto85) (*Italian*) - Marcepanek_ (thekingmarcepan) (*Polish*) -- Feruz Oripov (FeruzOripov) (*Russian*) +- Choi Younsoo (usagicore) (*Korean*) - Yann Aguettaz (yann-a) (*French*) +- zylosophe (*French*) +- Celso Fernandes (Celsof) (*Portuguese, Brazilian*) +- Feruz Oripov (FeruzOripov) (*Russian*) +- REMOVED_USER (*French*) +- Bui Huy Quang (bhuyquang1) (*Vietnamese*) +- bogomilshopov (*Bulgarian*) +- REMOVED_USER (*Burmese*) +- Kaede (kaedech) (*Japanese*) - Mick Onio (xgc.redes) (*Asturian*) - Malik Mann (dermalikmann) (*German*) - padulafacundo (*Spanish*) +- r3dsp1 (*Chinese Traditional, Hong Kong*) - dadosch (*German*) -- hg6 (*Hindi*) - Tianqi Zhang (tina.zhang040609) (*Chinese Simplified*) -- r3dsp1 (*Chinese Traditional, Hong Kong*) -- johannes hove-henriksen (J0hsHH) (*Norwegian*) +- HybridGlucose (*Chinese Traditional*) +- vmichalak (*French*) +- hg6 (*Hindi*) +- marivisales (*Portuguese, Brazilian*) - Orlando Murcio (Atos20) (*Spanish, Mexico*) -- cenegd (*Chinese Simplified*) +- maa123 (*Japanese*) +- Julian Doser (julian21) (*English, United Kingdom, German*) +- johannes hove-henriksen (J0hsHH) (*Norwegian*) +- Alexander Ivanov (Saiv46) (*Russian*) +- unstable.icu (*Chinese Simplified*) +- Padraic Calpin (padraic-padraic) (*Slovenian*) - Youngeon Lee (YoungeonLee) (*Korean*) +- LeJun (le-jun) (*French*) - shdy (*German*) -- Umi (mtrumi) (*Chinese Simplified, Chinese Traditional, Hong Kong*) -- Padraic Calpin (padraic-padraic) (*Slovenian*) -- Ильзира Рахматуллина (rahmatullinailzira53) (*Tatar*) +- REMOVED_USER (*French*) +- Yonjae Lee (yonjlee) (*Korean*) +- cenegd (*Chinese Simplified*) - piupiupiudiu (*Chinese Simplified*) -- Pixelcode (realpixelcode) (*German*) -- Dennis Reimund (reimunddennis7) (*German*) +- Umi (mtrumi) (*Chinese Traditional, Hong Kong, Chinese Simplified*) - Yogesh K S (yogi) (*Kannada*) +- Ulong32 (*Japanese*) - Adithya K (adithyak04) (*Malayalam*) - DAI JIE (daijie) (*Chinese Simplified*) +- Mihael Budeč (milli.pretili) (*Croatian*) - Hugh Liu (youloveonlymeh) (*Chinese Simplified*) -- Rakino (rakino) (*Chinese Simplified*) - ZQYD (*Chinese Simplified*) - X.M (kimonoki) (*Chinese Simplified*) -- boni777 (*Chinese Simplified*) +- Rakino (rakino) (*Chinese Simplified*) +- paziy Georgi (paziygeorgi4) (*Dutch*) +- Komeil Parseh (mmdbalkhi) (*Persian*) - Jothipazhani Nagarajan (jothipazhani.n) (*Tamil*) -- Miquel Sabaté Solà (mssola) (*Catalan*) +- tikky9 (*Portuguese, Brazilian*) +- horsm (*Finnish*) +- BenJule (*German*) - Stanisław Jelnicki (JelNiSlaw) (*Polish*) +- Yananas (wangyanyan.hy) (*Chinese Simplified*) +- Vivamus (elaaksu) (*Turkish*) +- ihealyou (*Italian*) - AmazighNM (*Kabyle*) +- Miquel Sabaté Solà (mssola) (*Catalan*) +- residuum (*German*) +- nua_kr (*Korean*) +- Andrea Mazzilli (andreamazzilli) (*Italian*) +- Paula SIMON (EncoreEutIlFalluQueJeLeSusse) (*French*) +- hallomaurits (*Dutch*) +- Erfan Kheyrollahi Qaroğlu (ekm507) (*Persian*) +- REMOVED_USER (*Galician, Spanish*) - alnd hezh (alndhezh) (*Sorani (Kurdish)*) -- CloudSet (*Chinese Simplified*) - Clash Clans (KURD12345) (*Sorani (Kurdish)*) -- Metehan Özyürek (MetehanOzyurek) (*Turkish*) -- Paula SIMON (EncoreEutIlFalluQueJeLeSusse) (*French*) +- ruok (*Chinese Simplified*) +- Frederik-FJ (*German*) +- CloudSet (*Chinese Simplified*) - Solid Rhino (SolidRhino) (*Dutch*) -- nua_kr (*Korean*) -- hallomaurits (*Dutch*) -- 林水溶 (shuiRong) (*Chinese Simplified*) -- rikrise (*Swedish*) -- Takeshi Umeda (noellabo) (*Japanese*) +- hussama (*Portuguese, Brazilian*) +- jazzynico (*French*) - k_taka (peaceroad) (*Japanese*) +- 林水溶 (shuiRong) (*Chinese Simplified*) +- Peter Lutz (theellutzo) (*German*) - Sébastien Feugère (smonff) (*French*) +- AnalGoddess770 (*Hebrew*) +- Sven Goller (svengoller) (*German*) +- Ahmet (ahmetlii) (*Turkish*) +- hosted22 (*German*) - Hallo Abdullah (hallo_hamza12) (*Sorani (Kurdish)*) -- hussama (*Portuguese, Brazilian*) -- EzigboOmenana (*Cornish*) +- Karam Hamada (TheKaram) (*Arabic*) +- Takeshi Umeda (noellabo) (*Japanese*) +- SnDer (*Dutch*) - Robert Yano (throwcalmbobaway) (*Spanish, Mexico*) -- Yasin İsa YILDIRIM (redsfyre) (*Turkish*) -- PifyZ (*French*) -- Tagada (Tagadda) (*French*) -- eichkat3r (*German*) -- Ashok314 (ashok314) (*Hindi*) +- Gustav Lindqvist (Reedyn) (*Swedish*) +- Dagur Ammendrup (dagurp) (*Icelandic*) +- shafouz (*Portuguese, Brazilian*) +- Miguel Branco (mglbranco) (*Galician*) +- Sergey Panteleev (saundefined) (*Russian*) +- Tom_ (*Czech*) - Zlr- (cZeler) (*French*) -- SnDer (*Dutch*) -- OminousCry (*Russian*) +- Ashok314 (ashok314) (*Hindi*) +- PifyZ (*French*) +- Zeyi Fan (fanzeyi) (*Chinese Simplified*) +- OminousCry (*Russian, Ukrainian*) - Adam Sapiński (Adamos9898) (*Polish*) -- Tom_ (*Czech*) -- shafouz (*Portuguese, Brazilian*) -- Shrinivasan T (tshrinivasan) (*Tamil*) -- Kk (kishorkumara3) (*Kannada*) -- Swati Sani (swatisani) (*Urdu (Pakistan)*) -- papayaisnotafood (*Chinese Traditional*) -- さっかりんにーさん (saccharin23) (*Japanese*) +- eichkat3r (*German*) +- Yasin İsa YILDIRIM (redsfyre) (*Turkish*) +- Tagada (Tagadda) (*French*) +- gasrios (*Portuguese, Brazilian*) +- 夜楓Yoka (Yoka2627) (*Chinese Simplified*) +- AniCommieDDR (*Russian*) +- Nathaël Noguès (NatNgs) (*French*) - Daniel M. (daniconil) (*Catalan*) - César Daniel Cavanzo Quintero (LeinadCQ) (*Esperanto*) -- Nathaël Noguès (NatNgs) (*French*) -- 夜楓Yoka (Yoka2627) (*Chinese Simplified*) +- Noam Tamim (noamtm) (*Hebrew*) +- papayaisnotafood (*Chinese Traditional*) +- さっかりんにーさん (saccharin23) (*Japanese*) +- Marcin Wolski (martinwolski) (*Polish*) +- REMOVED_USER (*Chinese Simplified*) +- Kk (kishorkumara3) (*Kannada*) +- Shrinivasan T (tshrinivasan) (*Tamil*) +- REMOVED_USER (Urdu (Pakistan)) +- Kakarico Bra (kakarico20) (*Portuguese, Brazilian*) +- Swati Sani (swatisani) (*Urdu (Pakistan)*) +- 快乐的老鼠宝宝 (LaoShuBaby) (*Chinese Simplified, Chinese Traditional*) - Mt Front (mtfront) (*Chinese Simplified*) -- Artem (Artem4ik) (*Russian*) -- Robin van der Vliet (RobinvanderVliet) (*Esperanto*) -- Tradjincal (tradjincal) (*French*) - SusVersiva (*Catalan*) +- REMOVED_USER (*Portuguese, Brazilian*) +- Avinash Mg (hatman290) (*Malayalam*) +- kruijs (*Dutch*) +- Artem (Artem4ik) (*Russian*) - Zinkokooo (*Basque*) -- Marvin (magicmarvman) (*German*) +- 劉昌賢 (twcctz500) (*Chinese Traditional*) - Vikatakavi (*Kannada*) +- Tradjincal (tradjincal) (*French*) +- Robin van der Vliet (RobinvanderVliet) (*Esperanto*) +- Marvin (magicmarvman) (*German*) - pullopen (*Chinese Simplified*) -- sergioaraujo1 (*Portuguese, Brazilian*) -- prabhjot (*Hindi*) -- CyberAmoeba (pseudoobscura) (*Chinese Simplified*) -- mmokhi (*Persian*) +- Tealk (*German*) +- tibequadorian (*German*) +- Henk Bulder (henkbulder) (*Dutch*) +- Edison Lee (edisonlee55) (*Chinese Traditional*) +- mpdude (*German*) +- Rijk van Geijtenbeek (rvangeijtenbeek) (*Dutch*) - Entelekheia-ousia (*Chinese Simplified*) +- REMOVED_USER (*Spanish*) +- sergioaraujo1 (*Portuguese, Brazilian*) - Livingston Samuel (livingston) (*Tamil*) +- mmokhi (*Persian*) - tsundoker (*Malayalam*) -- skaaarrr (*German*) -- Pierre Morvan (Iriep) (*Breton*) +- CyberAmoeba (pseudoobscura) (*Chinese Simplified*) +- prabhjot (*Hindi*) +- Ikka Putri (ikka240290) (*Indonesian, Danish, English, United Kingdom*) - Paz Galindo (paz.almendra.g) (*Spanish*) -- fedot (*Russian*) -- mkljczk (mykylyjczyk) (*Polish*) - Ricardo Colin (rysard) (*Spanish*) -- Philipp Fischbeck (PFischbeck) (*German*) +- Pierre Morvan (Iriep) (*Breton*) - oscfd (*Spanish*) +- Thies Mueller (thies00) (*German*) +- Lyra (teromene) (*French*) +- Kedr (lava20121991) (*Esperanto*) +- mkljczk (mykylyjczyk) (*Polish*) +- fedot (*Russian*) +- Philipp Fischbeck (PFischbeck) (*German*) +- Hasan Berkay Çağır (berkaycagir) (*Turkish*) +- Silvestri Nicola (nick99silver) (*Italian*) +- skaaarrr (*German*) +- Mo Rijndael (mo_rijndael) (*Russian*) +- tsesunnaallun (orezraey) (*Portuguese, Brazilian*) +- Lukas Fülling (lfuelling) (*German*) +- Algo (algovigura) (*Indonesian*) +- REMOVED_USER (*Spanish*) +- setthemfree (*Ukrainian*) +- i fly (ifly3years) (*Chinese Simplified*) +- ralozkolya (*Georgian*) - Zoé Bőle (zoe1337) (*German*) +- Ville Rantanen (vrntnn) (*Finnish*) - GaggiX (*Italian*) - JackXu (Merman-Jack) (*Chinese Simplified*) -- Lukas Fülling (lfuelling) (*German*) -- ralozkolya (*Georgian*) -- Jason Gibson (barberpike606) (*Slovenian, Chinese Simplified*) -- Dremski (*Bulgarian*) -- Kaede (kaedech) (*Japanese*) -- Aymeric (AymBroussier) (*French*) -- mashirozx (*Chinese Simplified*) -- María José Vera (mjverap) (*Spanish*) -- asala4544 (*Basque*) -- ronee (*Kurmanji (Kurdish)*) -- qwerty287 (*German*) -- pezcurrel (*Italian*) -- Anoop (anoopp) (*Malayalam*) +- ceonia (*Chinese Traditional, Hong Kong*) +- Emirhan Yavuz (takomlii) (*Turkish*) +- teezeh (*German*) +- MevLyshkin (Leinnan) (*Polish*) - Apple (blackteaovo) (*Chinese Simplified*) -- Lilian Nabati (Lilounab49) (*French*) -- ru_mactunnag (*Scottish Gaelic*) -- Nocta (*French*) +- qwerty287 (*German*) - Tangcuyu (*Chinese Simplified*) +- Nocta (*French*) +- ru_mactunnag (*Scottish Gaelic*) +- Lilian Nabati (Lilounab49) (*French*) +- lokalisoija (*Finnish*) - Dennis Reimund (reimund_dennis) (*German*) -- Albatroz Jeremias (albjeremias) (*Portuguese*) -- Xurxo Guerra (xguerrap) (*Galician*) +- ronee (*Kurmanji (Kurdish)*) +- EricVogt_ (*Spanish*) +- yu miao (metaxx.dev) (*Chinese Simplified*) +- Anoop (anoopp) (*Malayalam*) - Samir Tighzert (samir_t7) (*Kabyle*) -- lokalisoija (*Finnish*) +- sn02 (*German*) +- Yui Karasuma (yui87) (*Japanese*) +- asala4544 (*Basque*) +- Thibaut Rousseau (thiht44) (*French*) +- Jason Gibson (barberpike606) (*Slovenian, Chinese Simplified*) +- Sugar NO (g1024116707) (*Chinese Simplified*) +- Aymeric (AymBroussier) (*French*) +- pezcurrel (*Italian*) +- Xurxo Guerra (xguerrap) (*Galician*) +- nicosomb (*French*) +- Albatroz Jeremias (albjeremias) (*Portuguese*) +- María José Vera (mjverap) (*Spanish*) +- mashirozx (*Chinese Simplified*) - codl (*French*) -- thisdudeisvegan (braydofficial) (*German*) -- tamaina (*Japanese*) +- Doug (douglasalvespe) (*Portuguese, Brazilian*) - Matias Lavik (matiaslavik) (*Norwegian Nynorsk*) -- Aman Alam (aalam) (*Punjabi*) +- random_person (*Spanish*) +- whoeta (wh0eta) (*Russian*) +- xpac1985 (xpac) (*German*) +- thisdudeisvegan (braydofficial) (*German*) +- Fleva (*Sardinian*) +- Anonymous (Anonymous666) (*Russian*) +- Mohammad Adnan Mahmood (adnanmig) (*Arabic*) +- ÀŘǾŚ PÀŚĦÀÍ (arospashai) (*Sorani (Kurdish)*) +- mikel (mikelalas) (*Spanish*) +- Trond Boksasp (boksasp) (*Norwegian*) +- asretro (*Chinese Traditional, Hong Kong*) - Holger Huo (holgerhuo) (*Chinese Simplified*) -- Amith Raj Shetty (amithraj1989) (*Kannada*) +- Aman Alam (aalam) (*Punjabi*) +- smedvedev (*Russian*) +- Jay Lonnquist (crowkeep) (*Japanese*) - mimikun (*Japanese*) +- Mohd Bilal (mdb571) (*Malayalam*) +- veer66 (*Thai*) +- OpenAlgeria (*Arabic*) +- Rave (nayumi-464812844) (*Vietnamese*) +- ReavedNetwork (*German*) +- Michael (Discostu36) (*German*) +- tamaina (*Japanese*) +- sk22 (*German*) - Ragnars Eggerts (rmegg1933) (*Latvian*) -- ÀŘǾŚ PÀŚĦÀÍ (arospashai) (*Sorani (Kurdish)*) -- smedvedev (*Russian*) - Sais Lakshmanan (Saislakshmanan) (*Tamil*) -- Mohammad Adnan Mahmood (adnanmig) (*Arabic*) -- OpenAlgeria (*Arabic*) -- Trond Boksasp (boksasp) (*Norwegian*) -- Doug (douglasalvespe) (*Portuguese, Brazilian*) -- Mohd Bilal (mdb571) (*Malayalam*) -- Fleva (*Sardinian*) -- xpac1985 (xpac) (*German*) -- mikel (mikelalas) (*Spanish*) -- random_person (*Spanish*) -- asretro (*Chinese Traditional, Hong Kong*) -- Arĝentakato (argxentakato) (*Japanese*) -- Nithya Mary (nithyamary25) (*Tamil*) -- Azad ahmad (dashty) (*Sorani (Kurdish)*) +- Amith Raj Shetty (amithraj1989) (*Kannada*) - Bartek Fijałkowski (brateq) (*Polish*) +- Asbeltrion (*Spanish*) +- Michael Horstmann (mhrstmnn) (*German*) +- Joffrey Abeilard (Abeilard14) (*French*) +- capiscuas (*Spanish*) +- djoerd (*Dutch*) +- REMOVED_USER (*Spanish*) +- NeverMine17 (*Russian*) +- songxianj (songxian_jiang) (*Chinese Simplified*) +- Ács Zoltán (zoli111) (*Hungarian*) +- haaninjo (*Swedish*) +- REMOVED_USER (*Esperanto*) +- Philip Molares (DerMolly) (*German*) +- ChalkPE (amato0617) (*Korean*) - ebrezhoneg (*Breton*) +- 디떱 (diddub) (*Korean*) +- Hans (hansj) (*German*) +- Nithya Mary (nithyamary25) (*Tamil*) +- kavitha129 (*Tamil*) +- waweic (*German*) +- Aries (orlea) (*Japanese*) +- おさ (osapon) (*Japanese*) +- Abijeet Patro (Abijeet) (*Basque*) +- centumix (*Japanese*) +- Martin Müller (muellermartin) (*German*) +- tateisu (*Japanese*) +- Arĝentakato (argxentakato) (*Japanese*) +- Benjamin Cobb (benjamincobb) (*German*) +- deanerschnitzel (*German*) +- Jill H. (kokakiwi) (*French*) - maksutheam (*Finnish*) +- d0p1 (d0p1s4m4) (*French*) - majorblazr (*Danish*) -- Jill H. (kokakiwi) (*French*) - Patrice Boivin (patriceboivin58) (*French*) -- centumix (*Japanese*) - 江尚寒 (jiangshanghan) (*Chinese Simplified*) -- hud5634j (*Spanish*) -- おさ (osapon) (*Japanese*) -- Jiniux (*Italian*) -- Hannah (Aniqueper1) (*Chinese Simplified*) -- Ni Futchi (futchitwo) (*Japanese*) -- dobrado (*Portuguese, Brazilian*) -- dcapillae (*Spanish*) +- HSD Channel (kvdbve34) (*Russian*) +- alwyn joe (iomedivh200) (*Chinese Simplified*) +- ZHY (sheepzh) (*Chinese Simplified*) +- Bei Li (libei) (*Chinese Simplified*) +- Aluo (Aluo_rbszd) (*Chinese Simplified*) +- clarkzjw (*Chinese Simplified*) +- Noah Luppe (noahlup) (*German*) +- araghunde (*Galician*) +- BratishkaErik (*Russian*) +- Bunny9568 (*Chinese Simplified*) +- SamOak (*Portuguese, Brazilian*) - Ranj A Abdulqadir (RanjAhmed) (*Sorani (Kurdish)*) -- Kurdish Translator (Kurdish.boy) (*Sorani (Kurdish)*) - Amir Kurdo (kuraking202) (*Sorani (Kurdish)*) -- umonaca (*Chinese Simplified*) -- Jari Ronkainen (ronchaine) (*Finnish*) -- djoerd (*Dutch*) -- Savarín Electrográfico Marmota Intergalactica (herrero.maty) (*Spanish*) - 于晚霞 (xissshawww) (*Chinese Simplified*) -- tateisu (*Japanese*) -- NeverMine17 (*Russian*) +- Fyuoxyjidyho Moiodyyiodyhi (fyuodchiodmoiidiiduh86) (*Chinese Simplified*) +- RPD0911 (*Hungarian*) +- dcapillae (*Spanish*) +- dobrado (*Portuguese, Brazilian*) +- Hannah (Aniqueper1) (*Chinese Simplified*) +- Azad ahmad (dashty) (*Sorani (Kurdish)*) +- Uri Chachick (urich.404) (*Hebrew*) +- Bnoru (*Portuguese, Brazilian*) +- Jiniux (*Italian*) +- REMOVED_USER (*German*) +- Salh_haji6 (Sorani (Kurdish)) +- Kurdish Translator (*Kurdish.boy) (Sorani (Kurdish)*) +- Beagle (beagleworks) (*Japanese*) +- hud5634j (*Spanish*) +- Kisaragi Hiu (flyingfeather1501) (*Chinese Traditional*) +- Dominik Ziegler (dodomedia) (*German*) - soheilkhanalipur (*Persian*) -- SamOak (*Portuguese, Brazilian*) -- kavitha129 (*Tamil*) -- Salh_haji6 (*Sorani (Kurdish)*) - Brodi (brodi1) (*Dutch*) -- capiscuas (*Spanish*) -- HSD Channel (kvdbve34) (*Russian*) -- Abijeet Patro (Abijeet) (*Basque*) -- Ács Zoltán (zoli111) (*Hungarian*) -- Benjamin Cobb (benjamincobb) (*German*) -- waweic (*German*) -- Aries (orlea) (*Japanese*) +- Savarín Electrográfico Marmota Intergalactica (herrero.maty) (*Spanish*) +- Ni Futchi (futchitwo) (*Japanese*) +- Zois Lee (gcnwm) (*Chinese Simplified*) +- Arnold Marko (atomicmind) (*Slovenian*) +- scholzco (*German*) +- Jari Ronkainen (ronchaine) (*Finnish*) +- umonaca (*Chinese Simplified*) diff --git a/CHANGELOG.md b/CHANGELOG.md index 72f62a1dc..4392cc658 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,7 +3,12 @@ Changelog All notable changes to this project will be documented in this file. -## [Unreleased] +## [4.0.1] - 2022-11-14 +### Fixed + +- Fix nodes order being sometimes mangled when rewriting emoji ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/20677)) + +## [4.0.0] - 2022-11-14 Some of the features in this release have been funded through the [NGI0 Discovery](https://nlnet.nl/discovery) Fund, a fund established by [NLnet](https://nlnet.nl/) with financial support from the European Commission's [Next Generation Internet](https://ngi.eu/) programme, under the aegis of DG Communications Networks, Content and Technology under grant agreement No 825322. @@ -58,12 +63,13 @@ Some of the features in this release have been funded through the [NGI0 Discover - Add reputation and followers score boost to SQL-only account search ([Gargron](https://github.com/mastodon/mastodon/pull/19251)) - Add Scots, Balaibalan, Láadan, Lingua Franca Nova, Lojban, Toki Pona to languages list ([VyrCossont](https://github.com/mastodon/mastodon/pull/20168)) - Set autocomplete hints for e-mail, password and OTP fields ([rcombs](https://github.com/mastodon/mastodon/pull/19833), [offbyone](https://github.com/mastodon/mastodon/pull/19946), [ClearlyClaire](https://github.com/mastodon/mastodon/pull/20071)) +- Add support for DigitalOcean Spaces in setup wizard ([v-aisac](https://github.com/mastodon/mastodon/pull/20573)) ### Changed - **Change brand color and logotypes** ([Gargron](https://github.com/mastodon/mastodon/pull/18592), [Gargron](https://github.com/mastodon/mastodon/pull/18639), [Gargron](https://github.com/mastodon/mastodon/pull/18691), [ClearlyClaire](https://github.com/mastodon/mastodon/pull/18634), [Gargron](https://github.com/mastodon/mastodon/pull/19254), [mayaeh](https://github.com/mastodon/mastodon/pull/18710)) - **Change post editing to be enabled in web UI** ([Gargron](https://github.com/mastodon/mastodon/pull/19103)) -- **Change web UI to work for logged-out users** ([Gargron](https://github.com/mastodon/mastodon/pull/18961), [Gargron](https://github.com/mastodon/mastodon/pull/19250), [Gargron](https://github.com/mastodon/mastodon/pull/19294), [Gargron](https://github.com/mastodon/mastodon/pull/19306), [Gargron](https://github.com/mastodon/mastodon/pull/19315), [ykzts](https://github.com/mastodon/mastodon/pull/19322), [Gargron](https://github.com/mastodon/mastodon/pull/19412), [ClearlyClaire](https://github.com/mastodon/mastodon/pull/19437), [ClearlyClaire](https://github.com/mastodon/mastodon/pull/19415), [Gargron](https://github.com/mastodon/mastodon/pull/19348), [Gargron](https://github.com/mastodon/mastodon/pull/19295), [Gargron](https://github.com/mastodon/mastodon/pull/19422), [ClearlyClaire](https://github.com/mastodon/mastodon/pull/19414), [Gargron](https://github.com/mastodon/mastodon/pull/19319), [Gargron](https://github.com/mastodon/mastodon/pull/19345), [Gargron](https://github.com/mastodon/mastodon/pull/19310), [Gargron](https://github.com/mastodon/mastodon/pull/19301), [Gargron](https://github.com/mastodon/mastodon/pull/19423), [ykzts](https://github.com/mastodon/mastodon/pull/19471), [ykzts](https://github.com/mastodon/mastodon/pull/19333), [ykzts](https://github.com/mastodon/mastodon/pull/19337), [ykzts](https://github.com/mastodon/mastodon/pull/19272), [ykzts](https://github.com/mastodon/mastodon/pull/19468), [Gargron](https://github.com/mastodon/mastodon/pull/19466), [Gargron](https://github.com/mastodon/mastodon/pull/19457), [Gargron](https://github.com/mastodon/mastodon/pull/19426), [Gargron](https://github.com/mastodon/mastodon/pull/19427), [Gargron](https://github.com/mastodon/mastodon/pull/19421), [Gargron](https://github.com/mastodon/mastodon/pull/19417), [Gargron](https://github.com/mastodon/mastodon/pull/19413), [Gargron](https://github.com/mastodon/mastodon/pull/19397), [Gargron](https://github.com/mastodon/mastodon/pull/19387), [Gargron](https://github.com/mastodon/mastodon/pull/19396), [Gargron](https://github.com/mastodon/mastodon/pull/19385), [ykzts](https://github.com/mastodon/mastodon/pull/19334), [ykzts](https://github.com/mastodon/mastodon/pull/19329), [Gargron](https://github.com/mastodon/mastodon/pull/19324), [Gargron](https://github.com/mastodon/mastodon/pull/19318), [Gargron](https://github.com/mastodon/mastodon/pull/19316), [Gargron](https://github.com/mastodon/mastodon/pull/19263), [trwnh](https://github.com/mastodon/mastodon/pull/19305), [ykzts](https://github.com/mastodon/mastodon/pull/19273), [Gargron](https://github.com/mastodon/mastodon/pull/19801), [Gargron](https://github.com/mastodon/mastodon/pull/19790), [ClearlyClaire](https://github.com/mastodon/mastodon/pull/19773), [Gargron](https://github.com/mastodon/mastodon/pull/19798), [ClearlyClaire](https://github.com/mastodon/mastodon/pull/19724), [Gargron](https://github.com/mastodon/mastodon/pull/19709), [Gargron](https://github.com/mastodon/mastodon/pull/19514), [Gargron](https://github.com/mastodon/mastodon/pull/19562), [ClearlyClaire](https://github.com/mastodon/mastodon/pull/19981), [ClearlyClaire](https://github.com/mastodon/mastodon/pull/19978), [ClearlyClaire](https://github.com/mastodon/mastodon/pull/20148), [Gargron](https://github.com/mastodon/mastodon/pull/20302)) +- **Change web UI to work for logged-out users** ([Gargron](https://github.com/mastodon/mastodon/pull/18961), [Gargron](https://github.com/mastodon/mastodon/pull/19250), [Gargron](https://github.com/mastodon/mastodon/pull/19294), [Gargron](https://github.com/mastodon/mastodon/pull/19306), [Gargron](https://github.com/mastodon/mastodon/pull/19315), [ykzts](https://github.com/mastodon/mastodon/pull/19322), [Gargron](https://github.com/mastodon/mastodon/pull/19412), [ClearlyClaire](https://github.com/mastodon/mastodon/pull/19437), [ClearlyClaire](https://github.com/mastodon/mastodon/pull/19415), [Gargron](https://github.com/mastodon/mastodon/pull/19348), [Gargron](https://github.com/mastodon/mastodon/pull/19295), [Gargron](https://github.com/mastodon/mastodon/pull/19422), [ClearlyClaire](https://github.com/mastodon/mastodon/pull/19414), [Gargron](https://github.com/mastodon/mastodon/pull/19319), [Gargron](https://github.com/mastodon/mastodon/pull/19345), [Gargron](https://github.com/mastodon/mastodon/pull/19310), [Gargron](https://github.com/mastodon/mastodon/pull/19301), [Gargron](https://github.com/mastodon/mastodon/pull/19423), [ykzts](https://github.com/mastodon/mastodon/pull/19471), [ykzts](https://github.com/mastodon/mastodon/pull/19333), [ykzts](https://github.com/mastodon/mastodon/pull/19337), [ykzts](https://github.com/mastodon/mastodon/pull/19272), [ykzts](https://github.com/mastodon/mastodon/pull/19468), [Gargron](https://github.com/mastodon/mastodon/pull/19466), [Gargron](https://github.com/mastodon/mastodon/pull/19457), [Gargron](https://github.com/mastodon/mastodon/pull/19426), [Gargron](https://github.com/mastodon/mastodon/pull/19427), [Gargron](https://github.com/mastodon/mastodon/pull/19421), [Gargron](https://github.com/mastodon/mastodon/pull/19417), [Gargron](https://github.com/mastodon/mastodon/pull/19413), [Gargron](https://github.com/mastodon/mastodon/pull/19397), [Gargron](https://github.com/mastodon/mastodon/pull/19387), [Gargron](https://github.com/mastodon/mastodon/pull/19396), [Gargron](https://github.com/mastodon/mastodon/pull/19385), [ykzts](https://github.com/mastodon/mastodon/pull/19334), [ykzts](https://github.com/mastodon/mastodon/pull/19329), [Gargron](https://github.com/mastodon/mastodon/pull/19324), [Gargron](https://github.com/mastodon/mastodon/pull/19318), [Gargron](https://github.com/mastodon/mastodon/pull/19316), [Gargron](https://github.com/mastodon/mastodon/pull/19263), [trwnh](https://github.com/mastodon/mastodon/pull/19305), [ykzts](https://github.com/mastodon/mastodon/pull/19273), [Gargron](https://github.com/mastodon/mastodon/pull/19801), [Gargron](https://github.com/mastodon/mastodon/pull/19790), [ClearlyClaire](https://github.com/mastodon/mastodon/pull/19773), [Gargron](https://github.com/mastodon/mastodon/pull/19798), [ClearlyClaire](https://github.com/mastodon/mastodon/pull/19724), [Gargron](https://github.com/mastodon/mastodon/pull/19709), [Gargron](https://github.com/mastodon/mastodon/pull/19514), [Gargron](https://github.com/mastodon/mastodon/pull/19562), [ClearlyClaire](https://github.com/mastodon/mastodon/pull/19981), [ClearlyClaire](https://github.com/mastodon/mastodon/pull/19978), [ClearlyClaire](https://github.com/mastodon/mastodon/pull/20148), [Gargron](https://github.com/mastodon/mastodon/pull/20302), [cutls](https://github.com/mastodon/mastodon/pull/20400)) - The web app can now be accessed without being logged in - No more `/web` prefix on web app paths - Profiles, posts, and other public pages now use the same interface for logged in and logged out users @@ -79,7 +85,7 @@ Some of the features in this release have been funded through the [NGI0 Discover - Change label of publish button to be "Publish" again in web UI ([Gargron](https://github.com/mastodon/mastodon/pull/18583)) - Change language to be carried over on reply in web UI ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/18557)) - Change "Unfollow" to "Cancel follow request" when request still pending in web UI ([prplecake](https://github.com/mastodon/mastodon/pull/19363)) -- **Change post filtering system** ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/18058), [ClearlyClaire](https://github.com/mastodon/mastodon/pull/19050), [ClearlyClaire](https://github.com/mastodon/mastodon/pull/18894), [ClearlyClaire](https://github.com/mastodon/mastodon/pull/19051), [noellabo](https://github.com/mastodon/mastodon/pull/18923), [ClearlyClaire](https://github.com/mastodon/mastodon/pull/18956), [ClearlyClaire](https://github.com/mastodon/mastodon/pull/18744), [ClearlyClaire](https://github.com/mastodon/mastodon/pull/19878)) +- **Change post filtering system** ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/18058), [ClearlyClaire](https://github.com/mastodon/mastodon/pull/19050), [ClearlyClaire](https://github.com/mastodon/mastodon/pull/18894), [ClearlyClaire](https://github.com/mastodon/mastodon/pull/19051), [noellabo](https://github.com/mastodon/mastodon/pull/18923), [ClearlyClaire](https://github.com/mastodon/mastodon/pull/18956), [ClearlyClaire](https://github.com/mastodon/mastodon/pull/18744), [ClearlyClaire](https://github.com/mastodon/mastodon/pull/19878), [ClearlyClaire](https://github.com/mastodon/mastodon/pull/20567)) - Filtered keywords and phrases can now be grouped into named categories - Filtered posts show which exact filter was hit - Individual posts can be added to a filter @@ -105,6 +111,8 @@ Some of the features in this release have been funded through the [NGI0 Discover - Change incoming activity processing to happen in `ingress` queue ([Gargron](https://github.com/mastodon/mastodon/pull/20264)) - Change notifications to not link show preview cards in web UI ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/20335)) - Change amount of replies returned for logged out users in REST API ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/20355)) +- Change in-app links to keep you in-app in web UI ([trwnh](https://github.com/mastodon/mastodon/pull/20540), [Gargron](https://github.com/mastodon/mastodon/pull/20628)) +- Change table header to be sticky in admin UI ([sk22](https://github.com/mastodon/mastodon/pull/20442)) ### Removed @@ -117,6 +125,9 @@ Some of the features in this release have been funded through the [NGI0 Discover ### Fixed +- Fix rules with same priority being sorted non-deterministically ([Gargron](https://github.com/mastodon/mastodon/pull/20623)) +- Fix error when invalid domain name is submitted ([Gargron](https://github.com/mastodon/mastodon/pull/19474)) +- Fix icons having an image role ([Gargron](https://github.com/mastodon/mastodon/pull/20600)) - Fix connections to IPv6-only servers ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/20108)) - Fix unnecessary service worker registration and preloading when logged out in web UI ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/20341)) - Fix unnecessary and slow regex construction ([raggi](https://github.com/mastodon/mastodon/pull/20215)) @@ -185,10 +196,15 @@ Some of the features in this release have been funded through the [NGI0 Discover - Fix `CDN_HOST` not being used in some asset URLs ([tribela](https://github.com/mastodon/mastodon/pull/18662)) - Fix `CAS_DISPLAY_NAME`, `SAML_DISPLAY_NAME` and `OIDC_DISPLAY_NAME` being ignored ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/18568)) - Fix various typos in comments throughout the codebase ([luzpaz](https://github.com/mastodon/mastodon/pull/18604)) +- Fix CSV import error when rows include unicode characters ([HamptonMakes](https://github.com/mastodon/mastodon/pull/20592)) ### Security - Fix being able to spoof link verification ([Gargron](https://github.com/mastodon/mastodon/pull/20217)) +- Fix emoji substitution not applying only to text nodes in backend code ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/20641)) +- Fix emoji substitution not applying only to text nodes in web UI ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/20640)) +- Fix rate limiting for paths with formats ([Gargron](https://github.com/mastodon/mastodon/pull/20675)) +- Fix out-of-bound reads in blurhash transcoder ([delroth](https://github.com/mastodon/mastodon/pull/20388)) ## [3.5.3] - 2022-05-26 ### Added diff --git a/Gemfile b/Gemfile index c19a1b69b..1bff6cc7d 100644 --- a/Gemfile +++ b/Gemfile @@ -92,7 +92,7 @@ gem 'tty-prompt', '~> 0.23', require: false gem 'twitter-text', '~> 3.1.0' gem 'tzinfo-data', '~> 1.2022' gem 'webpacker', '~> 5.4' -gem 'webpush', git: 'https://github.com/ClearlyClaire/webpush.git', ref: 'f14a4d52e201128b1b00245d11b6de80d6cfdcd9' +gem 'webpush', github: 'ClearlyClaire/webpush', ref: 'f14a4d52e201128b1b00245d11b6de80d6cfdcd9' gem 'webauthn', '~> 2.5' gem 'json-ld' @@ -122,6 +122,7 @@ group :test do gem 'simplecov', '~> 0.21', require: false gem 'webmock', '~> 3.18' gem 'rspec_junit_formatter', '~> 0.6' + gem 'rack-test', '~> 2.0' end group :development do @@ -152,7 +153,6 @@ end gem 'concurrent-ruby', require: false gem 'connection_pool', require: false - gem 'xorcist', '~> 1.1' gem 'hcaptcha', '~> 7.1' diff --git a/Gemfile.lock b/Gemfile.lock index bfe69991d..ddd89fa16 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -818,6 +818,7 @@ DEPENDENCIES rack (~> 2.2.4) rack-attack (~> 6.6) rack-cors (~> 1.1) + rack-test (~> 2.0) rails (~> 6.1.7) rails-controller-testing (~> 1.0) rails-i18n (~> 6.0) diff --git a/app/controllers/api/base_controller.rb b/app/controllers/api/base_controller.rb index 3f3e1ca7b..665425f29 100644 --- a/app/controllers/api/base_controller.rb +++ b/app/controllers/api/base_controller.rb @@ -57,7 +57,7 @@ class Api::BaseController < ApplicationController render json: { error: I18n.t('errors.429') }, status: 429 end - rescue_from ActionController::ParameterMissing do |e| + rescue_from ActionController::ParameterMissing, Mastodon::InvalidParameterError do |e| render json: { error: e.to_s }, status: 400 end diff --git a/app/controllers/api/v2/admin/accounts_controller.rb b/app/controllers/api/v2/admin/accounts_controller.rb index bcc1a0733..b25831aa0 100644 --- a/app/controllers/api/v2/admin/accounts_controller.rb +++ b/app/controllers/api/v2/admin/accounts_controller.rb @@ -33,7 +33,7 @@ class Api::V2::Admin::AccountsController < Api::V1::Admin::AccountsController end def filter_params - params.permit(*FILTER_PARAMS) + params.permit(*FILTER_PARAMS, role_ids: []) end def pagination_params(core_params) diff --git a/app/controllers/api/v1/filters/keywords_controller.rb b/app/controllers/api/v2/filters/keywords_controller.rb index d3718a137..c63e1d986 100644 --- a/app/controllers/api/v1/filters/keywords_controller.rb +++ b/app/controllers/api/v2/filters/keywords_controller.rb @@ -1,6 +1,6 @@ # frozen_string_literal: true -class Api::V1::Filters::KeywordsController < Api::BaseController +class Api::V2::Filters::KeywordsController < Api::BaseController before_action -> { doorkeeper_authorize! :read, :'read:filters' }, only: [:index, :show] before_action -> { doorkeeper_authorize! :write, :'write:filters' }, except: [:index, :show] before_action :require_user! diff --git a/app/controllers/api/v1/filters/statuses_controller.rb b/app/controllers/api/v2/filters/statuses_controller.rb index b6bed306f..755c14cff 100644 --- a/app/controllers/api/v1/filters/statuses_controller.rb +++ b/app/controllers/api/v2/filters/statuses_controller.rb @@ -1,6 +1,6 @@ # frozen_string_literal: true -class Api::V1::Filters::StatusesController < Api::BaseController +class Api::V2::Filters::StatusesController < Api::BaseController before_action -> { doorkeeper_authorize! :read, :'read:filters' }, only: [:index, :show] before_action -> { doorkeeper_authorize! :write, :'write:filters' }, except: [:index, :show] before_action :require_user! diff --git a/app/javascript/flavours/glitch/actions/filters.js b/app/javascript/flavours/glitch/actions/filters.js index 76326802e..e9c609fc8 100644 --- a/app/javascript/flavours/glitch/actions/filters.js +++ b/app/javascript/flavours/glitch/actions/filters.js @@ -43,7 +43,7 @@ export const fetchFilters = () => (dispatch, getState) => { export const createFilterStatus = (params, onSuccess, onFail) => (dispatch, getState) => { dispatch(createFilterStatusRequest()); - api(getState).post(`/api/v1/filters/${params.filter_id}/statuses`, params).then(response => { + api(getState).post(`/api/v2/filters/${params.filter_id}/statuses`, params).then(response => { dispatch(createFilterStatusSuccess(response.data)); if (onSuccess) onSuccess(); }).catch(error => { diff --git a/app/javascript/flavours/glitch/features/account/components/header.js b/app/javascript/flavours/glitch/features/account/components/header.js index 93831b3e7..47c074ec3 100644 --- a/app/javascript/flavours/glitch/features/account/components/header.js +++ b/app/javascript/flavours/glitch/features/account/components/header.js @@ -317,8 +317,6 @@ class Header extends ImmutablePureComponent { <Avatar account={suspended || hidden ? undefined : account} size={90} /> </a> - <div className='spacer' /> - {!suspended && ( <div className='account__header__tabs__buttons'> {!hidden && ( diff --git a/app/javascript/flavours/glitch/features/emoji/emoji.js b/app/javascript/flavours/glitch/features/emoji/emoji.js index c4e2c26f2..50a399114 100644 --- a/app/javascript/flavours/glitch/features/emoji/emoji.js +++ b/app/javascript/flavours/glitch/features/emoji/emoji.js @@ -19,15 +19,26 @@ const emojiFilename = (filename) => { return borderedEmoji.includes(filename) ? (filename + '_border') : filename; }; -const emojify = (str, customEmojis = {}) => { - const tagCharsWithoutEmojis = '<&'; - const tagCharsWithEmojis = Object.keys(customEmojis).length ? '<&:' : '<&'; - let rtn = '', tagChars = tagCharsWithEmojis, invisible = 0; +const domParser = new DOMParser(); + +const emojifyTextNode = (node, customEmojis) => { + let str = node.textContent; + + const fragment = new DocumentFragment(); + for (;;) { - let match, i = 0, tag; - while (i < str.length && (tag = tagChars.indexOf(str[i])) === -1 && (invisible || useSystemEmojiFont || !(match = trie.search(str.slice(i))))) { - i += str.codePointAt(i) < 65536 ? 1 : 2; + let match, i = 0; + + if (customEmojis === null) { + while (i < str.length && (useSystemEmojiFont || !(match = trie.search(str.slice(i))))) { + i += str.codePointAt(i) < 65536 ? 1 : 2; + } + } else { + while (i < str.length && str[i] !== ':' && (useSystemEmojiFont || !(match = trie.search(str.slice(i))))) { + i += str.codePointAt(i) < 65536 ? 1 : 2; + } } + let rend, replacement = ''; if (i === str.length) { break; @@ -35,8 +46,6 @@ const emojify = (str, customEmojis = {}) => { if (!(() => { rend = str.indexOf(':', i + 1) + 1; if (!rend) return false; // no pair of ':' - const lt = str.indexOf('<', i + 1); - if (!(lt === -1 || lt >= rend)) return false; // tag appeared before closing ':' const shortname = str.slice(i, rend); // now got a replacee as ':shortname:' // if you want additional emoji handler, add statements below which set replacement and return true. @@ -47,29 +56,6 @@ const emojify = (str, customEmojis = {}) => { } return false; })()) rend = ++i; - } else if (tag >= 0) { // <, & - rend = str.indexOf('>;'[tag], i + 1) + 1; - if (!rend) { - break; - } - if (tag === 0) { - if (invisible) { - if (str[i + 1] === '/') { // closing tag - if (!--invisible) { - tagChars = tagCharsWithEmojis; - } - } else if (str[rend - 2] !== '/') { // opening tag - invisible++; - } - } else { - if (str.startsWith('<span class="invisible">', i)) { - // avoid emojifying on invisible text - invisible = 1; - tagChars = tagCharsWithoutEmojis; - } - } - } - i = rend; } else if (!useSystemEmojiFont) { // matched to unicode emoji const { filename, shortCode } = unicodeMapping[match]; const title = shortCode ? `:${shortCode}:` : ''; @@ -80,10 +66,43 @@ const emojify = (str, customEmojis = {}) => { rend += 1; } } - rtn += str.slice(0, i) + replacement; + + fragment.append(document.createTextNode(str.slice(0, i))); + if (replacement) { + fragment.append(domParser.parseFromString(replacement, 'text/html').documentElement.getElementsByTagName('img')[0]); + } + node.textContent = str.slice(0, i); str = str.slice(rend); } - return rtn + str; + + fragment.append(document.createTextNode(str)); + node.parentElement.replaceChild(fragment, node); +}; + +const emojifyNode = (node, customEmojis) => { + for (const child of node.childNodes) { + switch(child.nodeType) { + case Node.TEXT_NODE: + emojifyTextNode(child, customEmojis); + break; + case Node.ELEMENT_NODE: + if (!child.classList.contains('invisible')) + emojifyNode(child, customEmojis); + break; + } + } +}; + +const emojify = (str, customEmojis = {}) => { + const wrapper = document.createElement('div'); + wrapper.innerHTML = str; + + if (!Object.keys(customEmojis).length) + customEmojis = null; + + emojifyNode(wrapper, customEmojis); + + return wrapper.innerHTML; }; export default emojify; diff --git a/app/javascript/flavours/glitch/reducers/compose.js b/app/javascript/flavours/glitch/reducers/compose.js index 18e437bbc..1edc70add 100644 --- a/app/javascript/flavours/glitch/reducers/compose.js +++ b/app/javascript/flavours/glitch/reducers/compose.js @@ -547,7 +547,7 @@ export default function compose(state = initialState, action) { .setIn(['media_modal', 'dirty'], false) .update('media_attachments', list => list.map(item => { if (item.get('id') === action.media.id) { - return fromJS(action.media); + return fromJS(action.media).set('unattached', true); } return item; diff --git a/app/javascript/flavours/glitch/styles/components/accounts.scss b/app/javascript/flavours/glitch/styles/components/accounts.scss index 00519adf1..ac2d642a8 100644 --- a/app/javascript/flavours/glitch/styles/components/accounts.scss +++ b/app/javascript/flavours/glitch/styles/components/accounts.scss @@ -535,8 +535,11 @@ &__tabs { display: flex; align-items: flex-start; + justify-content: space-between; padding: 7px 10px; margin-top: -55px; + gap: 8px; + overflow: hidden; &__buttons { display: flex; @@ -545,6 +548,15 @@ padding-top: 55px; overflow: hidden; + .button { + flex-shrink: 1; + white-space: nowrap; + + @media screen and (max-width: $no-gap-breakpoint) { + min-width: 0; + } + } + .icon-button { border: 1px solid lighten($ui-base-color, 12%); border-radius: 4px; diff --git a/app/javascript/flavours/glitch/styles/tables.scss b/app/javascript/flavours/glitch/styles/tables.scss index 919255790..14daf591e 100644 --- a/app/javascript/flavours/glitch/styles/tables.scss +++ b/app/javascript/flavours/glitch/styles/tables.scss @@ -178,6 +178,9 @@ a.table-action-link { } &__toolbar { + position: sticky; + top: 0; + z-index: 1; border: 1px solid darken($ui-base-color, 8%); background: $ui-base-color; border-radius: 4px 0 0; diff --git a/app/javascript/mastodon/actions/filters.js b/app/javascript/mastodon/actions/filters.js index 76326802e..e9c609fc8 100644 --- a/app/javascript/mastodon/actions/filters.js +++ b/app/javascript/mastodon/actions/filters.js @@ -43,7 +43,7 @@ export const fetchFilters = () => (dispatch, getState) => { export const createFilterStatus = (params, onSuccess, onFail) => (dispatch, getState) => { dispatch(createFilterStatusRequest()); - api(getState).post(`/api/v1/filters/${params.filter_id}/statuses`, params).then(response => { + api(getState).post(`/api/v2/filters/${params.filter_id}/statuses`, params).then(response => { dispatch(createFilterStatusSuccess(response.data)); if (onSuccess) onSuccess(); }).catch(error => { diff --git a/app/javascript/mastodon/components/account.js b/app/javascript/mastodon/components/account.js index 51d2b8ba2..7aebb124c 100644 --- a/app/javascript/mastodon/components/account.js +++ b/app/javascript/mastodon/components/account.js @@ -3,13 +3,13 @@ import ImmutablePropTypes from 'react-immutable-proptypes'; import PropTypes from 'prop-types'; import Avatar from './avatar'; import DisplayName from './display_name'; -import Permalink from './permalink'; import IconButton from './icon_button'; import { defineMessages, injectIntl } from 'react-intl'; import ImmutablePureComponent from 'react-immutable-pure-component'; import { me } from '../initial_state'; import RelativeTimestamp from './relative_timestamp'; import Skeleton from 'mastodon/components/skeleton'; +import { Link } from 'react-router-dom'; const messages = defineMessages({ follow: { id: 'account.follow', defaultMessage: 'Follow' }, @@ -140,11 +140,11 @@ class Account extends ImmutablePureComponent { return ( <div className='account'> <div className='account__wrapper'> - <Permalink key={account.get('id')} className='account__display-name' title={account.get('acct')} href={account.get('url')} to={`/@${account.get('acct')}`}> + <Link key={account.get('id')} className='account__display-name' title={account.get('acct')} to={`/@${account.get('acct')}`}> <div className='account__avatar-wrapper'><Avatar account={account} size={size} /></div> {mute_expires_at} <DisplayName account={account} /> - </Permalink> + </Link> <div className='account__relationship'> {buttons} diff --git a/app/javascript/mastodon/components/admin/Trends.js b/app/javascript/mastodon/components/admin/Trends.js index 635bdf37d..9530c2a5b 100644 --- a/app/javascript/mastodon/components/admin/Trends.js +++ b/app/javascript/mastodon/components/admin/Trends.js @@ -50,7 +50,7 @@ export default class Trends extends React.PureComponent { <Hashtag key={hashtag.name} name={hashtag.name} - href={`/admin/tags/${hashtag.id}`} + to={`/admin/tags/${hashtag.id}`} people={hashtag.history[0].accounts * 1 + hashtag.history[1].accounts * 1} uses={hashtag.history[0].uses * 1 + hashtag.history[1].uses * 1} history={hashtag.history.reverse().map(day => day.uses)} diff --git a/app/javascript/mastodon/components/hashtag.js b/app/javascript/mastodon/components/hashtag.js index 75220211e..e516fc086 100644 --- a/app/javascript/mastodon/components/hashtag.js +++ b/app/javascript/mastodon/components/hashtag.js @@ -4,7 +4,7 @@ import { Sparklines, SparklinesCurve } from 'react-sparklines'; import { FormattedMessage } from 'react-intl'; import PropTypes from 'prop-types'; import ImmutablePropTypes from 'react-immutable-proptypes'; -import Permalink from './permalink'; +import { Link } from 'react-router-dom'; import ShortNumber from 'mastodon/components/short_number'; import Skeleton from 'mastodon/components/skeleton'; import classNames from 'classnames'; @@ -53,7 +53,6 @@ export const accountsCountRenderer = (displayNumber, pluralReady) => ( export const ImmutableHashtag = ({ hashtag }) => ( <Hashtag name={hashtag.get('name')} - href={hashtag.get('url')} to={`/tags/${hashtag.get('name')}`} people={hashtag.getIn(['history', 0, 'accounts']) * 1 + hashtag.getIn(['history', 1, 'accounts']) * 1} history={hashtag.get('history').reverse().map((day) => day.get('uses')).toArray()} @@ -64,12 +63,12 @@ ImmutableHashtag.propTypes = { hashtag: ImmutablePropTypes.map.isRequired, }; -const Hashtag = ({ name, href, to, people, uses, history, className, description, withGraph }) => ( +const Hashtag = ({ name, to, people, uses, history, className, description, withGraph }) => ( <div className={classNames('trends__item', className)}> <div className='trends__item__name'> - <Permalink href={href} to={to}> + <Link to={to}> {name ? <React.Fragment>#<span>{name}</span></React.Fragment> : <Skeleton width={50} />} - </Permalink> + </Link> {description ? ( <span>{description}</span> @@ -98,7 +97,6 @@ const Hashtag = ({ name, href, to, people, uses, history, className, description Hashtag.propTypes = { name: PropTypes.string, - href: PropTypes.string, to: PropTypes.string, people: PropTypes.number, description: PropTypes.node, diff --git a/app/javascript/mastodon/components/icon.js b/app/javascript/mastodon/components/icon.js index d8a17722f..d3d7c591d 100644 --- a/app/javascript/mastodon/components/icon.js +++ b/app/javascript/mastodon/components/icon.js @@ -14,7 +14,7 @@ export default class Icon extends React.PureComponent { const { id, className, fixedWidth, ...other } = this.props; return ( - <i role='img' className={classNames('fa', `fa-${id}`, className, { 'fa-fw': fixedWidth })} {...other} /> + <i className={classNames('fa', `fa-${id}`, className, { 'fa-fw': fixedWidth })} {...other} /> ); } diff --git a/app/javascript/mastodon/components/permalink.js b/app/javascript/mastodon/components/permalink.js deleted file mode 100644 index b369e9812..000000000 --- a/app/javascript/mastodon/components/permalink.js +++ /dev/null @@ -1,40 +0,0 @@ -import React from 'react'; -import PropTypes from 'prop-types'; - -export default class Permalink extends React.PureComponent { - - static contextTypes = { - router: PropTypes.object, - }; - - static propTypes = { - className: PropTypes.string, - href: PropTypes.string.isRequired, - to: PropTypes.string.isRequired, - children: PropTypes.node, - onInterceptClick: PropTypes.func, - }; - - handleClick = e => { - if (this.props.onInterceptClick && this.props.onInterceptClick()) { - e.preventDefault(); - return; - } - - if (this.context.router && e.button === 0 && !(e.ctrlKey || e.metaKey)) { - e.preventDefault(); - this.context.router.history.push(this.props.to); - } - } - - render () { - const { href, children, className, onInterceptClick, ...other } = this.props; - - return ( - <a target='_blank' href={href} onClick={this.handleClick} {...other} className={`permalink${className ? ' ' + className : ''}`}> - {children} - </a> - ); - } - -} diff --git a/app/javascript/mastodon/components/status.js b/app/javascript/mastodon/components/status.js index d1235550f..a1384ba58 100644 --- a/app/javascript/mastodon/components/status.js +++ b/app/javascript/mastodon/components/status.js @@ -378,7 +378,7 @@ class Status extends ImmutablePureComponent { prepend = ( <div className='status__prepend'> <div className='status__prepend-icon-wrapper'><Icon id='retweet' className='status__prepend-icon' fixedWidth /></div> - <FormattedMessage id='status.reblogged_by' defaultMessage='{name} boosted' values={{ name: <a onClick={this.handlePrependAccountClick} data-id={status.getIn(['account', 'id'])} href={status.getIn(['account', 'url'])} className='status__display-name muted'><bdi><strong dangerouslySetInnerHTML={display_name_html} /></bdi></a> }} /> + <FormattedMessage id='status.reblogged_by' defaultMessage='{name} boosted' values={{ name: <a onClick={this.handlePrependAccountClick} data-id={status.getIn(['account', 'id'])} href={`/@${status.getIn(['account', 'acct'])}`} className='status__display-name muted'><bdi><strong dangerouslySetInnerHTML={display_name_html} /></bdi></a> }} /> </div> ); @@ -392,7 +392,7 @@ class Status extends ImmutablePureComponent { prepend = ( <div className='status__prepend'> <div className='status__prepend-icon-wrapper'><Icon id='reply' className='status__prepend-icon' fixedWidth /></div> - <FormattedMessage id='status.replied_to' defaultMessage='Replied to {name}' values={{ name: <a onClick={this.handlePrependAccountClick} data-id={status.getIn(['account', 'id'])} href={status.getIn(['account', 'url'])} className='status__display-name muted'><bdi><strong dangerouslySetInnerHTML={display_name_html} /></bdi></a> }} /> + <FormattedMessage id='status.replied_to' defaultMessage='Replied to {name}' values={{ name: <a onClick={this.handlePrependAccountClick} data-id={status.getIn(['account', 'id'])} href={`/@${status.getIn(['account', 'acct'])}`} className='status__display-name muted'><bdi><strong dangerouslySetInnerHTML={display_name_html} /></bdi></a> }} /> </div> ); } @@ -511,12 +511,12 @@ class Status extends ImmutablePureComponent { <div className={classNames('status', `status-${status.get('visibility')}`, { 'status-reply': !!status.get('in_reply_to_id'), muted: this.props.muted })} data-id={status.get('id')}> <div className='status__info'> - <a onClick={this.handleClick} href={status.get('url')} className='status__relative-time' target='_blank' rel='noopener noreferrer'> + <a onClick={this.handleClick} href={`/@${status.getIn(['account', 'acct'])}\/${status.get('id')}`} className='status__relative-time' target='_blank' rel='noopener noreferrer'> <span className='status__visibility-icon'><Icon id={visibilityIcon.icon} title={visibilityIcon.text} /></span> <RelativeTimestamp timestamp={status.get('created_at')} />{status.get('edited_at') && <abbr title={intl.formatMessage(messages.edited, { date: intl.formatDate(status.get('edited_at'), { hour12: false, year: 'numeric', month: 'short', day: '2-digit', hour: '2-digit', minute: '2-digit' }) })}> *</abbr>} </a> - <a onClick={this.handleAccountClick} href={status.getIn(['account', 'url'])} title={status.getIn(['account', 'acct'])} className='status__display-name' target='_blank' rel='noopener noreferrer'> + <a onClick={this.handleAccountClick} href={`/@${status.getIn(['account', 'acct'])}`} title={status.getIn(['account', 'acct'])} className='status__display-name' target='_blank' rel='noopener noreferrer'> <div className='status__avatar'> {statusAvatar} </div> diff --git a/app/javascript/mastodon/components/status_content.js b/app/javascript/mastodon/components/status_content.js index 139e8ed16..fbc66eabf 100644 --- a/app/javascript/mastodon/components/status_content.js +++ b/app/javascript/mastodon/components/status_content.js @@ -2,13 +2,13 @@ import React from 'react'; import ImmutablePropTypes from 'react-immutable-proptypes'; import PropTypes from 'prop-types'; import { FormattedMessage, injectIntl } from 'react-intl'; -import Permalink from './permalink'; +import { Link } from 'react-router-dom'; import classnames from 'classnames'; import PollContainer from 'mastodon/containers/poll_container'; import Icon from 'mastodon/components/icon'; import { autoPlayGif, languages as preloadedLanguages, translationEnabled } from 'mastodon/initial_state'; -const MAX_HEIGHT = 642; // 20px * 32 (+ 2px padding at the top) +const MAX_HEIGHT = 706; // 22px * 32 (+ 2px padding at the top) class TranslateButton extends React.PureComponent { @@ -77,38 +77,45 @@ class StatusContent extends React.PureComponent { return; } + const { status, onCollapsedToggle } = this.props; const links = node.querySelectorAll('a'); + let link, mention; + for (var i = 0; i < links.length; ++i) { - let link = links[i]; + link = links[i]; + if (link.classList.contains('status-link')) { continue; } + link.classList.add('status-link'); - let mention = this.props.status.get('mentions').find(item => link.href === item.get('url')); + mention = this.props.status.get('mentions').find(item => link.href === item.get('url')); if (mention) { link.addEventListener('click', this.onMentionClick.bind(this, mention), false); link.setAttribute('title', mention.get('acct')); + link.setAttribute('href', `/@${mention.get('acct')}`); } else if (link.textContent[0] === '#' || (link.previousSibling && link.previousSibling.textContent && link.previousSibling.textContent[link.previousSibling.textContent.length - 1] === '#')) { link.addEventListener('click', this.onHashtagClick.bind(this, link.text), false); + link.setAttribute('href', `/tags/${link.text.slice(1)}`); } else { link.setAttribute('title', link.href); link.classList.add('unhandled-link'); } } - if (this.props.status.get('collapsed', null) === null) { - let collapsed = - this.props.collapsable - && this.props.onClick - && node.clientHeight > MAX_HEIGHT - && this.props.status.get('spoiler_text').length === 0; + if (status.get('collapsed', null) === null && onCollapsedToggle) { + const { collapsable, onClick } = this.props; - if(this.props.onCollapsedToggle) this.props.onCollapsedToggle(collapsed); + const collapsed = + collapsable + && onClick + && node.clientHeight > MAX_HEIGHT + && status.get('spoiler_text').length === 0; - this.props.status.set('collapsed', collapsed); + onCollapsedToggle(collapsed); } } @@ -242,9 +249,9 @@ class StatusContent extends React.PureComponent { let mentionsPlaceholder = ''; const mentionLinks = status.get('mentions').map(item => ( - <Permalink to={`/@${item.get('acct')}`} href={item.get('url')} key={item.get('id')} className='mention'> + <Link to={`/@${item.get('acct')}`} key={item.get('id')} className='mention'> @<span>{item.get('username')}</span> - </Permalink> + </Link> )).reduce((aggregate, item) => [...aggregate, item, ' '], []); const toggleText = hidden ? <FormattedMessage id='status.show_more' defaultMessage='Show more' /> : <FormattedMessage id='status.show_less' defaultMessage='Show less' />; diff --git a/app/javascript/mastodon/features/account/components/featured_tags.js b/app/javascript/mastodon/features/account/components/featured_tags.js index 8194c063a..24a3f2171 100644 --- a/app/javascript/mastodon/features/account/components/featured_tags.js +++ b/app/javascript/mastodon/features/account/components/featured_tags.js @@ -39,7 +39,6 @@ class FeaturedTags extends ImmutablePureComponent { <Hashtag key={featuredTag.get('name')} name={featuredTag.get('name')} - href={featuredTag.get('url')} to={`/@${account.get('acct')}/tagged/${featuredTag.get('name')}`} uses={featuredTag.get('statuses_count') * 1} withGraph={false} diff --git a/app/javascript/mastodon/features/account/components/header.js b/app/javascript/mastodon/features/account/components/header.js index c38eea55b..1825e0de6 100644 --- a/app/javascript/mastodon/features/account/components/header.js +++ b/app/javascript/mastodon/features/account/components/header.js @@ -314,8 +314,6 @@ class Header extends ImmutablePureComponent { <Avatar account={suspended || hidden ? undefined : account} size={90} /> </a> - <div className='spacer' /> - {!suspended && ( <div className='account__header__tabs__buttons'> {!hidden && ( diff --git a/app/javascript/mastodon/features/account_gallery/components/media_item.js b/app/javascript/mastodon/features/account_gallery/components/media_item.js index ba7ec46a3..3190caeb4 100644 --- a/app/javascript/mastodon/features/account_gallery/components/media_item.js +++ b/app/javascript/mastodon/features/account_gallery/components/media_item.js @@ -129,7 +129,7 @@ export default class MediaItem extends ImmutablePureComponent { return ( <div className='account-gallery__item' style={{ width, height }}> - <a className='media-gallery__item-thumbnail' href={status.get('url')} onClick={this.handleClick} title={title} target='_blank' rel='noopener noreferrer'> + <a className='media-gallery__item-thumbnail' href={`/@${status.getIn(['account', 'acct'])}\/${status.get('id')}`} onClick={this.handleClick} title={title} target='_blank' rel='noopener noreferrer'> <Blurhash hash={attachment.get('blurhash')} className={classNames('media-gallery__preview', { 'media-gallery__preview--hidden': visible && loaded })} diff --git a/app/javascript/mastodon/features/account_timeline/components/moved_note.js b/app/javascript/mastodon/features/account_timeline/components/moved_note.js index a548160a5..daff47a9d 100644 --- a/app/javascript/mastodon/features/account_timeline/components/moved_note.js +++ b/app/javascript/mastodon/features/account_timeline/components/moved_note.js @@ -4,7 +4,7 @@ import { FormattedMessage } from 'react-intl'; import ImmutablePureComponent from 'react-immutable-pure-component'; import AvatarOverlay from '../../../components/avatar_overlay'; import DisplayName from '../../../components/display_name'; -import Permalink from 'mastodon/components/permalink'; +import { Link } from 'react-router-dom'; export default class MovedNote extends ImmutablePureComponent { @@ -23,12 +23,12 @@ export default class MovedNote extends ImmutablePureComponent { </div> <div className='moved-account-banner__action'> - <Permalink href={to.get('url')} to={`/@${to.get('acct')}`} className='detailed-status__display-name'> + <Link to={`/@${to.get('acct')}`} className='detailed-status__display-name'> <div className='detailed-status__display-avatar'><AvatarOverlay account={to} friend={from} /></div> <DisplayName account={to} /> - </Permalink> + </Link> - <Permalink href={to.get('url')} to={`/@${to.get('acct')}`} className='button'><FormattedMessage id='account.go_to_profile' defaultMessage='Go to profile' /></Permalink> + <Link to={`/@${to.get('acct')}`} className='button'><FormattedMessage id='account.go_to_profile' defaultMessage='Go to profile' /></Link> </div> </div> ); diff --git a/app/javascript/mastodon/features/compose/components/navigation_bar.js b/app/javascript/mastodon/features/compose/components/navigation_bar.js index 372765ca4..be979af50 100644 --- a/app/javascript/mastodon/features/compose/components/navigation_bar.js +++ b/app/javascript/mastodon/features/compose/components/navigation_bar.js @@ -3,7 +3,7 @@ import PropTypes from 'prop-types'; import ImmutablePropTypes from 'react-immutable-proptypes'; import ActionBar from './action_bar'; import Avatar from '../../../components/avatar'; -import Permalink from '../../../components/permalink'; +import { Link } from 'react-router-dom'; import IconButton from '../../../components/icon_button'; import { FormattedMessage } from 'react-intl'; import ImmutablePureComponent from 'react-immutable-pure-component'; @@ -19,15 +19,15 @@ export default class NavigationBar extends ImmutablePureComponent { render () { return ( <div className='navigation-bar'> - <Permalink href={this.props.account.get('url')} to={`/@${this.props.account.get('acct')}`}> + <Link to={`/@${this.props.account.get('acct')}`}> <span style={{ display: 'none' }}>{this.props.account.get('acct')}</span> <Avatar account={this.props.account} size={46} /> - </Permalink> + </Link> <div className='navigation-bar__profile'> - <Permalink href={this.props.account.get('url')} to={`/@${this.props.account.get('acct')}`}> + <Link to={`/@${this.props.account.get('acct')}`}> <strong className='navigation-bar__profile-account'>@{this.props.account.get('acct')}</strong> - </Permalink> + </Link> <a href='/settings/profile' className='navigation-bar__profile-edit'><FormattedMessage id='navigation_bar.edit_profile' defaultMessage='Edit profile' /></a> </div> diff --git a/app/javascript/mastodon/features/compose/components/reply_indicator.js b/app/javascript/mastodon/features/compose/components/reply_indicator.js index 863defb76..fc236882a 100644 --- a/app/javascript/mastodon/features/compose/components/reply_indicator.js +++ b/app/javascript/mastodon/features/compose/components/reply_indicator.js @@ -50,7 +50,7 @@ class ReplyIndicator extends ImmutablePureComponent { <div className='reply-indicator__header'> <div className='reply-indicator__cancel'><IconButton title={intl.formatMessage(messages.cancel)} icon='times' onClick={this.handleClick} inverted /></div> - <a href={status.getIn(['account', 'url'])} onClick={this.handleAccountClick} className='reply-indicator__display-name'> + <a href={`/@${status.getIn(['account', 'acct'])}`} onClick={this.handleAccountClick} className='reply-indicator__display-name'> <div className='reply-indicator__display-avatar'><Avatar account={status.get('account')} size={24} /></div> <DisplayName account={status.get('account')} /> </a> diff --git a/app/javascript/mastodon/features/direct_timeline/components/conversation.js b/app/javascript/mastodon/features/direct_timeline/components/conversation.js index 77ff2ce7b..4a770970d 100644 --- a/app/javascript/mastodon/features/direct_timeline/components/conversation.js +++ b/app/javascript/mastodon/features/direct_timeline/components/conversation.js @@ -7,7 +7,7 @@ import AttachmentList from 'mastodon/components/attachment_list'; import { defineMessages, injectIntl, FormattedMessage } from 'react-intl'; import DropdownMenuContainer from 'mastodon/containers/dropdown_menu_container'; import AvatarComposite from 'mastodon/components/avatar_composite'; -import Permalink from 'mastodon/components/permalink'; +import { Link } from 'react-router-dom'; import IconButton from 'mastodon/components/icon_button'; import RelativeTimestamp from 'mastodon/components/relative_timestamp'; import { HotKeys } from 'react-hotkeys'; @@ -133,7 +133,7 @@ class Conversation extends ImmutablePureComponent { menu.push({ text: intl.formatMessage(messages.delete), action: this.handleDelete }); - const names = accounts.map(a => <Permalink to={`/@${a.get('acct')}`} href={a.get('url')} key={a.get('id')} title={a.get('acct')}><bdi><strong className='display-name__html' dangerouslySetInnerHTML={{ __html: a.get('display_name_html') }} /></bdi></Permalink>).reduce((prev, cur) => [prev, ', ', cur]); + const names = accounts.map(a => <Link to={`/@${a.get('acct')}`} key={a.get('id')} title={a.get('acct')}><bdi><strong className='display-name__html' dangerouslySetInnerHTML={{ __html: a.get('display_name_html') }} /></bdi></Link>).reduce((prev, cur) => [prev, ', ', cur]); const handlers = { reply: this.handleReply, diff --git a/app/javascript/mastodon/features/directory/components/account_card.js b/app/javascript/mastodon/features/directory/components/account_card.js index e7eeb2254..977f0c32c 100644 --- a/app/javascript/mastodon/features/directory/components/account_card.js +++ b/app/javascript/mastodon/features/directory/components/account_card.js @@ -6,7 +6,7 @@ import { connect } from 'react-redux'; import { makeGetAccount } from 'mastodon/selectors'; import Avatar from 'mastodon/components/avatar'; import DisplayName from 'mastodon/components/display_name'; -import Permalink from 'mastodon/components/permalink'; +import { Link } from 'react-router-dom'; import Button from 'mastodon/components/button'; import { FormattedMessage, injectIntl, defineMessages } from 'react-intl'; import { autoPlayGif, me, unfollowModal } from 'mastodon/initial_state'; @@ -169,7 +169,7 @@ class AccountCard extends ImmutablePureComponent { return ( <div className='account-card'> - <Permalink href={account.get('url')} to={`/@${account.get('acct')}`} className='account-card__permalink'> + <Link to={`/@${account.get('acct')}`} className='account-card__permalink'> <div className='account-card__header'> <img src={ @@ -183,7 +183,7 @@ class AccountCard extends ImmutablePureComponent { <div className='account-card__title__avatar'><Avatar account={account} size={56} /></div> <DisplayName account={account} /> </div> - </Permalink> + </Link> {account.get('note').length > 0 && ( <div diff --git a/app/javascript/mastodon/features/emoji/__tests__/emoji-test.js b/app/javascript/mastodon/features/emoji/__tests__/emoji-test.js index 07b3d8c53..2f19aab7e 100644 --- a/app/javascript/mastodon/features/emoji/__tests__/emoji-test.js +++ b/app/javascript/mastodon/features/emoji/__tests__/emoji-test.js @@ -11,8 +11,8 @@ describe('emoji', () => { }); it('works with unclosed tags', () => { - expect(emojify('hello>')).toEqual('hello>'); - expect(emojify('<hello')).toEqual('<hello'); + expect(emojify('hello>')).toEqual('hello>'); + expect(emojify('<hello')).toEqual(''); }); it('works with unclosed shortcodes', () => { @@ -22,23 +22,23 @@ describe('emoji', () => { it('does unicode', () => { expect(emojify('\uD83D\uDC69\u200D\uD83D\uDC69\u200D\uD83D\uDC66\u200D\uD83D\uDC66')).toEqual( - '<img draggable="false" class="emojione" alt="👩👩👦👦" title=":woman-woman-boy-boy:" src="/emoji/1f469-200d-1f469-200d-1f466-200d-1f466.svg" />'); + '<img draggable="false" class="emojione" alt="👩👩👦👦" title=":woman-woman-boy-boy:" src="/emoji/1f469-200d-1f469-200d-1f466-200d-1f466.svg">'); expect(emojify('👨👩👧👧')).toEqual( - '<img draggable="false" class="emojione" alt="👨👩👧👧" title=":man-woman-girl-girl:" src="/emoji/1f468-200d-1f469-200d-1f467-200d-1f467.svg" />'); - expect(emojify('👩👩👦')).toEqual('<img draggable="false" class="emojione" alt="👩👩👦" title=":woman-woman-boy:" src="/emoji/1f469-200d-1f469-200d-1f466.svg" />'); + '<img draggable="false" class="emojione" alt="👨👩👧👧" title=":man-woman-girl-girl:" src="/emoji/1f468-200d-1f469-200d-1f467-200d-1f467.svg">'); + expect(emojify('👩👩👦')).toEqual('<img draggable="false" class="emojione" alt="👩👩👦" title=":woman-woman-boy:" src="/emoji/1f469-200d-1f469-200d-1f466.svg">'); expect(emojify('\u2757')).toEqual( - '<img draggable="false" class="emojione" alt="❗" title=":exclamation:" src="/emoji/2757.svg" />'); + '<img draggable="false" class="emojione" alt="❗" title=":exclamation:" src="/emoji/2757.svg">'); }); it('does multiple unicode', () => { expect(emojify('\u2757 #\uFE0F\u20E3')).toEqual( - '<img draggable="false" class="emojione" alt="❗" title=":exclamation:" src="/emoji/2757.svg" /> <img draggable="false" class="emojione" alt="#️⃣" title=":hash:" src="/emoji/23-20e3.svg" />'); + '<img draggable="false" class="emojione" alt="❗" title=":exclamation:" src="/emoji/2757.svg"> <img draggable="false" class="emojione" alt="#️⃣" title=":hash:" src="/emoji/23-20e3.svg">'); expect(emojify('\u2757#\uFE0F\u20E3')).toEqual( - '<img draggable="false" class="emojione" alt="❗" title=":exclamation:" src="/emoji/2757.svg" /><img draggable="false" class="emojione" alt="#️⃣" title=":hash:" src="/emoji/23-20e3.svg" />'); + '<img draggable="false" class="emojione" alt="❗" title=":exclamation:" src="/emoji/2757.svg"><img draggable="false" class="emojione" alt="#️⃣" title=":hash:" src="/emoji/23-20e3.svg">'); expect(emojify('\u2757 #\uFE0F\u20E3 \u2757')).toEqual( - '<img draggable="false" class="emojione" alt="❗" title=":exclamation:" src="/emoji/2757.svg" /> <img draggable="false" class="emojione" alt="#️⃣" title=":hash:" src="/emoji/23-20e3.svg" /> <img draggable="false" class="emojione" alt="❗" title=":exclamation:" src="/emoji/2757.svg" />'); + '<img draggable="false" class="emojione" alt="❗" title=":exclamation:" src="/emoji/2757.svg"> <img draggable="false" class="emojione" alt="#️⃣" title=":hash:" src="/emoji/23-20e3.svg"> <img draggable="false" class="emojione" alt="❗" title=":exclamation:" src="/emoji/2757.svg">'); expect(emojify('foo \u2757 #\uFE0F\u20E3 bar')).toEqual( - 'foo <img draggable="false" class="emojione" alt="❗" title=":exclamation:" src="/emoji/2757.svg" /> <img draggable="false" class="emojione" alt="#️⃣" title=":hash:" src="/emoji/23-20e3.svg" /> bar'); + 'foo <img draggable="false" class="emojione" alt="❗" title=":exclamation:" src="/emoji/2757.svg"> <img draggable="false" class="emojione" alt="#️⃣" title=":hash:" src="/emoji/23-20e3.svg"> bar'); }); it('ignores unicode inside of tags', () => { @@ -46,16 +46,16 @@ describe('emoji', () => { }); it('does multiple emoji properly (issue 5188)', () => { - expect(emojify('👌🌈💕')).toEqual('<img draggable="false" class="emojione" alt="👌" title=":ok_hand:" src="/emoji/1f44c.svg" /><img draggable="false" class="emojione" alt="🌈" title=":rainbow:" src="/emoji/1f308.svg" /><img draggable="false" class="emojione" alt="💕" title=":two_hearts:" src="/emoji/1f495.svg" />'); - expect(emojify('👌 🌈 💕')).toEqual('<img draggable="false" class="emojione" alt="👌" title=":ok_hand:" src="/emoji/1f44c.svg" /> <img draggable="false" class="emojione" alt="🌈" title=":rainbow:" src="/emoji/1f308.svg" /> <img draggable="false" class="emojione" alt="💕" title=":two_hearts:" src="/emoji/1f495.svg" />'); + expect(emojify('👌🌈💕')).toEqual('<img draggable="false" class="emojione" alt="👌" title=":ok_hand:" src="/emoji/1f44c.svg"><img draggable="false" class="emojione" alt="🌈" title=":rainbow:" src="/emoji/1f308.svg"><img draggable="false" class="emojione" alt="💕" title=":two_hearts:" src="/emoji/1f495.svg">'); + expect(emojify('👌 🌈 💕')).toEqual('<img draggable="false" class="emojione" alt="👌" title=":ok_hand:" src="/emoji/1f44c.svg"> <img draggable="false" class="emojione" alt="🌈" title=":rainbow:" src="/emoji/1f308.svg"> <img draggable="false" class="emojione" alt="💕" title=":two_hearts:" src="/emoji/1f495.svg">'); }); it('does an emoji that has no shortcode', () => { - expect(emojify('👁🗨')).toEqual('<img draggable="false" class="emojione" alt="👁🗨" title="" src="/emoji/1f441-200d-1f5e8.svg" />'); + expect(emojify('👁🗨')).toEqual('<img draggable="false" class="emojione" alt="👁🗨" title="" src="/emoji/1f441-200d-1f5e8.svg">'); }); it('does an emoji whose filename is irregular', () => { - expect(emojify('↙️')).toEqual('<img draggable="false" class="emojione" alt="↙️" title=":arrow_lower_left:" src="/emoji/2199.svg" />'); + expect(emojify('↙️')).toEqual('<img draggable="false" class="emojione" alt="↙️" title=":arrow_lower_left:" src="/emoji/2199.svg">'); }); it('avoid emojifying on invisible text', () => { @@ -67,26 +67,26 @@ describe('emoji', () => { it('avoid emojifying on invisible text with nested tags', () => { expect(emojify('<span class="invisible">😄<span class="foo">bar</span>😴</span>😇')) - .toEqual('<span class="invisible">😄<span class="foo">bar</span>😴</span><img draggable="false" class="emojione" alt="😇" title=":innocent:" src="/emoji/1f607.svg" />'); + .toEqual('<span class="invisible">😄<span class="foo">bar</span>😴</span><img draggable="false" class="emojione" alt="😇" title=":innocent:" src="/emoji/1f607.svg">'); expect(emojify('<span class="invisible">😄<span class="invisible">😕</span>😴</span>😇')) - .toEqual('<span class="invisible">😄<span class="invisible">😕</span>😴</span><img draggable="false" class="emojione" alt="😇" title=":innocent:" src="/emoji/1f607.svg" />'); - expect(emojify('<span class="invisible">😄<br/>😴</span>😇')) - .toEqual('<span class="invisible">😄<br/>😴</span><img draggable="false" class="emojione" alt="😇" title=":innocent:" src="/emoji/1f607.svg" />'); + .toEqual('<span class="invisible">😄<span class="invisible">😕</span>😴</span><img draggable="false" class="emojione" alt="😇" title=":innocent:" src="/emoji/1f607.svg">'); + expect(emojify('<span class="invisible">😄<br>😴</span>😇')) + .toEqual('<span class="invisible">😄<br>😴</span><img draggable="false" class="emojione" alt="😇" title=":innocent:" src="/emoji/1f607.svg">'); }); it('skips the textual presentation VS15 character', () => { expect(emojify('✴︎')) // This is U+2734 EIGHT POINTED BLACK STAR then U+FE0E VARIATION SELECTOR-15 - .toEqual('<img draggable="false" class="emojione" alt="✴" title=":eight_pointed_black_star:" src="/emoji/2734_border.svg" />'); + .toEqual('<img draggable="false" class="emojione" alt="✴" title=":eight_pointed_black_star:" src="/emoji/2734_border.svg">'); }); it('does an simple emoji properly', () => { expect(emojify('♀♂')) - .toEqual('<img draggable="false" class="emojione" alt="♀" title=":female_sign:" src="/emoji/2640.svg" /><img draggable="false" class="emojione" alt="♂" title=":male_sign:" src="/emoji/2642.svg" />'); + .toEqual('<img draggable="false" class="emojione" alt="♀" title=":female_sign:" src="/emoji/2640.svg"><img draggable="false" class="emojione" alt="♂" title=":male_sign:" src="/emoji/2642.svg">'); }); it('does an emoji containing ZWJ properly', () => { expect(emojify('💂♀️💂♂️')) - .toEqual('<img draggable="false" class="emojione" alt="💂\u200D♀️" title=":female-guard:" src="/emoji/1f482-200d-2640-fe0f_border.svg" /><img draggable="false" class="emojione" alt="💂\u200D♂️" title=":male-guard:" src="/emoji/1f482-200d-2642-fe0f_border.svg" />'); + .toEqual('<img draggable="false" class="emojione" alt="💂\u200D♀️" title=":female-guard:" src="/emoji/1f482-200d-2640-fe0f_border.svg"><img draggable="false" class="emojione" alt="💂\u200D♂️" title=":male-guard:" src="/emoji/1f482-200d-2642-fe0f_border.svg">'); }); }); }); diff --git a/app/javascript/mastodon/features/emoji/emoji.js b/app/javascript/mastodon/features/emoji/emoji.js index fb1a3804c..52a8458fb 100644 --- a/app/javascript/mastodon/features/emoji/emoji.js +++ b/app/javascript/mastodon/features/emoji/emoji.js @@ -19,15 +19,26 @@ const emojiFilename = (filename) => { return borderedEmoji.includes(filename) ? (filename + '_border') : filename; }; -const emojify = (str, customEmojis = {}) => { - const tagCharsWithoutEmojis = '<&'; - const tagCharsWithEmojis = Object.keys(customEmojis).length ? '<&:' : '<&'; - let rtn = '', tagChars = tagCharsWithEmojis, invisible = 0; +const domParser = new DOMParser(); + +const emojifyTextNode = (node, customEmojis) => { + let str = node.textContent; + + const fragment = new DocumentFragment(); + for (;;) { - let match, i = 0, tag; - while (i < str.length && (tag = tagChars.indexOf(str[i])) === -1 && (invisible || !(match = trie.search(str.slice(i))))) { - i += str.codePointAt(i) < 65536 ? 1 : 2; + let match, i = 0; + + if (customEmojis === null) { + while (i < str.length && !(match = trie.search(str.slice(i)))) { + i += str.codePointAt(i) < 65536 ? 1 : 2; + } + } else { + while (i < str.length && str[i] !== ':' && !(match = trie.search(str.slice(i)))) { + i += str.codePointAt(i) < 65536 ? 1 : 2; + } } + let rend, replacement = ''; if (i === str.length) { break; @@ -35,8 +46,6 @@ const emojify = (str, customEmojis = {}) => { if (!(() => { rend = str.indexOf(':', i + 1) + 1; if (!rend) return false; // no pair of ':' - const lt = str.indexOf('<', i + 1); - if (!(lt === -1 || lt >= rend)) return false; // tag appeared before closing ':' const shortname = str.slice(i, rend); // now got a replacee as ':shortname:' // if you want additional emoji handler, add statements below which set replacement and return true. @@ -47,29 +56,6 @@ const emojify = (str, customEmojis = {}) => { } return false; })()) rend = ++i; - } else if (tag >= 0) { // <, & - rend = str.indexOf('>;'[tag], i + 1) + 1; - if (!rend) { - break; - } - if (tag === 0) { - if (invisible) { - if (str[i + 1] === '/') { // closing tag - if (!--invisible) { - tagChars = tagCharsWithEmojis; - } - } else if (str[rend - 2] !== '/') { // opening tag - invisible++; - } - } else { - if (str.startsWith('<span class="invisible">', i)) { - // avoid emojifying on invisible text - invisible = 1; - tagChars = tagCharsWithoutEmojis; - } - } - } - i = rend; } else { // matched to unicode emoji const { filename, shortCode } = unicodeMapping[match]; const title = shortCode ? `:${shortCode}:` : ''; @@ -80,10 +66,43 @@ const emojify = (str, customEmojis = {}) => { rend += 1; } } - rtn += str.slice(0, i) + replacement; + + fragment.append(document.createTextNode(str.slice(0, i))); + if (replacement) { + fragment.append(domParser.parseFromString(replacement, 'text/html').documentElement.getElementsByTagName('img')[0]); + } + node.textContent = str.slice(0, i); str = str.slice(rend); } - return rtn + str; + + fragment.append(document.createTextNode(str)); + node.parentElement.replaceChild(fragment, node); +}; + +const emojifyNode = (node, customEmojis) => { + for (const child of node.childNodes) { + switch(child.nodeType) { + case Node.TEXT_NODE: + emojifyTextNode(child, customEmojis); + break; + case Node.ELEMENT_NODE: + if (!child.classList.contains('invisible')) + emojifyNode(child, customEmojis); + break; + } + } +}; + +const emojify = (str, customEmojis = {}) => { + const wrapper = document.createElement('div'); + wrapper.innerHTML = str; + + if (!Object.keys(customEmojis).length) + customEmojis = null; + + emojifyNode(wrapper, customEmojis); + + return wrapper.innerHTML; }; export default emojify; diff --git a/app/javascript/mastodon/features/follow_recommendations/components/account.js b/app/javascript/mastodon/features/follow_recommendations/components/account.js index ffc0ab00c..14f4e7e1b 100644 --- a/app/javascript/mastodon/features/follow_recommendations/components/account.js +++ b/app/javascript/mastodon/features/follow_recommendations/components/account.js @@ -6,7 +6,7 @@ import { connect } from 'react-redux'; import { makeGetAccount } from 'mastodon/selectors'; import Avatar from 'mastodon/components/avatar'; import DisplayName from 'mastodon/components/display_name'; -import Permalink from 'mastodon/components/permalink'; +import { Link } from 'react-router-dom'; import IconButton from 'mastodon/components/icon_button'; import { injectIntl, defineMessages } from 'react-intl'; import { followAccount, unfollowAccount } from 'mastodon/actions/accounts'; @@ -66,13 +66,13 @@ class Account extends ImmutablePureComponent { return ( <div className='account follow-recommendations-account'> <div className='account__wrapper'> - <Permalink className='account__display-name account__display-name--with-note' title={account.get('acct')} href={account.get('url')} to={`/@${account.get('acct')}`}> + <Link className='account__display-name account__display-name--with-note' title={account.get('acct')} to={`/@${account.get('acct')}`}> <div className='account__avatar-wrapper'><Avatar account={account} size={36} /></div> <DisplayName account={account} /> <div className='account__note'>{getFirstSentence(account.get('note_plain'))}</div> - </Permalink> + </Link> <div className='account__relationship'> {button} diff --git a/app/javascript/mastodon/features/follow_requests/components/account_authorize.js b/app/javascript/mastodon/features/follow_requests/components/account_authorize.js index 263a7ae16..d41f331e5 100644 --- a/app/javascript/mastodon/features/follow_requests/components/account_authorize.js +++ b/app/javascript/mastodon/features/follow_requests/components/account_authorize.js @@ -1,7 +1,7 @@ import React from 'react'; import PropTypes from 'prop-types'; import ImmutablePropTypes from 'react-immutable-proptypes'; -import Permalink from '../../../components/permalink'; +import { Link } from 'react-router-dom'; import Avatar from '../../../components/avatar'; import DisplayName from '../../../components/display_name'; import IconButton from '../../../components/icon_button'; @@ -30,10 +30,10 @@ class AccountAuthorize extends ImmutablePureComponent { return ( <div className='account-authorize__wrapper'> <div className='account-authorize'> - <Permalink href={account.get('url')} to={`/@${account.get('acct')}`} className='detailed-status__display-name'> + <Link to={`/@${account.get('acct')}`} className='detailed-status__display-name'> <div className='account-authorize__avatar'><Avatar account={account} size={48} /></div> <DisplayName account={account} /> - </Permalink> + </Link> <div className='account__header__content translate' dangerouslySetInnerHTML={content} /> </div> diff --git a/app/javascript/mastodon/features/notifications/components/follow_request.js b/app/javascript/mastodon/features/notifications/components/follow_request.js index 9ef3fde7e..08de875e3 100644 --- a/app/javascript/mastodon/features/notifications/components/follow_request.js +++ b/app/javascript/mastodon/features/notifications/components/follow_request.js @@ -3,7 +3,7 @@ import ImmutablePropTypes from 'react-immutable-proptypes'; import PropTypes from 'prop-types'; import Avatar from 'mastodon/components/avatar'; import DisplayName from 'mastodon/components/display_name'; -import Permalink from 'mastodon/components/permalink'; +import { Link } from 'react-router-dom'; import IconButton from 'mastodon/components/icon_button'; import { defineMessages, injectIntl } from 'react-intl'; import ImmutablePureComponent from 'react-immutable-pure-component'; @@ -42,10 +42,10 @@ class FollowRequest extends ImmutablePureComponent { return ( <div className='account'> <div className='account__wrapper'> - <Permalink key={account.get('id')} className='account__display-name' title={account.get('acct')} href={account.get('url')} to={`/@${account.get('acct')}`}> + <Link key={account.get('id')} className='account__display-name' title={account.get('acct')} to={`/@${account.get('acct')}`}> <div className='account__avatar-wrapper'><Avatar account={account} size={36} /></div> <DisplayName account={account} /> - </Permalink> + </Link> <div className='account__relationship'> <IconButton title={intl.formatMessage(messages.authorize)} icon='check' onClick={onAuthorize} /> diff --git a/app/javascript/mastodon/features/notifications/components/notification.js b/app/javascript/mastodon/features/notifications/components/notification.js index 5974e378e..ea2c9c0a4 100644 --- a/app/javascript/mastodon/features/notifications/components/notification.js +++ b/app/javascript/mastodon/features/notifications/components/notification.js @@ -10,7 +10,7 @@ import AccountContainer from 'mastodon/containers/account_container'; import Report from './report'; import FollowRequestContainer from '../containers/follow_request_container'; import Icon from 'mastodon/components/icon'; -import Permalink from 'mastodon/components/permalink'; +import { Link } from 'react-router-dom'; import classNames from 'classnames'; const messages = defineMessages({ @@ -378,7 +378,7 @@ class Notification extends ImmutablePureComponent { const targetAccount = report.get('target_account'); const targetDisplayNameHtml = { __html: targetAccount.get('display_name_html') }; - const targetLink = <bdi><Permalink className='notification__display-name' href={targetAccount.get('url')} title={targetAccount.get('acct')} to={`/@${targetAccount.get('acct')}`} dangerouslySetInnerHTML={targetDisplayNameHtml} /></bdi>; + const targetLink = <bdi><Link className='notification__display-name' title={targetAccount.get('acct')} to={`/@${targetAccount.get('acct')}`} dangerouslySetInnerHTML={targetDisplayNameHtml} /></bdi>; return ( <HotKeys handlers={this.getHandlers()}> @@ -403,7 +403,7 @@ class Notification extends ImmutablePureComponent { const { notification } = this.props; const account = notification.get('account'); const displayNameHtml = { __html: account.get('display_name_html') }; - const link = <bdi><Permalink className='notification__display-name' href={account.get('url')} title={account.get('acct')} to={`/@${account.get('acct')}`} dangerouslySetInnerHTML={displayNameHtml} /></bdi>; + const link = <bdi><Link className='notification__display-name' href={`/@${account.get('acct')}`} title={account.get('acct')} to={`/@${account.get('acct')}`} dangerouslySetInnerHTML={displayNameHtml} /></bdi>; switch(notification.get('type')) { case 'follow': diff --git a/app/javascript/mastodon/features/picture_in_picture/components/footer.js b/app/javascript/mastodon/features/picture_in_picture/components/footer.js index 5b875dc30..0dff834c3 100644 --- a/app/javascript/mastodon/features/picture_in_picture/components/footer.js +++ b/app/javascript/mastodon/features/picture_in_picture/components/footer.js @@ -184,7 +184,7 @@ class Footer extends ImmutablePureComponent { <IconButton className='status__action-bar-button' title={replyTitle} icon={status.get('in_reply_to_account_id') === status.getIn(['account', 'id']) ? 'reply' : replyIcon} onClick={this.handleReplyClick} counter={status.get('replies_count')} obfuscateCount /> <IconButton className={classNames('status__action-bar-button', { reblogPrivate })} disabled={!publicStatus && !reblogPrivate} active={status.get('reblogged')} title={reblogTitle} icon='retweet' onClick={this.handleReblogClick} counter={status.get('reblogs_count')} /> <IconButton className='status__action-bar-button star-icon' animate active={status.get('favourited')} title={intl.formatMessage(messages.favourite)} icon='star' onClick={this.handleFavouriteClick} counter={status.get('favourites_count')} /> - {withOpenButton && <IconButton className='status__action-bar-button' title={intl.formatMessage(messages.open)} icon='external-link' onClick={this.handleOpenClick} href={status.get('url')} />} + {withOpenButton && <IconButton className='status__action-bar-button' title={intl.formatMessage(messages.open)} icon='external-link' onClick={this.handleOpenClick} href={`/@${status.getIn(['account', 'acct'])}\/${status.get('id')}`} />} </div> ); } diff --git a/app/javascript/mastodon/features/status/components/detailed_status.js b/app/javascript/mastodon/features/status/components/detailed_status.js index 1a2aab819..c62910e0e 100644 --- a/app/javascript/mastodon/features/status/components/detailed_status.js +++ b/app/javascript/mastodon/features/status/components/detailed_status.js @@ -261,7 +261,7 @@ class DetailedStatus extends ImmutablePureComponent { return ( <div style={outerStyle}> <div ref={this.setRef} className={classNames('detailed-status', `detailed-status-${status.get('visibility')}`, { compact })}> - <a href={status.getIn(['account', 'url'])} onClick={this.handleAccountClick} className='detailed-status__display-name'> + <a href={`/@${status.getIn(['account', 'acct'])}`} onClick={this.handleAccountClick} className='detailed-status__display-name'> <div className='detailed-status__display-avatar'><Avatar account={status.get('account')} size={46} /></div> <DisplayName account={status.get('account')} localDomain={this.props.domain} /> </a> @@ -276,7 +276,7 @@ class DetailedStatus extends ImmutablePureComponent { {media} <div className='detailed-status__meta'> - <a className='detailed-status__datetime' href={status.get('url')} target='_blank' rel='noopener noreferrer'> + <a className='detailed-status__datetime' href={`/@${status.getIn(['account', 'acct'])}\/${status.get('id')}`} target='_blank' rel='noopener noreferrer'> <FormattedDate value={new Date(status.get('created_at'))} hour12={false} year='numeric' month='short' day='2-digit' hour='2-digit' minute='2-digit' /> </a>{edited}{visibilityLink}{applicationLink}{reblogLink} · {favouriteLink} </div> diff --git a/app/javascript/mastodon/features/ui/components/boost_modal.js b/app/javascript/mastodon/features/ui/components/boost_modal.js index d7a6d711e..077ce7b35 100644 --- a/app/javascript/mastodon/features/ui/components/boost_modal.js +++ b/app/javascript/mastodon/features/ui/components/boost_modal.js @@ -98,12 +98,12 @@ class BoostModal extends ImmutablePureComponent { <div className='boost-modal__container'> <div className={classNames('status', `status-${status.get('visibility')}`, 'light')}> <div className='status__info'> - <a href={status.get('url')} className='status__relative-time' target='_blank' rel='noopener noreferrer'> + <a href={`/@${status.getIn(['account', 'acct'])}\/${status.get('id')}`} className='status__relative-time' target='_blank' rel='noopener noreferrer'> <span className='status__visibility-icon'><Icon id={visibilityIcon.icon} title={visibilityIcon.text} /></span> <RelativeTimestamp timestamp={status.get('created_at')} /> </a> - <a onClick={this.handleAccountClick} href={status.getIn(['account', 'url'])} className='status__display-name'> + <a onClick={this.handleAccountClick} href={`/@${status.getIn(['account', 'acct'])}`} className='status__display-name'> <div className='status__avatar'> <Avatar account={status.get('account')} size={48} /> </div> diff --git a/app/javascript/mastodon/features/ui/components/header.js b/app/javascript/mastodon/features/ui/components/header.js index a1c281315..4e109080e 100644 --- a/app/javascript/mastodon/features/ui/components/header.js +++ b/app/javascript/mastodon/features/ui/components/header.js @@ -4,16 +4,15 @@ import { Link, withRouter } from 'react-router-dom'; import { FormattedMessage } from 'react-intl'; import { registrationsOpen, me } from 'mastodon/initial_state'; import Avatar from 'mastodon/components/avatar'; -import Permalink from 'mastodon/components/permalink'; import PropTypes from 'prop-types'; import { connect } from 'react-redux'; const Account = connect(state => ({ account: state.getIn(['accounts', me]), }))(({ account }) => ( - <Permalink href={account.get('url')} to={`/@${account.get('acct')}`} title={account.get('acct')}> + <Link to={`/@${account.get('acct')}`} title={account.get('acct')}> <Avatar account={account} size={35} /> - </Permalink> + </Link> )); export default @withRouter diff --git a/app/javascript/mastodon/locales/ca.json b/app/javascript/mastodon/locales/ca.json index ea63eedb3..4b5fb25e4 100644 --- a/app/javascript/mastodon/locales/ca.json +++ b/app/javascript/mastodon/locales/ca.json @@ -1,14 +1,14 @@ { "about.blocks": "Servidors moderats", "about.contact": "Contacte:", - "about.disclaimer": "Mastodon és un programari lliure de codi obert i una marca comercial de Mastodon gGmbH.", - "about.domain_blocks.no_reason_available": "Motiu no disponible", + "about.disclaimer": "Mastodon és programari lliure de codi obert i una marca comercial de Mastodon gGmbH.", + "about.domain_blocks.no_reason_available": "No és disponible el motiu", "about.domain_blocks.preamble": "En general, Mastodon et permet veure el contingut i interaccionar amb els usuaris de qualsevol altre servidor del fedivers. Aquestes són les excepcions que s'han fet en aquest servidor particular.", - "about.domain_blocks.silenced.explanation": "Generalment no veuràs perfils ni contingut d'aquest servidor, a menys que el cerquis explícitament o optis per ell seguint-lo.", + "about.domain_blocks.silenced.explanation": "Generalment no veuràs perfils ni contingut d'aquest servidor, a menys que el cerquis explícitament o optis per seguir-lo.", "about.domain_blocks.silenced.title": "Limitat", - "about.domain_blocks.suspended.explanation": "No es processaran, emmagatzemaran ni s'intercanviaran dades d'aquest servidor, fent impossible qualsevol interacció o comunicació amb els usuaris d'aquest servidor.", + "about.domain_blocks.suspended.explanation": "No es processaran, emmagatzemaran ni intercanviaran dades d'aquest servidor, fent impossible qualsevol interacció o comunicació amb els seus usuaris.", "about.domain_blocks.suspended.title": "Suspès", - "about.not_available": "Aquesta informació no s'ha fet disponible en aquest servidor.", + "about.not_available": "Aquesta informació no és disponible en aquest servidor.", "about.powered_by": "Xarxa social descentralitzada impulsada per {mastodon}", "about.rules": "Normes del servidor", "account.account_note_header": "Nota", @@ -19,19 +19,19 @@ "account.block_domain": "Bloqueja el domini {domain}", "account.blocked": "Bloquejat", "account.browse_more_on_origin_server": "Navega més en el perfil original", - "account.cancel_follow_request": "Retirar la sol·licitud de seguiment", + "account.cancel_follow_request": "Retira la sol·licitud de seguiment", "account.direct": "Envia missatge directe a @{name}", "account.disable_notifications": "No em notifiquis les publicacions de @{name}", - "account.domain_blocked": "Domini bloquejat", + "account.domain_blocked": "Domini blocat", "account.edit_profile": "Edita el perfil", - "account.enable_notifications": "Notifica’m les publicacions de @{name}", + "account.enable_notifications": "Notifica'm les publicacions de @{name}", "account.endorse": "Recomana en el perfil", "account.featured_tags.last_status_at": "Última publicació el {date}", - "account.featured_tags.last_status_never": "Cap publicació", + "account.featured_tags.last_status_never": "No hi ha publicacions", "account.featured_tags.title": "Etiquetes destacades de: {name}", "account.follow": "Segueix", "account.followers": "Seguidors", - "account.followers.empty": "Ningú segueix aquest usuari encara.", + "account.followers.empty": "Encara ningú no segueix aquest usuari.", "account.followers_counter": "{count, plural, one {{counter} Seguidor} other {{counter} Seguidors}}", "account.following": "Seguint", "account.following_counter": "{count, plural, other {{counter} Seguint}}", @@ -52,25 +52,25 @@ "account.open_original_page": "Obre la pàgina original", "account.posts": "Publicacions", "account.posts_with_replies": "Publicacions i respostes", - "account.report": "Informa sobre @{name}", - "account.requested": "Esperant aprovació. Fes clic per cancel·lar la petició de seguiment", + "account.report": "Informa quant a @{name}", + "account.requested": "S'està esperant l'aprovació. Feu clic per a cancel·lar la petició de seguiment", "account.share": "Comparteix el perfil de @{name}", "account.show_reblogs": "Mostra els impulsos de @{name}", "account.statuses_counter": "{count, plural, one {{counter} Publicació} other {{counter} Publicacions}}", "account.unblock": "Desbloqueja @{name}", "account.unblock_domain": "Desbloqueja el domini {domain}", - "account.unblock_short": "Desbloquejar", - "account.unendorse": "No recomanar en el perfil", - "account.unfollow": "Deixar de seguir", + "account.unblock_short": "Desbloqueja", + "account.unendorse": "No recomanis en el perfil", + "account.unfollow": "Deixa de seguir", "account.unmute": "Deixar de silenciar @{name}", - "account.unmute_notifications": "Activar notificacions de @{name}", + "account.unmute_notifications": "Activa les notificacions de @{name}", "account.unmute_short": "Deixa de silenciar", "account_note.placeholder": "Clica per afegir-hi una nota", - "admin.dashboard.daily_retention": "Ràtio de retenció d'usuaris nous, per dia, després del registre", - "admin.dashboard.monthly_retention": "Ràtio de retenció d'usuaris nous, per mes, després del registre", + "admin.dashboard.daily_retention": "Ràtio de retenció d'usuaris nous per dia, després del registre", + "admin.dashboard.monthly_retention": "Ràtio de retenció d'usuaris nous per mes, després del registre", "admin.dashboard.retention.average": "Mitjana", - "admin.dashboard.retention.cohort": "Mes del registre", - "admin.dashboard.retention.cohort_size": "Nous usuaris", + "admin.dashboard.retention.cohort": "Mes de registre", + "admin.dashboard.retention.cohort_size": "Usuaris nous", "alert.rate_limited.message": "Si us plau, torna-ho a provar després de {retry_time, time, medium}.", "alert.rate_limited.title": "Límit de freqüència", "alert.unexpected.message": "S'ha produït un error inesperat.", @@ -79,21 +79,21 @@ "attachments_list.unprocessed": "(sense processar)", "audio.hide": "Amaga l'àudio", "autosuggest_hashtag.per_week": "{count} per setmana", - "boost_modal.combo": "Pots prémer {combo} per evitar-ho el pròxim cop", - "bundle_column_error.copy_stacktrace": "Copiar l'informe d'error", - "bundle_column_error.error.body": "No s'ha pogut renderitzar la pàgina sol·licitada. Podría ser degut a un error en el nostre codi o un problema de compatibilitat del navegador.", + "boost_modal.combo": "Podeu prémer {combo} per a evitar-ho el pròxim cop", + "bundle_column_error.copy_stacktrace": "Copia l'informe d'error", + "bundle_column_error.error.body": "No s'ha pogut renderitzar la pàgina sol·licitada. Podria ser per un error en el nostre codi o per un problema de compatibilitat del navegador.", "bundle_column_error.error.title": "Oh, no!", - "bundle_column_error.network.body": "Hi ha hagut un error al intentar carregar aquesta pàgina. Això podria ser degut a un problem temporal amb la teva connexió a internet o amb aquest servidor.", - "bundle_column_error.network.title": "Error de xarxa", - "bundle_column_error.retry": "Tornar-ho a provar", + "bundle_column_error.network.body": "Hi ha hagut un error en intentar carregar aquesta pàgina. Això podria ser per un problema temporal amb la teva connexió a internet o amb aquest servidor.", + "bundle_column_error.network.title": "Error de connexió", + "bundle_column_error.retry": "Torna-ho a provar", "bundle_column_error.return": "Torna a Inici", - "bundle_column_error.routing.body": "No es pot trobar la pàgina sol·licitada. Estàs segur que la URL de la barra d'adreces és correcte?", + "bundle_column_error.routing.body": "No es pot trobar la pàgina sol·licitada. Segur que la URL de la barra d'adreces és correcta?", "bundle_column_error.routing.title": "404", "bundle_modal_error.close": "Tanca", "bundle_modal_error.message": "S'ha produït un error en carregar aquest component.", - "bundle_modal_error.retry": "Tornar-ho a provar", - "closed_registrations.other_server_instructions": "Donat que Mastodon és descentralitzat, pots crear un compte en un altre servidor i encara interactuar amb aquest.", - "closed_registrations_modal.description": "Crear un compte a {domain} no és possible ara mateix però, si us plau, tingues en compte que no necessites específicament un compte a {domain} per a usar Mastodon.", + "bundle_modal_error.retry": "Torna-ho a provar", + "closed_registrations.other_server_instructions": "Com que Mastodon és descentralitzat, pots crear un compte en un altre servidor i seguir interactuant amb aquest.", + "closed_registrations_modal.description": "No es pot crear un compte a {domain} ara mateix, però tingueu en compte que no necessiteu específicament un compte a {domain} per a usar Mastodon.", "closed_registrations_modal.find_another_server": "Troba un altre servidor", "closed_registrations_modal.preamble": "Mastodon és descentralitzat per tant no importa on tinguis el teu compte, seràs capaç de seguir i interactuar amb tothom des d'aquest servidor. Fins i tot pots tenir el compte en el teu propi servidor!", "closed_registrations_modal.title": "Registrant-se a Mastodon", @@ -130,7 +130,7 @@ "compose_form.hashtag_warning": "Aquesta publicació no es mostrarà en cap etiqueta, ja que no està llistada. Només les publicacions públiques es poden cercar per etiqueta.", "compose_form.lock_disclaimer": "El teu compte no està {locked}. Tothom pot seguir-te i veure les publicacions de només per a seguidors.", "compose_form.lock_disclaimer.lock": "bloquejat", - "compose_form.placeholder": "Què et passa pel cap?", + "compose_form.placeholder": "Què tens en ment?", "compose_form.poll.add_option": "Afegir una opció", "compose_form.poll.duration": "Durada de l'enquesta", "compose_form.poll.option_placeholder": "Opció {number}", @@ -210,7 +210,7 @@ "empty_column.account_timeline": "No hi ha publicacions aquí!", "empty_column.account_unavailable": "Perfil no disponible", "empty_column.blocks": "Encara no has bloquejat cap usuari.", - "empty_column.bookmarked_statuses": "Encara no has marcat com publicació com a preferida. Quan en marquis una apareixerà aquí.", + "empty_column.bookmarked_statuses": "Encara no has marcat cap publicació com a preferida. Quan en marquis una, apareixerà aquí.", "empty_column.community": "La línia de temps local és buida. Escriu alguna cosa públicament per posar-ho tot en marxa!", "empty_column.direct": "Encara no tens missatges directes. Quan n'enviïs o en rebis, es mostraran aquí.", "empty_column.domain_blocks": "Encara no hi ha dominis bloquejats.", @@ -257,7 +257,7 @@ "filter_modal.title.status": "Filtra una publicació", "follow_recommendations.done": "Fet", "follow_recommendations.heading": "Segueix a la gent de la que t'agradaria veure les seves publicacions! Aquí hi ha algunes recomanacions.", - "follow_recommendations.lead": "Les publicacions del usuaris que segueixes es mostraran en ordre cronològic en la teva línia de temps Inici. No tinguis por en cometre errors, pots fàcilment deixar de seguir-los en qualsevol moment!", + "follow_recommendations.lead": "Les publicacions dels usuaris que segueixes es mostraran en ordre cronològic en la teva línia de temps Inici. No tinguis por en cometre errors, pots fàcilment deixar de seguir-los en qualsevol moment!", "follow_request.authorize": "Autoritza", "follow_request.reject": "Rebutja", "follow_requests.unlocked_explanation": "Tot i que el teu compte no està bloquejat, el personal de {domain} ha pensat que és possible que vulguis revisar les sol·licituds de seguiment d’aquests comptes manualment.", @@ -294,7 +294,7 @@ "interaction_modal.on_this_server": "En aquest servidor", "interaction_modal.other_server_instructions": "Copia i enganxa aquest enllaç en el camp de cerca de la teva aplicació Mastodon preferida o en l'interfície web del teu servidor Mastodon.", "interaction_modal.preamble": "Donat que Mastodon és descentralitzat, pots fer servir el teu compte existent a un altre servidor Mastodon o plataforma compatible si és que no tens compte en aquest.", - "interaction_modal.title.favourite": "Afavoreix la publicació de {name}", + "interaction_modal.title.favourite": "Marca la publicació de {name}", "interaction_modal.title.follow": "Segueix {name}", "interaction_modal.title.reblog": "Impulsa la publicació de {name}", "interaction_modal.title.reply": "Respon a la publicació de {name}", @@ -310,7 +310,7 @@ "keyboard_shortcuts.direct": "per obrir la columna de missatges directes", "keyboard_shortcuts.down": "Mou-lo avall en la llista", "keyboard_shortcuts.enter": "Obrir publicació", - "keyboard_shortcuts.favourite": "Afavoreix la publicació", + "keyboard_shortcuts.favourite": "Marca la publicació", "keyboard_shortcuts.favourites": "Obre la llista de preferits", "keyboard_shortcuts.federated": "Obre la línia de temps federada", "keyboard_shortcuts.heading": "Dreceres de teclat", @@ -542,7 +542,7 @@ "status.admin_account": "Obre l'interfície de moderació per a @{name}", "status.admin_status": "Obrir aquesta publicació a la interfície de moderació", "status.block": "Bloqueja @{name}", - "status.bookmark": "Afavoreix", + "status.bookmark": "Marca", "status.cancel_reblog_private": "Desfés l'impuls", "status.cannot_reblog": "Aquesta publicació no es pot impulsar", "status.copy": "Copia l'enllaç a la publicació", diff --git a/app/javascript/mastodon/locales/cy.json b/app/javascript/mastodon/locales/cy.json index 0d1149ef1..9812eec62 100644 --- a/app/javascript/mastodon/locales/cy.json +++ b/app/javascript/mastodon/locales/cy.json @@ -2,7 +2,7 @@ "about.blocks": "Gweinyddion sy'n cael eu cymedroli", "about.contact": "Cyswllt:", "about.disclaimer": "Mae Mastodon yn feddalwedd rhydd, cod agored ac o dan hawlfraint Mastodon gGmbH.", - "about.domain_blocks.no_reason_available": "Reason not available", + "about.domain_blocks.no_reason_available": "Rheswm ddim ar gael", "about.domain_blocks.preamble": "Yn gyffredinol, mae Mastodon yn caniatáu i chi weld cynnwys gan unrhyw weinyddwr arall yn y ffederasiwn a rhyngweithio â hi. Dyma'r eithriadau a wnaed ar y gweinydd penodol hwn.", "about.domain_blocks.silenced.explanation": "Yn gyffredinol, fyddwch chi ddim yn gweld proffiliau a chynnwys o'r gweinydd hwn, oni bai eich bod yn chwilio'n benodol amdano neu yn ymuno drwy ei ddilyn.", "about.domain_blocks.silenced.title": "Tawelwyd", @@ -28,7 +28,7 @@ "account.endorse": "Arddangos ar fy mhroffil", "account.featured_tags.last_status_at": "Y cofnod diwethaf ar {date}", "account.featured_tags.last_status_never": "Dim postiadau", - "account.featured_tags.title": "{name}'s featured hashtags", + "account.featured_tags.title": "hashnodau dan sylw {name}", "account.follow": "Dilyn", "account.followers": "Dilynwyr", "account.followers.empty": "Does neb yn dilyn y defnyddiwr hwn eto.", @@ -49,7 +49,7 @@ "account.mute": "Tawelu @{name}", "account.mute_notifications": "Cuddio hysbysiadau o @{name}", "account.muted": "Distewyd", - "account.open_original_page": "Open original page", + "account.open_original_page": "Agor y dudalen wreiddiol", "account.posts": "Postiadau", "account.posts_with_replies": "Postiadau ac atebion", "account.report": "Adrodd @{name}", @@ -95,7 +95,7 @@ "closed_registrations.other_server_instructions": "Gan fod Mastodon yn ddatganoledig, gallwch greu cyfrif ar weinydd arall a dal i ryngweithio gyda hwn.", "closed_registrations_modal.description": "Ar hyn o bryd nid yw'n bosib creu cyfrif ar {domain}, ond cadwch mewn cof nad oes raid i chi gael cyfrif yn benodol ar {domain} i ddefnyddio Mastodon.", "closed_registrations_modal.find_another_server": "Dod o hyd i weinydd arall", - "closed_registrations_modal.preamble": "Mastodon is decentralized, so no matter where you create your account, you will be able to follow and interact with anyone on this server. You can even self-host it!", + "closed_registrations_modal.preamble": "Mae Mastodon wedi'i ddatganoli, felly does dim gwahaniaeth ble rydych chi'n creu eich cyfrif, byddwch chi'n gallu dilyn a rhyngweithio ag unrhyw un ar y gweinydd hwn. Gallwch hyd yn oed ei gynnal ef eich hun!", "closed_registrations_modal.title": "Cofrestru ar Mastodon", "column.about": "Ynghylch", "column.blocks": "Defnyddwyr a flociwyd", @@ -181,12 +181,12 @@ "directory.local": "O {domain} yn unig", "directory.new_arrivals": "Newydd-ddyfodiaid", "directory.recently_active": "Yn weithredol yn ddiweddar", - "disabled_account_banner.account_settings": "Account settings", + "disabled_account_banner.account_settings": "Gosodiadau'r cyfrif", "disabled_account_banner.text": "Mae eich cyfrif {disabledAccount} wedi ei analluogi ar hyn o bryd.", "dismissable_banner.community_timeline": "Dyma'r postiadau cyhoeddus diweddaraf gan bobl y caiff eu cyfrifon eu cynnal ar {domain}.", "dismissable_banner.dismiss": "Diystyru", - "dismissable_banner.explore_links": "These news stories are being talked about by people on this and other servers of the decentralized network right now.", - "dismissable_banner.explore_statuses": "These posts from this and other servers in the decentralized network are gaining traction on this server right now.", + "dismissable_banner.explore_links": "Mae'r straeon newyddion hyn yn cael eu trafod gan bobl ar y gweinydd hwn a rhai eraill ar y rhwydwaith datganoledig hwn, ar hyn o bryd.", + "dismissable_banner.explore_statuses": "Mae'r cofnodion hyn o'r gweinydd hwn a gweinyddion eraill yn y rhwydwaith datganoledig hwn yn denu sylw ar y gweinydd hwn ar hyn o bryd.", "dismissable_banner.explore_tags": "These hashtags are gaining traction among people on this and other servers of the decentralized network right now.", "dismissable_banner.public_timeline": "These are the most recent public posts from people on this and other servers of the decentralized network that this server knows about.", "embed.instructions": "Gosodwch y post hwn ar eich gwefan drwy gopïo'r côd isod.", diff --git a/app/javascript/mastodon/locales/de.json b/app/javascript/mastodon/locales/de.json index 77aef2197..3cf08a855 100644 --- a/app/javascript/mastodon/locales/de.json +++ b/app/javascript/mastodon/locales/de.json @@ -42,7 +42,7 @@ "account.joined_short": "Beigetreten", "account.languages": "Genutzte Sprachen überarbeiten", "account.link_verified_on": "Das Profil mit dieser E-Mail-Adresse wurde bereits am {date} bestätigt", - "account.locked_info": "Der Privatsphärenstatus dieses Kontos wurde auf „gesperrt“ gesetzt. Die Person bestimmt manuell, wer ihm/ihr folgen darf.", + "account.locked_info": "Die Privatsphäre dieses Kontos wurde auf „geschützt“ gesetzt. Die Person bestimmt manuell, wer ihrem Profil folgen darf.", "account.media": "Medien", "account.mention": "@{name} im Beitrag erwähnen", "account.moved_to": "{name} hat angegeben, dass dieser der neue Account ist:", @@ -87,15 +87,15 @@ "bundle_column_error.network.title": "Netzwerkfehler", "bundle_column_error.retry": "Erneut versuchen", "bundle_column_error.return": "Zurück zur Startseite", - "bundle_column_error.routing.body": "Die angeforderte Seite konnte nicht gefunden werden. Sind Sie sicher, dass die URL in der Adressleiste korrekt ist?", + "bundle_column_error.routing.body": "Die angeforderte Seite konnte nicht gefunden werden. Bist du dir sicher, dass die URL in der Adressleiste korrekt ist?", "bundle_column_error.routing.title": "404", "bundle_modal_error.close": "Schließen", "bundle_modal_error.message": "Etwas ist beim Laden schiefgelaufen.", "bundle_modal_error.retry": "Erneut versuchen", - "closed_registrations.other_server_instructions": "Da Mastodon dezentralisiert ist, können Sie ein Konto auf einem anderen Server erstellen und trotzdem mit diesem Server interagieren.", - "closed_registrations_modal.description": "Das Anlegen eines Kontos auf {domain} ist derzeit nicht möglich, aber bedenken Sie bitte, dass Sie kein spezielles Konto auf {domain} benötigen, um Mastodon nutzen zu können.", + "closed_registrations.other_server_instructions": "Da Mastodon dezentralisiert ist, kannst du ein Konto auf einem anderen Server erstellen und trotzdem mit diesem Server interagieren.", + "closed_registrations_modal.description": "Das Anlegen eines Kontos auf {domain} ist derzeit nicht möglich, aber bedenke, dass du kein extra Konto auf {domain} benötigst, um Mastodon nutzen zu können.", "closed_registrations_modal.find_another_server": "Einen anderen Server auswählen", - "closed_registrations_modal.preamble": "Mastodon ist dezentralisiert, d.h. unabhängig davon, wo Sie Ihr Konto erstellen, können Sie jedem auf diesem Server folgen und mit ihm interagieren. Sie können ihn sogar selbst hosten!", + "closed_registrations_modal.preamble": "Mastodon ist dezentralisiert, das heißt unabhängig davon, wo du dein Konto erstellst, kannst du jedes Konto auf diesem Server folgen und mit dem interagieren. Du kannst auch deinen eigenen Server hosten!", "closed_registrations_modal.title": "Bei Mastodon registrieren", "column.about": "Über", "column.blocks": "Blockierte Profile", @@ -292,7 +292,7 @@ "interaction_modal.description.reply": "Mit einem Account auf Mastodon kannst du auf diesen Beitrag antworten.", "interaction_modal.on_another_server": "Auf einem anderen Server", "interaction_modal.on_this_server": "Auf diesem Server", - "interaction_modal.other_server_instructions": "Kopieren Sie diese Adresse und fügen Sie diese in das Suchfeld Ihrer bevorzugten Mastodon-App oder in die Weboberfläche Ihres Mastodon-Servers ein.", + "interaction_modal.other_server_instructions": "Kopiere diese URL und füge sie in das Suchfeld deiner bevorzugten Mastodon-App oder im Webinterface deiner Mastodon-Instanz ein.", "interaction_modal.preamble": "Da Mastodon dezentralisiert ist, kannst du dein bestehendes Konto auf einem anderen Mastodon-Server oder einer kompatiblen Plattform nutzen, wenn du kein Konto auf dieser Plattform hast.", "interaction_modal.title.favourite": "Lieblingsbeitrag von {name}", "interaction_modal.title.follow": "Folge {name}", @@ -341,7 +341,7 @@ "lightbox.next": "Weiter", "lightbox.previous": "Zurück", "limited_account_hint.action": "Profil trotzdem anzeigen", - "limited_account_hint.title": "Dieses Profil wurde von den Moderator*innnen der Mastodon-Instanz {domain} ausgeblendet.", + "limited_account_hint.title": "Dieses Profil wurde von den Moderator*innen der Mastodon-Instanz {domain} ausgeblendet.", "lists.account.add": "Zur Liste hinzufügen", "lists.account.remove": "Von der Liste entfernen", "lists.delete": "Liste löschen", @@ -491,7 +491,7 @@ "report.placeholder": "Zusätzliche Kommentare", "report.reasons.dislike": "Das gefällt mir nicht", "report.reasons.dislike_description": "Es ist etwas, das du nicht sehen willst", - "report.reasons.other": "Da ist was anderes", + "report.reasons.other": "Es geht um etwas anderes", "report.reasons.other_description": "Das Problem passt nicht in die Kategorien", "report.reasons.spam": "Das ist Spam", "report.reasons.spam_description": "Bösartige Links, gefälschtes Engagement oder wiederholte Antworten", @@ -545,7 +545,7 @@ "status.bookmark": "Lesezeichen setzen", "status.cancel_reblog_private": "Teilen des Beitrags rückgängig machen", "status.cannot_reblog": "Dieser Beitrag kann nicht geteilt werden", - "status.copy": "Kopiere Link des Beitrags", + "status.copy": "Link zum Beitrag kopieren", "status.delete": "Beitrag löschen", "status.detailed_status": "Detaillierte Ansicht der Unterhaltung", "status.direct": "Direktnachricht an @{name}", @@ -588,7 +588,7 @@ "status.show_more_all": "Alle Inhaltswarnungen aufklappen", "status.show_original": "Original anzeigen", "status.translate": "Übersetzen", - "status.translated_from_with": "Von {lang} mit {provider} übersetzt", + "status.translated_from_with": "Aus {lang} mittels {provider} übersetzt", "status.uncached_media_warning": "Nicht verfügbar", "status.unmute_conversation": "Stummschaltung der Unterhaltung aufheben", "status.unpin": "Vom Profil lösen", @@ -638,7 +638,7 @@ "upload_modal.preparing_ocr": "Vorbereitung von OCR…", "upload_modal.preview_label": "Vorschau ({ratio})", "upload_progress.label": "Wird hochgeladen …", - "upload_progress.processing": "Wird verarbeitet …", + "upload_progress.processing": "Wird verarbeitet…", "video.close": "Video schließen", "video.download": "Datei herunterladen", "video.exit_fullscreen": "Vollbild verlassen", diff --git a/app/javascript/mastodon/locales/eo.json b/app/javascript/mastodon/locales/eo.json index 01a2821bc..12823083d 100644 --- a/app/javascript/mastodon/locales/eo.json +++ b/app/javascript/mastodon/locales/eo.json @@ -2,8 +2,8 @@ "about.blocks": "Moderigitaj serviloj", "about.contact": "Kontakto:", "about.disclaimer": "Mastodon estas libera, malfermitkoda programaro kaj varmarko de la firmao Mastodon gGmbH.", - "about.domain_blocks.no_reason_available": "Kialo ne estas disponebla", - "about.domain_blocks.preamble": "Mastodon generally allows you to view content from and interact with users from any other server in the fediverse. These are the exceptions that have been made on this particular server.", + "about.domain_blocks.no_reason_available": "Kialo ne disponebla", + "about.domain_blocks.preamble": "Mastodono ebligas vidi enhavojn el uzantoj kaj komuniki kun ilin el aliaj serviloj el la Fediverso. Estas la limigoj deciditaj por tiu ĉi servilo.", "about.domain_blocks.silenced.explanation": "Vi ne ĝenerale vidos profilojn kaj enhavojn de ĉi tiu servilo, krom se vi eksplice trovas aŭ estas permesita de via sekvato.", "about.domain_blocks.silenced.title": "Limigita", "about.domain_blocks.suspended.explanation": "No data from this server will be processed, stored or exchanged, making any interaction or communication with users from this server impossible.", @@ -40,7 +40,7 @@ "account.go_to_profile": "Iri al profilo", "account.hide_reblogs": "Kaŝi la plusendojn de @{name}", "account.joined_short": "Aliĝis", - "account.languages": "Change subscribed languages", + "account.languages": "Ŝanĝi elekton de abonitaj lingvoj", "account.link_verified_on": "La posedanto de tiu ligilo estis kontrolita je {date}", "account.locked_info": "La privateco de tiu konto estas elektita kiel fermita. La posedanto povas mane akcepti tiun, kiu povas sekvi rin.", "account.media": "Aŭdovidaĵoj", @@ -49,7 +49,7 @@ "account.mute": "Silentigi @{name}", "account.mute_notifications": "Silentigi la sciigojn de @{name}", "account.muted": "Silentigita", - "account.open_original_page": "Open original page", + "account.open_original_page": "Malfermi originan paĝon", "account.posts": "Mesaĝoj", "account.posts_with_replies": "Mesaĝoj kaj respondoj", "account.report": "Raporti @{name}", @@ -96,7 +96,7 @@ "closed_registrations_modal.description": "Creating an account on {domain} is currently not possible, but please keep in mind that you do not need an account specifically on {domain} to use Mastodon.", "closed_registrations_modal.find_another_server": "Trovi alian servilon", "closed_registrations_modal.preamble": "Mastodon is decentralized, so no matter where you create your account, you will be able to follow and interact with anyone on this server. You can even self-host it!", - "closed_registrations_modal.title": "Registri en Mastodon", + "closed_registrations_modal.title": "Krei konton en Mastodon", "column.about": "Pri", "column.blocks": "Blokitaj uzantoj", "column.bookmarks": "Legosignoj", @@ -389,7 +389,7 @@ "navigation_bar.security": "Sekureco", "not_signed_in_indicator.not_signed_in": "You need to sign in to access this resource.", "notification.admin.report": "{name} raportis {target}", - "notification.admin.sign_up": "{name} registris", + "notification.admin.sign_up": "{name} kreis konton", "notification.favourite": "{name} aldonis vian mesaĝon al siaj preferaĵoj", "notification.follow": "{name} eksekvis vin", "notification.follow_request": "{name} petis sekvi vin", @@ -464,8 +464,8 @@ "relative_time.full.days": "antaŭ {number, plural, one {# tago} other {# tagoj}}", "relative_time.full.hours": "antaŭ {number, plural, one {# horo} other {# horoj}}", "relative_time.full.just_now": "ĵus nun", - "relative_time.full.minutes": "{number, plural, one {# minute} other {# minutes}} ago", - "relative_time.full.seconds": "{number, plural, one {# second} other {# seconds}} ago", + "relative_time.full.minutes": "antaŭ {number, plural, one {# minuto} other {# minutoj}}", + "relative_time.full.seconds": "antaŭ {number, plural, one {# sekundo} other {# sekundoj}}", "relative_time.hours": "{number}h", "relative_time.just_now": "nun", "relative_time.minutes": "{number}m", @@ -476,7 +476,7 @@ "report.block_explanation": "You will not see their posts. They will not be able to see your posts or follow you. They will be able to tell that they are blocked.", "report.categories.other": "Aliaj", "report.categories.spam": "Trudmesaĝo", - "report.categories.violation": "Content violates one or more server rules", + "report.categories.violation": "Enhavo malobservas unu aŭ plurajn servilajn regulojn", "report.category.subtitle": "Elektu la plej bonan kongruon", "report.category.title": "Diru al ni kio okazas pri ĉi tiu {type}", "report.category.title_account": "profilo", @@ -528,15 +528,15 @@ "search_results.nothing_found": "Povis trovi nenion por ĉi tiuj serĉaj terminoj", "search_results.statuses": "Mesaĝoj", "search_results.statuses_fts_disabled": "Serĉi mesaĝojn laŭ enhavo ne estas ebligita en ĉi tiu Mastodon-servilo.", - "search_results.title": "Search for {q}", + "search_results.title": "Serĉ-rezultoj por {q}", "search_results.total": "{count, number} {count, plural, one {rezulto} other {rezultoj}}", "server_banner.about_active_users": "People using this server during the last 30 days (Monthly Active Users)", "server_banner.active_users": "active users", - "server_banner.administered_by": "Administered by:", + "server_banner.administered_by": "Administrata de:", "server_banner.introduction": "{domain} is part of the decentralized social network powered by {mastodon}.", "server_banner.learn_more": "Learn more", - "server_banner.server_stats": "Server stats:", - "sign_in_banner.create_account": "Create account", + "server_banner.server_stats": "Statistikoj de la servilo:", + "sign_in_banner.create_account": "Krei konton", "sign_in_banner.sign_in": "Sign in", "sign_in_banner.text": "Sign in to follow profiles or hashtags, favourite, share and reply to posts, or interact from your account on a different server.", "status.admin_account": "Malfermi la kontrolan interfacon por @{name}", @@ -587,13 +587,13 @@ "status.show_more": "Montri pli", "status.show_more_all": "Montri pli ĉiun", "status.show_original": "Show original", - "status.translate": "Translate", - "status.translated_from_with": "Translated from {lang} using {provider}", + "status.translate": "Traduki", + "status.translated_from_with": "Tradukita el {lang} per {provider}", "status.uncached_media_warning": "Nedisponebla", "status.unmute_conversation": "Malsilentigi la konversacion", "status.unpin": "Depingli de profilo", "subscribed_languages.lead": "Only posts in selected languages will appear on your home and list timelines after the change. Select none to receive posts in all languages.", - "subscribed_languages.save": "Save changes", + "subscribed_languages.save": "Konservi ŝanĝojn", "subscribed_languages.target": "Change subscribed languages for {target}", "suggestions.dismiss": "Forigi la proponon", "suggestions.header": "Vi povus interesiĝi pri…", @@ -610,7 +610,7 @@ "timeline_hint.resources.followers": "Sekvantoj", "timeline_hint.resources.follows": "Sekvatoj", "timeline_hint.resources.statuses": "Pli malnovaj mesaĝoj", - "trends.counter_by_accounts": "{count, plural, one {{counter} person} other {{counter} people}} in the past {days, plural, one {day} other {{days} days}}", + "trends.counter_by_accounts": "{count, plural, one {{counter} persono} other {{counter} personoj}} dum la pasinta{days, plural, one { tago} other {j {days} tagoj}}", "trends.trending_now": "Nunaj furoraĵoj", "ui.beforeunload": "Via malneto perdiĝos se vi eliras de Mastodon.", "units.short.billion": "{count}Md", diff --git a/app/javascript/mastodon/locales/es-AR.json b/app/javascript/mastodon/locales/es-AR.json index deb539d0b..74a6acd26 100644 --- a/app/javascript/mastodon/locales/es-AR.json +++ b/app/javascript/mastodon/locales/es-AR.json @@ -2,7 +2,7 @@ "about.blocks": "Servidores moderados", "about.contact": "Contacto:", "about.disclaimer": "Mastodon es software libre y de código abierto y una marca comercial de Mastodon gGmbH.", - "about.domain_blocks.no_reason_available": "Reason not available", + "about.domain_blocks.no_reason_available": "Motivo no disponible", "about.domain_blocks.preamble": "Mastodon normalmente te permite ver el contenido e interactuar con los usuarios de cualquier otro servidor en el fediverso. Estas son las excepciones que se han hecho en este servidor en particular.", "about.domain_blocks.silenced.explanation": "Normalmente no verás perfiles y contenido de este servidor, a menos que lo busqués explícitamente o sigás alguna cuenta.", "about.domain_blocks.silenced.title": "Limitados", @@ -49,7 +49,7 @@ "account.mute": "Silenciar a @{name}", "account.mute_notifications": "Silenciar notificaciones de @{name}", "account.muted": "Silenciado", - "account.open_original_page": "Open original page", + "account.open_original_page": "Abrir página original", "account.posts": "Mensajes", "account.posts_with_replies": "Mnsjs y resp. públicas", "account.report": "Denunciar a @{name}", @@ -292,7 +292,7 @@ "interaction_modal.description.reply": "Con una cuenta en Mastodon, podés responder a este mensaje.", "interaction_modal.on_another_server": "En un servidor diferente", "interaction_modal.on_this_server": "En este servidor", - "interaction_modal.other_server_instructions": "Copia y pega esta URL en la barra de búsqueda de tu aplicación Mastodon favorita o la interfaz web de tu servidor Mastodon.", + "interaction_modal.other_server_instructions": "Copiá y pegá esta dirección web en la barra de búsqueda de tu aplicación favorita de Mastodon, o en la interface web de tu servidor de Mastodon.", "interaction_modal.preamble": "Ya que Mastodon es descentralizado, podés usar tu cuenta existente alojada por otro servidor Mastodon (u otra plataforma compatible, si no tenés una cuenta en ésta).", "interaction_modal.title.favourite": "Marcar como favorito el mensaje de {name}", "interaction_modal.title.follow": "Seguir a {name}", @@ -614,8 +614,8 @@ "trends.trending_now": "Tendencia ahora", "ui.beforeunload": "Tu borrador se perderá si abandonás Mastodon.", "units.short.billion": "{count}MM", - "units.short.million": "{count}M", - "units.short.thousand": "{count}mil", + "units.short.million": "{count} M", + "units.short.thousand": "{count} mil", "upload_area.title": "Para subir, arrastrá y soltá", "upload_button.label": "Agregá imágenes, o un archivo de audio o video", "upload_error.limit": "Se excedió el límite de subida de archivos.", diff --git a/app/javascript/mastodon/locales/es.json b/app/javascript/mastodon/locales/es.json index bdbdb8565..c4c625d2f 100644 --- a/app/javascript/mastodon/locales/es.json +++ b/app/javascript/mastodon/locales/es.json @@ -501,7 +501,7 @@ "report.rules.title": "¿Qué normas se están violando?", "report.statuses.subtitle": "Selecciona todos los que correspondan", "report.statuses.title": "¿Hay alguna publicación que respalde este informe?", - "report.submit": "Publicar", + "report.submit": "Enviar", "report.target": "Reportando", "report.thanks.take_action": "Aquí están tus opciones para controlar lo que ves en Mastodon:", "report.thanks.take_action_actionable": "Mientras revisamos esto, puedes tomar medidas contra @{name}:", diff --git a/app/javascript/mastodon/locales/fi.json b/app/javascript/mastodon/locales/fi.json index eec5416c5..3d1454866 100644 --- a/app/javascript/mastodon/locales/fi.json +++ b/app/javascript/mastodon/locales/fi.json @@ -2,7 +2,7 @@ "about.blocks": "Moderoidut palvelimet", "about.contact": "Yhteystiedot:", "about.disclaimer": "Mastodon on vapaa avoimen lähdekoodin ohjelmisto ja Mastodon gGmbH:n tavaramerkki.", - "about.domain_blocks.no_reason_available": "Reason not available", + "about.domain_blocks.no_reason_available": "Syy ei saatavilla", "about.domain_blocks.preamble": "Mastodonin avulla voit yleensä tarkastella sisältöä ja olla vuorovaikutuksessa käyttäjien kanssa millä tahansa muulla palvelimella fediversessä. Nämä ovat poikkeuksia, jotka on tehty tälle palvelimelle.", "about.domain_blocks.silenced.explanation": "Et yleensä näe profiileja ja sisältöä tältä palvelimelta, ellet nimenomaisesti etsi tai valitse sitä seuraamalla.", "about.domain_blocks.silenced.title": "Rajoitettu", @@ -49,7 +49,7 @@ "account.mute": "Mykistä @{name}", "account.mute_notifications": "Mykistä ilmoitukset käyttäjältä @{name}", "account.muted": "Mykistetty", - "account.open_original_page": "Open original page", + "account.open_original_page": "Avaa alkuperäinen sivu", "account.posts": "Viestit", "account.posts_with_replies": "Viestit ja vastaukset", "account.report": "Raportoi @{name}", diff --git a/app/javascript/mastodon/locales/gl.json b/app/javascript/mastodon/locales/gl.json index 3410a8b7d..62a71b122 100644 --- a/app/javascript/mastodon/locales/gl.json +++ b/app/javascript/mastodon/locales/gl.json @@ -2,7 +2,7 @@ "about.blocks": "Servidores moderados", "about.contact": "Contacto:", "about.disclaimer": "Mastodon é software libre, de código aberto, e unha marca comercial de Mastodon gGmbH.", - "about.domain_blocks.no_reason_available": "Reason not available", + "about.domain_blocks.no_reason_available": "Non está indicada a razón", "about.domain_blocks.preamble": "Mastodon de xeito xeral permíteche ver contidos doutros servidores do fediverso e interactuar coas súas usuarias. Estas son as excepcións que se estabeleceron neste servidor en particular.", "about.domain_blocks.silenced.explanation": "Por defecto non verás perfís e contido desde este servidor, a menos que mires de xeito explícito ou optes por seguir ese contido ou usuaria.", "about.domain_blocks.silenced.title": "Limitado", @@ -49,7 +49,7 @@ "account.mute": "Acalar @{name}", "account.mute_notifications": "Acalar as notificacións de @{name}", "account.muted": "Acalada", - "account.open_original_page": "Open original page", + "account.open_original_page": "Abrir páxina orixinal", "account.posts": "Publicacións", "account.posts_with_replies": "Publicacións e respostas", "account.report": "Informar sobre @{name}", diff --git a/app/javascript/mastodon/locales/ja.json b/app/javascript/mastodon/locales/ja.json index 78d5d9e0d..9bc323607 100644 --- a/app/javascript/mastodon/locales/ja.json +++ b/app/javascript/mastodon/locales/ja.json @@ -2,7 +2,7 @@ "about.blocks": "制限中のサーバー", "about.contact": "連絡先", "about.disclaimer": "Mastodonは自由なオープンソースソフトウェアでMastodon gGmbHの商標です。", - "about.domain_blocks.no_reason_available": "Reason not available", + "about.domain_blocks.no_reason_available": "制限理由", "about.domain_blocks.preamble": "Mastodonでは連合先のどのようなサーバーのユーザーとも交流できます。ただし次のサーバーには例外が設定されています。", "about.domain_blocks.silenced.explanation": "このサーバーのプロフィールやコンテンツは、明示的に検索したり、フォローでオプトインしない限り、通常は表示されません。", "about.domain_blocks.silenced.title": "制限", @@ -49,7 +49,7 @@ "account.mute": "@{name}さんをミュート", "account.mute_notifications": "@{name}さんからの通知を受け取らない", "account.muted": "ミュート済み", - "account.open_original_page": "Open original page", + "account.open_original_page": "元のページを開く", "account.posts": "投稿", "account.posts_with_replies": "投稿と返信", "account.report": "@{name}さんを通報", @@ -296,7 +296,7 @@ "interaction_modal.description.reply": "Mastodonのアカウントでこの投稿に反応できます。", "interaction_modal.on_another_server": "別のサーバー", "interaction_modal.on_this_server": "このサーバー", - "interaction_modal.other_server_instructions": "Copy and paste this URL into the search field of your favourite Mastodon app or the web interface of your Mastodon server.", + "interaction_modal.other_server_instructions": "このURLをお気に入りのMastodonアプリやMastodonサーバーのWebインターフェースの検索フィールドにコピーして貼り付けます。", "interaction_modal.preamble": "Mastodonは分散化されているためアカウントを持っていなくても別のMastodonサーバーまたは互換性のあるプラットフォームでホストされているアカウントを使用できます。", "interaction_modal.title.favourite": "{name}さんの投稿をお気に入り", "interaction_modal.title.follow": "{name}さんをフォロー", diff --git a/app/javascript/mastodon/locales/lv.json b/app/javascript/mastodon/locales/lv.json index 89c3aee4e..711a003fe 100644 --- a/app/javascript/mastodon/locales/lv.json +++ b/app/javascript/mastodon/locales/lv.json @@ -461,11 +461,11 @@ "regeneration_indicator.label": "Ielādē…", "regeneration_indicator.sublabel": "Tiek gatavota tava plūsma!", "relative_time.days": "{number}d", - "relative_time.full.days": "{number, plural, one {# diena} other {# dienas}} atpakaļ", - "relative_time.full.hours": "{number, plural, one {# stunda} other {# stundas}} atpakaļ", + "relative_time.full.days": "Pirms {number, plural, one {# dienas} other {# dienām}}", + "relative_time.full.hours": "Pirms {number, plural, one {# stundas} other {# stundām}}", "relative_time.full.just_now": "tikko", - "relative_time.full.minutes": "{number, plural, one {# minūte} other {# minūtes}} atpakaļ", - "relative_time.full.seconds": "{number, plural, one {# sekunde} other {# sekundes}} atpakaļ", + "relative_time.full.minutes": "Pirms {number, plural, one {# minūtes} other {# minūtēm}}", + "relative_time.full.seconds": "Pirms {number, plural, one {# sekundes} other {# sekundēm}}", "relative_time.hours": "{number}st", "relative_time.just_now": "tagad", "relative_time.minutes": "{number}m", @@ -553,7 +553,7 @@ "status.edited": "Rediģēts {date}", "status.edited_x_times": "Rediģēts {count, plural, one {{count} reize} other {{count} reizes}}", "status.embed": "Iestrādāt", - "status.favourite": "Iecienītā", + "status.favourite": "Patīk", "status.filter": "Filtrē šo ziņu", "status.filtered": "Filtrēts", "status.hide": "Slēpt", diff --git a/app/javascript/mastodon/locales/ml.json b/app/javascript/mastodon/locales/ml.json index 0517ce02a..51afa4b43 100644 --- a/app/javascript/mastodon/locales/ml.json +++ b/app/javascript/mastodon/locales/ml.json @@ -1,8 +1,8 @@ { - "about.blocks": "Moderated servers", - "about.contact": "Contact:", + "about.blocks": "മോഡറേറ്റഡ് സെർവറുകൾ", + "about.contact": "ബന്ധപ്പെടുക:", "about.disclaimer": "Mastodon is free, open-source software, and a trademark of Mastodon gGmbH.", - "about.domain_blocks.no_reason_available": "Reason not available", + "about.domain_blocks.no_reason_available": "കാരണം ലഭ്യമല്", "about.domain_blocks.preamble": "Mastodon generally allows you to view content from and interact with users from any other server in the fediverse. These are the exceptions that have been made on this particular server.", "about.domain_blocks.silenced.explanation": "You will generally not see profiles and content from this server, unless you explicitly look it up or opt into it by following.", "about.domain_blocks.silenced.title": "Limited", diff --git a/app/javascript/mastodon/locales/nl.json b/app/javascript/mastodon/locales/nl.json index f3742b5a2..131d56298 100644 --- a/app/javascript/mastodon/locales/nl.json +++ b/app/javascript/mastodon/locales/nl.json @@ -2,7 +2,7 @@ "about.blocks": "Gemodereerde servers", "about.contact": "Contact:", "about.disclaimer": "Mastodon is vrije, opensourcesoftware en een handelsmerk van Mastodon gGmbH.", - "about.domain_blocks.no_reason_available": "Reason not available", + "about.domain_blocks.no_reason_available": "Reden niet beschikbaar", "about.domain_blocks.preamble": "In het algemeen kun je met Mastodon berichten ontvangen van, en interactie hebben met gebruikers van elke server in de fediverse. Dit zijn de uitzonderingen die op deze specifieke server gelden.", "about.domain_blocks.silenced.explanation": "In het algemeen zie je geen berichten en accounts van deze server, tenzij je berichten expliciet opzoekt of ervoor kiest om een account van deze server te volgen.", "about.domain_blocks.silenced.title": "Beperkt", @@ -49,7 +49,7 @@ "account.mute": "@{name} negeren", "account.mute_notifications": "Meldingen van @{name} negeren", "account.muted": "Genegeerd", - "account.open_original_page": "Open original page", + "account.open_original_page": "Originele pagina openen", "account.posts": "Berichten", "account.posts_with_replies": "Berichten en reacties", "account.report": "@{name} rapporteren", diff --git a/app/javascript/mastodon/locales/nn.json b/app/javascript/mastodon/locales/nn.json index 83e0ec9c3..6113e32d0 100644 --- a/app/javascript/mastodon/locales/nn.json +++ b/app/javascript/mastodon/locales/nn.json @@ -151,7 +151,7 @@ "confirmations.block.confirm": "Blokker", "confirmations.block.message": "Er du sikker på at du vil blokkera {name}?", "confirmations.cancel_follow_request.confirm": "Trekk attende førespurnad", - "confirmations.cancel_follow_request.message": "Er du sikker på at du vil trekke attende førespurnaden din for å fylgje {name}?", + "confirmations.cancel_follow_request.message": "Er du sikker på at du vil trekkje attende førespurnaden din om å fylgje {name}?", "confirmations.delete.confirm": "Slett", "confirmations.delete.message": "Er du sikker på at du vil sletta denne statusen?", "confirmations.delete_list.confirm": "Slett", diff --git a/app/javascript/mastodon/locales/no.json b/app/javascript/mastodon/locales/no.json index ff8be31ee..6ef9fd040 100644 --- a/app/javascript/mastodon/locales/no.json +++ b/app/javascript/mastodon/locales/no.json @@ -110,7 +110,7 @@ "column.lists": "Lister", "column.mutes": "Dempede brukere", "column.notifications": "Varsler", - "column.pins": "Pinned toot", + "column.pins": "Festede innlegg", "column.public": "Felles tidslinje", "column_back_button.label": "Tilbake", "column_header.hide_settings": "Skjul innstillinger", @@ -265,7 +265,7 @@ "footer.directory": "Profilkatalog", "footer.get_app": "Last ned appen", "footer.invite": "Invitér folk", - "footer.keyboard_shortcuts": "Keyboard shortcuts", + "footer.keyboard_shortcuts": "Hurtigtaster", "footer.privacy_policy": "Personvernregler", "footer.source_code": "Vis kildekode", "generic.saved": "Lagret", @@ -494,26 +494,26 @@ "report.reasons.other": "Det er noe annet", "report.reasons.other_description": "Problemet passer ikke inn i de andre kategoriene", "report.reasons.spam": "Det er spam", - "report.reasons.spam_description": "Malicious links, fake engagement, or repetitive replies", + "report.reasons.spam_description": "Ondsinnede lenker, falsk engasjement eller repeterende svar", "report.reasons.violation": "Det bryter serverregler", "report.reasons.violation_description": "Du er klar over at det bryter spesifikke regler", "report.rules.subtitle": "Velg alle som passer", "report.rules.title": "Hvilke regler brytes?", "report.statuses.subtitle": "Velg alle som passer", - "report.statuses.title": "Are there any posts that back up this report?", + "report.statuses.title": "Er det noen innlegg som støtter opp under denne rapporten?", "report.submit": "Send inn", "report.target": "Rapporterer", "report.thanks.take_action": "Her er alternativene dine for å kontrollere hva du ser på Mastodon:", - "report.thanks.take_action_actionable": "While we review this, you can take action against @{name}:", + "report.thanks.take_action_actionable": "Mens vi går gjennom dette, kan du iverksettet tiltak mot @{name}:", "report.thanks.title": "Ønsker du ikke å se dette?", - "report.thanks.title_actionable": "Thanks for reporting, we'll look into this.", + "report.thanks.title_actionable": "Takk for at du rapporterer, vi skal se på dette.", "report.unfollow": "Slutt å følge @{name}", "report.unfollow_explanation": "Du følger denne kontoen. For ikke å se innleggene deres i din hjem-feed lenger, slutt å følge dem.", "report_notification.attached_statuses": "{count, plural,one {{count} innlegg} other {{count} innlegg}} vedlagt", "report_notification.categories.other": "Annet", "report_notification.categories.spam": "Søppelpost", "report_notification.categories.violation": "Regelbrudd", - "report_notification.open": "Open report", + "report_notification.open": "Åpne rapport", "search.placeholder": "Søk", "search.search_or_paste": "Søk eller lim inn URL", "search_popout.search_format": "Avansert søkeformat", @@ -592,9 +592,9 @@ "status.uncached_media_warning": "Ikke tilgjengelig", "status.unmute_conversation": "Ikke demp samtale", "status.unpin": "Angre festing på profilen", - "subscribed_languages.lead": "Only posts in selected languages will appear on your home and list timelines after the change. Select none to receive posts in all languages.", - "subscribed_languages.save": "Save changes", - "subscribed_languages.target": "Change subscribed languages for {target}", + "subscribed_languages.lead": "Bare innlegg på valgte språk vil dukke opp i dine hjem- og liste-tidslinjer etter endringen. Velg ingen for å motta innlegg på alle språk.", + "subscribed_languages.save": "Lagre endringer", + "subscribed_languages.target": "Endre abbonerte språk for {target}", "suggestions.dismiss": "Utelukk forslaget", "suggestions.header": "Du er kanskje interessert i …", "tabs_bar.federated_timeline": "Felles", @@ -610,7 +610,7 @@ "timeline_hint.resources.followers": "Følgere", "timeline_hint.resources.follows": "Følger", "timeline_hint.resources.statuses": "Eldre innlegg", - "trends.counter_by_accounts": "{count, plural, one {{counter} person} other {{counter} people}} in the past {days, plural, one {day} other {{days} days}}", + "trends.counter_by_accounts": "{count, plural, one {{counter} person} other {{counter} folk}} {days, plural, one {den siste dagen} other {de siste {days} dagene}}", "trends.trending_now": "Trender nå", "ui.beforeunload": "Din kladd vil bli forkastet om du forlater Mastodon.", "units.short.billion": "{count}m.ard", @@ -629,7 +629,7 @@ "upload_form.video_description": "Beskriv det for folk med hørselstap eller synshemminger", "upload_modal.analyzing_picture": "Analyserer bildet …", "upload_modal.apply": "Bruk", - "upload_modal.applying": "Applying…", + "upload_modal.applying": "Utfører…", "upload_modal.choose_image": "Velg et bilde", "upload_modal.description_placeholder": "Når du en gang kommer, neste sommer, skal vi atter drikke vin", "upload_modal.detect_text": "Oppdag tekst i bildet", @@ -638,7 +638,7 @@ "upload_modal.preparing_ocr": "Forbereder OCR…", "upload_modal.preview_label": "Forhåndsvisning ({ratio})", "upload_progress.label": "Laster opp...", - "upload_progress.processing": "Processing…", + "upload_progress.processing": "Behandler…", "video.close": "Lukk video", "video.download": "Last ned fil", "video.exit_fullscreen": "Lukk fullskjerm", diff --git a/app/javascript/mastodon/locales/pl.json b/app/javascript/mastodon/locales/pl.json index 4728d7286..78b09ca53 100644 --- a/app/javascript/mastodon/locales/pl.json +++ b/app/javascript/mastodon/locales/pl.json @@ -9,7 +9,7 @@ "about.domain_blocks.suspended.explanation": "Żadne dane z tego serwera nie będą przetwarzane, przechowywane lub wymieniane, co uniemożliwia jakąkolwiek interakcję lub komunikację z użytkownikami z tego serwera.", "about.domain_blocks.suspended.title": "Zawieszono", "about.not_available": "Ta informacja nie została udostępniona na tym serwerze.", - "about.powered_by": "Zdecentralizowane media społecznościowe w technologii {mastodon}", + "about.powered_by": "Zdecentralizowane media społecznościowe napędzane przez {mastodon}", "about.rules": "Regulamin serwera", "account.account_note_header": "Notatka", "account.add_or_remove_from_list": "Dodaj lub usuń z list", @@ -336,7 +336,7 @@ "keyboard_shortcuts.start": "aby otworzyć kolumnę „Rozpocznij”", "keyboard_shortcuts.toggle_hidden": "aby wyświetlić lub ukryć wpis spod CW", "keyboard_shortcuts.toggle_sensitivity": "by pokazać/ukryć multimedia", - "keyboard_shortcuts.toot": "aby utworzyć nowy wpis", + "keyboard_shortcuts.toot": "Stwórz nowy post", "keyboard_shortcuts.unfocus": "aby opuścić pole wyszukiwania/pisania", "keyboard_shortcuts.up": "aby przejść na górę listy", "lightbox.close": "Zamknij", diff --git a/app/javascript/mastodon/locales/sk.json b/app/javascript/mastodon/locales/sk.json index bbc1aa0c3..d02fb0bec 100644 --- a/app/javascript/mastodon/locales/sk.json +++ b/app/javascript/mastodon/locales/sk.json @@ -1,16 +1,16 @@ { "about.blocks": "Moderated servers", - "about.contact": "Contact:", + "about.contact": "Kontakt:", "about.disclaimer": "Mastodon is free, open-source software, and a trademark of Mastodon gGmbH.", "about.domain_blocks.no_reason_available": "Reason not available", "about.domain_blocks.preamble": "Mastodon generally allows you to view content from and interact with users from any other server in the fediverse. These are the exceptions that have been made on this particular server.", "about.domain_blocks.silenced.explanation": "You will generally not see profiles and content from this server, unless you explicitly look it up or opt into it by following.", - "about.domain_blocks.silenced.title": "Limited", + "about.domain_blocks.silenced.title": "Obmedzená", "about.domain_blocks.suspended.explanation": "No data from this server will be processed, stored or exchanged, making any interaction or communication with users from this server impossible.", - "about.domain_blocks.suspended.title": "Suspended", + "about.domain_blocks.suspended.title": "Vylúčený/á", "about.not_available": "This information has not been made available on this server.", "about.powered_by": "Decentralized social media powered by {mastodon}", - "about.rules": "Server rules", + "about.rules": "Serverové pravidlá", "account.account_note_header": "Poznámka", "account.add_or_remove_from_list": "Pridaj do, alebo odober zo zoznamov", "account.badges.bot": "Bot", @@ -26,8 +26,8 @@ "account.edit_profile": "Uprav profil", "account.enable_notifications": "Oboznamuj ma, keď má @{name} príspevky", "account.endorse": "Zobrazuj na profile", - "account.featured_tags.last_status_at": "Last post on {date}", - "account.featured_tags.last_status_never": "No posts", + "account.featured_tags.last_status_at": "Posledný príspevok dňa {date}", + "account.featured_tags.last_status_never": "Žiadne príspevky", "account.featured_tags.title": "{name}'s featured hashtags", "account.follow": "Nasleduj", "account.followers": "Sledujúci", @@ -37,9 +37,9 @@ "account.following_counter": "{count, plural, one {{counter} Following} other {{counter} Following}}", "account.follows.empty": "Tento používateľ ešte nikoho nenasleduje.", "account.follows_you": "Nasleduje ťa", - "account.go_to_profile": "Go to profile", + "account.go_to_profile": "Prejdi na profil", "account.hide_reblogs": "Skry vyzdvihnutia od @{name}", - "account.joined_short": "Joined", + "account.joined_short": "Pridal/a sa", "account.languages": "Change subscribed languages", "account.link_verified_on": "Vlastníctvo tohto odkazu bolo skontrolované {date}", "account.locked_info": "Stav súkromia pre tento účet je nastavený na zamknutý. Jeho vlastník sám prehodnocuje, kto ho môže sledovať.", @@ -51,7 +51,7 @@ "account.muted": "Nevšímaný/á", "account.open_original_page": "Open original page", "account.posts": "Príspevky/ov", - "account.posts_with_replies": "Príspevky, aj s odpoveďami", + "account.posts_with_replies": "Príspevky a odpovede", "account.report": "Nahlás @{name}", "account.requested": "Čaká na schválenie. Klikni pre zrušenie žiadosti", "account.share": "Zdieľaj @{name} profil", @@ -84,20 +84,20 @@ "bundle_column_error.error.body": "The requested page could not be rendered. It could be due to a bug in our code, or a browser compatibility issue.", "bundle_column_error.error.title": "Oh, no!", "bundle_column_error.network.body": "There was an error when trying to load this page. This could be due to a temporary problem with your internet connection or this server.", - "bundle_column_error.network.title": "Network error", + "bundle_column_error.network.title": "Chyba siete", "bundle_column_error.retry": "Skús to znova", - "bundle_column_error.return": "Go back home", + "bundle_column_error.return": "Prejdi späť na domovskú stránku", "bundle_column_error.routing.body": "The requested page could not be found. Are you sure the URL in the address bar is correct?", "bundle_column_error.routing.title": "404", "bundle_modal_error.close": "Zatvor", "bundle_modal_error.message": "Nastala chyba pri načítaní tohto komponentu.", "bundle_modal_error.retry": "Skúsiť znova", "closed_registrations.other_server_instructions": "Since Mastodon is decentralized, you can create an account on another server and still interact with this one.", - "closed_registrations_modal.description": "Creating an account on {domain} is currently not possible, but please keep in mind that you do not need an account specifically on {domain} to use Mastodon.", - "closed_registrations_modal.find_another_server": "Find another server", + "closed_registrations_modal.description": "Vytvorenie účtu na {domain} nie je v súčasnosti možné, ale majte prosím na pamäti, že nepotrebujete účet práve na {domain}, aby bolo možné používať Mastodon.", + "closed_registrations_modal.find_another_server": "Nájdi iný server", "closed_registrations_modal.preamble": "Mastodon is decentralized, so no matter where you create your account, you will be able to follow and interact with anyone on this server. You can even self-host it!", - "closed_registrations_modal.title": "Signing up on Mastodon", - "column.about": "About", + "closed_registrations_modal.title": "Registrácia na Mastodon", + "column.about": "O tomto serveri", "column.blocks": "Blokovaní užívatelia", "column.bookmarks": "Záložky", "column.community": "Miestna časová os", @@ -175,13 +175,13 @@ "conversation.mark_as_read": "Označ za prečítané", "conversation.open": "Ukáž konverzáciu", "conversation.with": "S {names}", - "copypaste.copied": "Copied", - "copypaste.copy": "Copy", + "copypaste.copied": "Skopírované", + "copypaste.copy": "Kopíruj", "directory.federated": "Zo známého fedivesmíru", "directory.local": "Iba z {domain}", "directory.new_arrivals": "Nové príchody", "directory.recently_active": "Nedávno aktívne", - "disabled_account_banner.account_settings": "Account settings", + "disabled_account_banner.account_settings": "Nastavenia účtu", "disabled_account_banner.text": "Your account {disabledAccount} is currently disabled.", "dismissable_banner.community_timeline": "These are the most recent public posts from people whose accounts are hosted by {domain}.", "dismissable_banner.dismiss": "Dismiss", @@ -264,10 +264,10 @@ "footer.about": "About", "footer.directory": "Profiles directory", "footer.get_app": "Get the app", - "footer.invite": "Invite people", - "footer.keyboard_shortcuts": "Keyboard shortcuts", - "footer.privacy_policy": "Privacy policy", - "footer.source_code": "View source code", + "footer.invite": "Pozvi ľudí", + "footer.keyboard_shortcuts": "Klávesové skratky", + "footer.privacy_policy": "Zásady súkromia", + "footer.source_code": "Zobraziť zdrojový kód", "generic.saved": "Uložené", "getting_started.heading": "Začni tu", "hashtag.column_header.tag_mode.all": "a {additional}", @@ -290,14 +290,14 @@ "interaction_modal.description.follow": "With an account on Mastodon, you can follow {name} to receive their posts in your home feed.", "interaction_modal.description.reblog": "With an account on Mastodon, you can boost this post to share it with your own followers.", "interaction_modal.description.reply": "With an account on Mastodon, you can respond to this post.", - "interaction_modal.on_another_server": "On a different server", - "interaction_modal.on_this_server": "On this server", + "interaction_modal.on_another_server": "Na inom serveri", + "interaction_modal.on_this_server": "Na tomto serveri", "interaction_modal.other_server_instructions": "Copy and paste this URL into the search field of your favourite Mastodon app or the web interface of your Mastodon server.", "interaction_modal.preamble": "Since Mastodon is decentralized, you can use your existing account hosted by another Mastodon server or compatible platform if you don't have an account on this one.", "interaction_modal.title.favourite": "Favourite {name}'s post", - "interaction_modal.title.follow": "Follow {name}", - "interaction_modal.title.reblog": "Boost {name}'s post", - "interaction_modal.title.reply": "Reply to {name}'s post", + "interaction_modal.title.follow": "Nasleduj {name}", + "interaction_modal.title.reblog": "Vyzdvihni {name}ov/in príspevok", + "interaction_modal.title.reply": "Odpovedz na {name}ov/in príspevok", "intervals.full.days": "{number, plural, one {# deň} few {# dní} many {# dní} other {# dní}}", "intervals.full.hours": "{number, plural, one {# hodina} few {# hodín} many {# hodín} other {# hodín}}", "intervals.full.minutes": "{number, plural, one {# minúta} few {# minút} many {# minút} other {# minút}}", @@ -364,7 +364,7 @@ "mute_modal.duration": "Trvanie", "mute_modal.hide_notifications": "Skry oznámenia od tohto používateľa?", "mute_modal.indefinite": "Bez obmedzenia", - "navigation_bar.about": "About", + "navigation_bar.about": "O tomto serveri", "navigation_bar.blocks": "Blokovaní užívatelia", "navigation_bar.bookmarks": "Záložky", "navigation_bar.community_timeline": "Miestna časová os", @@ -385,7 +385,7 @@ "navigation_bar.pins": "Pripnuté príspevky", "navigation_bar.preferences": "Nastavenia", "navigation_bar.public_timeline": "Federovaná časová os", - "navigation_bar.search": "Search", + "navigation_bar.search": "Hľadaj", "navigation_bar.security": "Zabezbečenie", "not_signed_in_indicator.not_signed_in": "You need to sign in to access this resource.", "notification.admin.report": "{name} nahlásil/a {target}", @@ -455,8 +455,8 @@ "privacy.public.short": "Verejné", "privacy.unlisted.long": "Visible for all, but opted-out of discovery features", "privacy.unlisted.short": "Verejne, ale nezobraziť v osi", - "privacy_policy.last_updated": "Last updated {date}", - "privacy_policy.title": "Privacy Policy", + "privacy_policy.last_updated": "Posledná úprava {date}", + "privacy_policy.title": "Zásady súkromia", "refresh": "Obnoviť", "regeneration_indicator.label": "Načítava sa…", "regeneration_indicator.sublabel": "Tvoja domovská nástenka sa pripravuje!", @@ -532,12 +532,12 @@ "search_results.total": "{count, number} {count, plural, one {výsledok} many {výsledkov} other {výsledky}}", "server_banner.about_active_users": "People using this server during the last 30 days (Monthly Active Users)", "server_banner.active_users": "active users", - "server_banner.administered_by": "Administered by:", + "server_banner.administered_by": "Správcom je:", "server_banner.introduction": "{domain} is part of the decentralized social network powered by {mastodon}.", - "server_banner.learn_more": "Learn more", - "server_banner.server_stats": "Server stats:", - "sign_in_banner.create_account": "Create account", - "sign_in_banner.sign_in": "Sign in", + "server_banner.learn_more": "Zisti viac", + "server_banner.server_stats": "Serverové štatistiky:", + "sign_in_banner.create_account": "Vytvor účet", + "sign_in_banner.sign_in": "Prihlás sa", "sign_in_banner.text": "Sign in to follow profiles or hashtags, favourite, share and reply to posts, or interact from your account on a different server.", "status.admin_account": "Otvor moderovacie rozhranie užívateľa @{name}", "status.admin_status": "Otvor tento príspevok v moderovacom rozhraní", @@ -575,7 +575,7 @@ "status.reblogs.empty": "Nikto ešte nevyzdvihol tento príspevok. Keď tak niekto urobí, bude to zobrazené práve tu.", "status.redraft": "Vymaž a prepíš", "status.remove_bookmark": "Odstráň záložku", - "status.replied_to": "Replied to {name}", + "status.replied_to": "Odpoveď na {name}", "status.reply": "Odpovedať", "status.replyAll": "Odpovedz na diskusiu", "status.report": "Nahlás @{name}", @@ -586,14 +586,14 @@ "status.show_less_all": "Všetkým ukáž menej", "status.show_more": "Ukáž viac", "status.show_more_all": "Všetkým ukáž viac", - "status.show_original": "Show original", - "status.translate": "Translate", + "status.show_original": "Ukáž pôvodný", + "status.translate": "Preložiť", "status.translated_from_with": "Translated from {lang} using {provider}", "status.uncached_media_warning": "Nedostupný/é", "status.unmute_conversation": "Prestaň si nevšímať konverzáciu", "status.unpin": "Odopni z profilu", "subscribed_languages.lead": "Only posts in selected languages will appear on your home and list timelines after the change. Select none to receive posts in all languages.", - "subscribed_languages.save": "Save changes", + "subscribed_languages.save": "Ulož zmeny", "subscribed_languages.target": "Change subscribed languages for {target}", "suggestions.dismiss": "Zavrhni návrh", "suggestions.header": "Mohlo by ťa zaujímať…", diff --git a/app/javascript/mastodon/locales/sq.json b/app/javascript/mastodon/locales/sq.json index cdcca1697..860c0e5a1 100644 --- a/app/javascript/mastodon/locales/sq.json +++ b/app/javascript/mastodon/locales/sq.json @@ -2,7 +2,7 @@ "about.blocks": "Shërbyes të moderuar", "about.contact": "Kontakt:", "about.disclaimer": "Mastodon-i është software i lirë, me burim të hapët dhe shenjë tregtare e Mastodon gGmbH.", - "about.domain_blocks.no_reason_available": "Reason not available", + "about.domain_blocks.no_reason_available": "S’ka arsye", "about.domain_blocks.preamble": "Mastodon-i ju lë përgjithësisht të shihni lëndë prej përdoruesish dhe të ndërveproni me ta nga cilido shërbyes tjetër qofshin në fedivers. Ka përjashtime që janë bërë në këtë shërbyes të dhënë.", "about.domain_blocks.silenced.explanation": "Përgjithësisht s’do të shihni profile dhe lëndë nga ky shërbyes, veç në i kërkofshi shprehimisht apo zgjidhni të bëhet kjo, duke i ndjekur.", "about.domain_blocks.silenced.title": "E kufizuar", @@ -49,7 +49,7 @@ "account.mute": "Heshtoni @{name}", "account.mute_notifications": "Heshtoji njoftimet prej @{name}", "account.muted": "Heshtuar", - "account.open_original_page": "Open original page", + "account.open_original_page": "Hap faqen origjinale", "account.posts": "Mesazhe", "account.posts_with_replies": "Mesazhe dhe përgjigje", "account.report": "Raportojeni @{name}", @@ -292,7 +292,7 @@ "interaction_modal.description.reply": "Me një llogari në Mastodon, mund t’i përgjigjeni këtij postimi.", "interaction_modal.on_another_server": "Në një tjetër shërbyes", "interaction_modal.on_this_server": "Në këtë shërbyes", - "interaction_modal.other_server_instructions": "Copy and paste this URL into the search field of your favourite Mastodon app or the web interface of your Mastodon server.", + "interaction_modal.other_server_instructions": "Kopjojeni dhe ngjiteni këtë URL te fusha e kërkimeve të aplikacionit tuaj të parapëlqyer Mastodon, ose të ndërfaqes web të shërbyesit tuaj Mastodon.", "interaction_modal.preamble": "Ngaqë Mastodon-i është i decentralizuar, mund të përdorni llogarinë tuaj ekzistuese të sterhuar nga një tjetër shërbyes Mastodon, ose platformë e përputhshme, nëse s’keni një llogari në këtë shërbyes.", "interaction_modal.title.favourite": "Parapëlqejeni postimin e {name}", "interaction_modal.title.follow": "Ndiq {name}", diff --git a/app/javascript/mastodon/locales/th.json b/app/javascript/mastodon/locales/th.json index 77279ba01..d6d53d56c 100644 --- a/app/javascript/mastodon/locales/th.json +++ b/app/javascript/mastodon/locales/th.json @@ -4,11 +4,11 @@ "about.disclaimer": "Mastodon เป็นซอฟต์แวร์เสรี โอเพนซอร์ส และเครื่องหมายการค้าของ Mastodon gGmbH", "about.domain_blocks.no_reason_available": "เหตุผลไม่พร้อมใช้งาน", "about.domain_blocks.preamble": "โดยทั่วไป Mastodon อนุญาตให้คุณดูเนื้อหาจากและโต้ตอบกับผู้ใช้จากเซิร์ฟเวอร์อื่นใดในจักรวาลสหพันธ์ นี่คือข้อยกเว้นที่ทำขึ้นในเซิร์ฟเวอร์นี้โดยเฉพาะ", - "about.domain_blocks.silenced.explanation": "You will generally not see profiles and content from this server, unless you explicitly look it up or opt into it by following.", + "about.domain_blocks.silenced.explanation": "โดยทั่วไปคุณจะไม่เห็นโปรไฟล์และเนื้อหาจากเซิร์ฟเวอร์นี้ เว้นแต่คุณจะค้นหาเซิร์ฟเวอร์หรือเลือกรับเซิร์ฟเวอร์โดยการติดตามอย่างชัดเจน", "about.domain_blocks.silenced.title": "จำกัดอยู่", "about.domain_blocks.suspended.explanation": "จะไม่ประมวลผล จัดเก็บ หรือแลกเปลี่ยนข้อมูลจากเซิร์ฟเวอร์นี้ ทำให้การโต้ตอบหรือการสื่อสารใด ๆ กับผู้ใช้จากเซิร์ฟเวอร์นี้เป็นไปไม่ได้", "about.domain_blocks.suspended.title": "ระงับอยู่", - "about.not_available": "This information has not been made available on this server.", + "about.not_available": "ไม่ได้ทำให้ข้อมูลนี้พร้อมใช้งานในเซิร์ฟเวอร์นี้", "about.powered_by": "สื่อสังคมแบบกระจายศูนย์ที่ขับเคลื่อนโดย {mastodon}", "about.rules": "กฎของเซิร์ฟเวอร์", "account.account_note_header": "หมายเหตุ", @@ -93,9 +93,9 @@ "bundle_modal_error.message": "มีบางอย่างผิดพลาดขณะโหลดส่วนประกอบนี้", "bundle_modal_error.retry": "ลองอีกครั้ง", "closed_registrations.other_server_instructions": "เนื่องจาก Mastodon เป็นแบบกระจายศูนย์ คุณสามารถสร้างบัญชีในเซิร์ฟเวอร์อื่นและยังคงโต้ตอบกับเซิร์ฟเวอร์นี้", - "closed_registrations_modal.description": "Creating an account on {domain} is currently not possible, but please keep in mind that you do not need an account specifically on {domain} to use Mastodon.", + "closed_registrations_modal.description": "ไม่สามารถสร้างบัญชีใน {domain} ได้ในปัจจุบัน แต่โปรดจำไว้ว่าคุณไม่จำเป็นต้องมีบัญชีใน {domain} โดยเฉพาะเพื่อใช้ Mastodon", "closed_registrations_modal.find_another_server": "ค้นหาเซิร์ฟเวอร์อื่น", - "closed_registrations_modal.preamble": "Mastodon is decentralized, so no matter where you create your account, you will be able to follow and interact with anyone on this server. You can even self-host it!", + "closed_registrations_modal.preamble": "Mastodon เป็นแบบกระจายศูนย์ ดังนั้นไม่ว่าคุณจะสร้างบัญชีของคุณที่ใด คุณจะสามารถติดตามและโต้ตอบกับใครก็ตามในเซิร์ฟเวอร์นี้ คุณยังสามารถโฮสต์บัญชีด้วยตนเองได้อีกด้วย!", "closed_registrations_modal.title": "การลงทะเบียนใน Mastodon", "column.about": "เกี่ยวกับ", "column.blocks": "ผู้ใช้ที่ปิดกั้นอยู่", @@ -127,7 +127,7 @@ "compose.language.search": "ค้นหาภาษา...", "compose_form.direct_message_warning_learn_more": "เรียนรู้เพิ่มเติม", "compose_form.encryption_warning": "โพสต์ใน Mastodon ไม่ได้เข้ารหัสแบบต้นทางถึงปลายทาง อย่าแบ่งปันข้อมูลที่ละเอียดอ่อนใด ๆ ผ่าน Mastodon", - "compose_form.hashtag_warning": "จะไม่แสดงรายการโพสต์นี้ภายใต้แฮชแท็กใด ๆ เนื่องจากไม่อยู่ในรายการ เฉพาะโพสต์สาธารณะเท่านั้นที่สามารถค้นหาได้โดยแฮชแท็ก", + "compose_form.hashtag_warning": "จะไม่แสดงรายการโพสต์นี้ภายใต้แฮชแท็กใด ๆ เนื่องจากโพสต์ไม่อยู่ในรายการ เฉพาะโพสต์สาธารณะเท่านั้นที่สามารถค้นหาได้โดยแฮชแท็ก", "compose_form.lock_disclaimer": "บัญชีของคุณไม่ได้ {locked} ใครก็ตามสามารถติดตามคุณเพื่อดูโพสต์สำหรับผู้ติดตามเท่านั้นของคุณ", "compose_form.lock_disclaimer.lock": "ล็อคอยู่", "compose_form.placeholder": "คุณกำลังคิดอะไรอยู่?", @@ -239,7 +239,7 @@ "explore.trending_links": "ข่าว", "explore.trending_statuses": "โพสต์", "explore.trending_tags": "แฮชแท็ก", - "filter_modal.added.context_mismatch_explanation": "This filter category does not apply to the context in which you have accessed this post. If you want the post to be filtered in this context too, you will have to edit the filter.", + "filter_modal.added.context_mismatch_explanation": "หมวดหมู่ตัวกรองนี้ไม่ได้นำไปใช้กับบริบทที่คุณได้เข้าถึงโพสต์นี้ หากคุณต้องการกรองโพสต์ในบริบทนี้ด้วย คุณจะต้องแก้ไขตัวกรอง", "filter_modal.added.context_mismatch_title": "บริบทไม่ตรงกัน!", "filter_modal.added.expired_explanation": "หมวดหมู่ตัวกรองนี้หมดอายุแล้ว คุณจะต้องเปลี่ยนวันหมดอายุสำหรับหมวดหมู่เพื่อนำไปใช้", "filter_modal.added.expired_title": "ตัวกรองหมดอายุแล้ว!", @@ -496,7 +496,7 @@ "report.reasons.spam": "โพสต์เป็นสแปม", "report.reasons.spam_description": "ลิงก์ที่เป็นอันตราย, การมีส่วนร่วมปลอม หรือการตอบกลับซ้ำ ๆ", "report.reasons.violation": "โพสต์ละเมิดกฎของเซิร์ฟเวอร์", - "report.reasons.violation_description": "คุณทราบว่าโพสต์แหกกฎเฉพาะ", + "report.reasons.violation_description": "คุณตระหนักว่าโพสต์แหกกฎเฉพาะ", "report.rules.subtitle": "เลือกทั้งหมดที่นำไปใช้", "report.rules.title": "กำลังละเมิดกฎใด?", "report.statuses.subtitle": "เลือกทั้งหมดที่นำไปใช้", diff --git a/app/javascript/mastodon/locales/tr.json b/app/javascript/mastodon/locales/tr.json index 1ed5e5872..9dd5aef76 100644 --- a/app/javascript/mastodon/locales/tr.json +++ b/app/javascript/mastodon/locales/tr.json @@ -2,7 +2,7 @@ "about.blocks": "Denetlenen sunucular", "about.contact": "İletişim:", "about.disclaimer": "Mastodon özgür, açık kaynak bir yazılımdır ve Mastodon gGmbH şirketinin ticari markasıdır.", - "about.domain_blocks.no_reason_available": "Grerekçe mevcut değil", + "about.domain_blocks.no_reason_available": "Gerekçe mevcut değil", "about.domain_blocks.preamble": "Mastodon, genel olarak fediverse'teki herhangi bir sunucudan içerik görüntülemenize ve kullanıcılarıyla etkileşim kurmanıza izin verir. Bunlar, bu sunucuda yapılmış olan istisnalardır.", "about.domain_blocks.silenced.explanation": "Açık bir şekilde aramadığınız veya takip ederek abone olmadığınız sürece, bu sunucudaki profilleri veya içerikleri genelde göremeyeceksiniz.", "about.domain_blocks.silenced.title": "Sınırlı", diff --git a/app/javascript/mastodon/reducers/compose.js b/app/javascript/mastodon/reducers/compose.js index afb8b40c1..8cc7bf520 100644 --- a/app/javascript/mastodon/reducers/compose.js +++ b/app/javascript/mastodon/reducers/compose.js @@ -436,7 +436,7 @@ export default function compose(state = initialState, action) { .setIn(['media_modal', 'dirty'], false) .update('media_attachments', list => list.map(item => { if (item.get('id') === action.media.id) { - return fromJS(action.media); + return fromJS(action.media).set('unattached', true); } return item; diff --git a/app/javascript/styles/mastodon/components.scss b/app/javascript/styles/mastodon/components.scss index 2c339ffef..24e2aed5d 100644 --- a/app/javascript/styles/mastodon/components.scss +++ b/app/javascript/styles/mastodon/components.scss @@ -964,7 +964,7 @@ } .status__content.status__content--collapsed { - max-height: 20px * 15; // 15 lines is roughly above 500 characters + max-height: 22px * 15; // 15 lines is roughly above 500 characters } .status__content__read-more-button { @@ -1869,9 +1869,6 @@ a.account__display-name { a { color: inherit; - } - - .permalink { text-decoration: none; } @@ -7026,8 +7023,11 @@ noscript { &__tabs { display: flex; align-items: flex-start; + justify-content: space-between; margin-top: -55px; padding-top: 10px; + gap: 8px; + overflow: hidden; &__buttons { display: flex; @@ -7036,6 +7036,15 @@ noscript { padding-top: 55px; overflow: hidden; + .button { + flex-shrink: 1; + white-space: nowrap; + + @media screen and (max-width: $no-gap-breakpoint) { + min-width: 0; + } + } + .icon-button { border: 1px solid lighten($ui-base-color, 12%); border-radius: 4px; diff --git a/app/javascript/styles/mastodon/tables.scss b/app/javascript/styles/mastodon/tables.scss index 39211910f..b644b38f1 100644 --- a/app/javascript/styles/mastodon/tables.scss +++ b/app/javascript/styles/mastodon/tables.scss @@ -178,6 +178,9 @@ a.table-action-link { } &__toolbar { + position: sticky; + top: 0; + z-index: 1; border: 1px solid darken($ui-base-color, 8%); background: $ui-base-color; border-radius: 4px 0 0; diff --git a/app/lib/emoji_formatter.rb b/app/lib/emoji_formatter.rb index 194849c23..a9785d5f9 100644 --- a/app/lib/emoji_formatter.rb +++ b/app/lib/emoji_formatter.rb @@ -23,48 +23,40 @@ class EmojiFormatter def to_s return html if custom_emojis.empty? || html.blank? - i = -1 - tag_open_index = nil - inside_shortname = false - shortname_start_index = -1 - invisible_depth = 0 - last_index = 0 - result = ''.dup - - while i + 1 < html.size - i += 1 - - if invisible_depth.zero? && inside_shortname && html[i] == ':' - inside_shortname = false - shortcode = html[shortname_start_index + 1..i - 1] - char_after = html[i + 1] - - next unless (char_after.nil? || !DISALLOWED_BOUNDING_REGEX.match?(char_after)) && (emoji = emoji_map[shortcode]) - - result << html[last_index..shortname_start_index - 1] if shortname_start_index.positive? - result << image_for_emoji(shortcode, emoji) - last_index = i + 1 - elsif tag_open_index && html[i] == '>' - tag = html[tag_open_index..i] - tag_open_index = nil - - if invisible_depth.positive? - invisible_depth += count_tag_nesting(tag) - elsif tag == '<span class="invisible">' - invisible_depth = 1 + tree = Nokogiri::HTML.fragment(html) + tree.xpath('./text()|.//text()[not(ancestor[@class="invisible"])]').to_a.each do |node| + i = -1 + inside_shortname = false + shortname_start_index = -1 + last_index = 0 + text = node.content + result = Nokogiri::XML::NodeSet.new(tree.document) + + while i + 1 < text.size + i += 1 + + if inside_shortname && text[i] == ':' + inside_shortname = false + shortcode = text[shortname_start_index + 1..i - 1] + char_after = text[i + 1] + + next unless (char_after.nil? || !DISALLOWED_BOUNDING_REGEX.match?(char_after)) && (emoji = emoji_map[shortcode]) + + result << Nokogiri::XML::Text.new(text[last_index..shortname_start_index - 1], tree.document) if shortname_start_index.positive? + result << Nokogiri::HTML.fragment(image_for_emoji(shortcode, emoji)) + + last_index = i + 1 + elsif text[i] == ':' && (i.zero? || !DISALLOWED_BOUNDING_REGEX.match?(text[i - 1])) + inside_shortname = true + shortname_start_index = i end - elsif html[i] == '<' - tag_open_index = i - inside_shortname = false - elsif !tag_open_index && html[i] == ':' && (i.zero? || !DISALLOWED_BOUNDING_REGEX.match?(html[i - 1])) - inside_shortname = true - shortname_start_index = i end - end - result << html[last_index..-1] + result << Nokogiri::XML::Text.new(text[last_index..-1], tree.document) + node.replace(result) + end - result.html_safe # rubocop:disable Rails/OutputSafety + tree.to_html.html_safe # rubocop:disable Rails/OutputSafety end private diff --git a/app/models/account_filter.rb b/app/models/account_filter.rb index e214e0bad..e09ce4ec2 100644 --- a/app/models/account_filter.rb +++ b/app/models/account_filter.rb @@ -57,7 +57,7 @@ class AccountFilter when 'order' order_scope(value) else - raise "Unknown filter: #{key}" + raise Mastodon::InvalidParameterError, "Unknown filter: #{key}" end end @@ -68,7 +68,7 @@ class AccountFilter when 'remote' Account.remote else - raise "Unknown origin: #{value}" + raise Mastodon::InvalidParameterError, "Unknown origin: #{value}" end end @@ -84,8 +84,10 @@ class AccountFilter accounts_with_users.merge(User.disabled) when 'silenced' Account.silenced + when 'sensitized' + Account.sensitized else - raise "Unknown status: #{value}" + raise Mastodon::InvalidParameterError, "Unknown status: #{value}" end end @@ -96,7 +98,7 @@ class AccountFilter when 'recent' Account.recent else - raise "Unknown order: #{value}" + raise Mastodon::InvalidParameterError, "Unknown order: #{value}" end end diff --git a/app/models/admin/action_log_filter.rb b/app/models/admin/action_log_filter.rb index edb391e2e..f89d452ef 100644 --- a/app/models/admin/action_log_filter.rb +++ b/app/models/admin/action_log_filter.rb @@ -95,7 +95,7 @@ class Admin::ActionLogFilter account = Account.find_or_initialize_by(id: value) Admin::ActionLog.where(target: [account, account.user].compact) else - raise "Unknown filter: #{key}" + raise Mastodon::InvalidParameterError, "Unknown filter: #{key}" end end end diff --git a/app/models/admin/appeal_filter.rb b/app/models/admin/appeal_filter.rb index b163d2e56..f5dcc0f54 100644 --- a/app/models/admin/appeal_filter.rb +++ b/app/models/admin/appeal_filter.rb @@ -30,7 +30,7 @@ class Admin::AppealFilter when 'status' status_scope(value) else - raise "Unknown filter: #{key}" + raise Mastodon::InvalidParameterError, "Unknown filter: #{key}" end end @@ -43,7 +43,7 @@ class Admin::AppealFilter when 'pending' Appeal.pending else - raise "Unknown status: #{value}" + raise Mastodon::InvalidParameterError, "Unknown status: #{value}" end end end diff --git a/app/models/admin/status_filter.rb b/app/models/admin/status_filter.rb index d7a16f760..4d439e9a1 100644 --- a/app/models/admin/status_filter.rb +++ b/app/models/admin/status_filter.rb @@ -32,7 +32,7 @@ class Admin::StatusFilter when 'media' Status.joins(:media_attachments).merge(@account.media_attachments.reorder(nil)).group(:id).reorder('statuses.id desc') else - raise "Unknown filter: #{key}" + raise Mastodon::InvalidParameterError, "Unknown filter: #{key}" end end end diff --git a/app/models/announcement_filter.rb b/app/models/announcement_filter.rb index 950852460..85c3b1d2c 100644 --- a/app/models/announcement_filter.rb +++ b/app/models/announcement_filter.rb @@ -33,7 +33,7 @@ class AnnouncementFilter when 'unpublished' Announcement.unpublished else - raise "Unknown filter: #{key}" + raise Mastodon::InvalidParameterError, "Unknown filter: #{key}" end end end diff --git a/app/models/concerns/domain_normalizable.rb b/app/models/concerns/domain_normalizable.rb index fb84058fc..8e244c1d8 100644 --- a/app/models/concerns/domain_normalizable.rb +++ b/app/models/concerns/domain_normalizable.rb @@ -11,5 +11,7 @@ module DomainNormalizable def normalize_domain self.domain = TagManager.instance.normalize_domain(domain&.strip) + rescue Addressable::URI::InvalidURIError + errors.add(:domain, :invalid) end end diff --git a/app/models/custom_emoji_filter.rb b/app/models/custom_emoji_filter.rb index 414e1fcdd..ed7a8dda1 100644 --- a/app/models/custom_emoji_filter.rb +++ b/app/models/custom_emoji_filter.rb @@ -39,7 +39,7 @@ class CustomEmojiFilter when 'shortcode' CustomEmoji.search(value.strip) else - raise "Unknown filter: #{key}" + raise Mastodon::InvalidParameterError, "Unknown filter: #{key}" end end end diff --git a/app/models/instance_filter.rb b/app/models/instance_filter.rb index e7e5166a1..1d94c919f 100644 --- a/app/models/instance_filter.rb +++ b/app/models/instance_filter.rb @@ -36,7 +36,7 @@ class InstanceFilter when 'availability' availability_scope(value) else - raise "Unknown filter: #{key}" + raise Mastodon::InvalidParameterError, "Unknown filter: #{key}" end end @@ -47,7 +47,7 @@ class InstanceFilter when 'unavailable' Instance.joins(:unavailable_domain) else - raise "Unknown availability: #{value}" + raise Mastodon::InvalidParameterError, "Unknown availability: #{value}" end end end diff --git a/app/models/invite_filter.rb b/app/models/invite_filter.rb index 9685d4abb..c1edb3871 100644 --- a/app/models/invite_filter.rb +++ b/app/models/invite_filter.rb @@ -31,7 +31,7 @@ class InviteFilter when 'expired' Invite.expired else - raise "Unknown filter: #{key}" + raise Mastodon::InvalidParameterError, "Unknown filter: #{key}" end end end diff --git a/app/models/media_attachment.rb b/app/models/media_attachment.rb index 2bab8c0b6..6f079dd18 100644 --- a/app/models/media_attachment.rb +++ b/app/models/media_attachment.rb @@ -82,6 +82,7 @@ class MediaAttachment < ApplicationRecord IMAGE_CONVERTED_STYLES = { original: { format: 'jpeg', + content_type: 'image/jpeg', }.merge(IMAGE_STYLES[:original]).freeze, small: { diff --git a/app/models/relationship_filter.rb b/app/models/relationship_filter.rb index 9135ff144..249fe3df8 100644 --- a/app/models/relationship_filter.rb +++ b/app/models/relationship_filter.rb @@ -53,7 +53,7 @@ class RelationshipFilter when 'activity' activity_scope(value) else - raise "Unknown filter: #{key}" + raise Mastodon::InvalidParameterError, "Unknown filter: #{key}" end end @@ -68,7 +68,7 @@ class RelationshipFilter when 'invited' Account.joins(user: :invite).merge(Invite.where(user: account.user)).eager_load(:account_stat).reorder(nil) else - raise "Unknown relationship: #{value}" + raise Mastodon::InvalidParameterError, "Unknown relationship: #{value}" end end @@ -83,7 +83,7 @@ class RelationshipFilter when 'remote' Account.remote else - raise "Unknown location: #{value}" + raise Mastodon::InvalidParameterError, "Unknown location: #{value}" end end @@ -94,7 +94,7 @@ class RelationshipFilter when 'primary' Account.where(moved_to_account_id: nil) else - raise "Unknown status: #{value}" + raise Mastodon::InvalidParameterError, "Unknown status: #{value}" end end @@ -105,7 +105,7 @@ class RelationshipFilter when 'recent' params[:relationship] == 'invited' ? Account.recent : Follow.recent else - raise "Unknown order: #{value}" + raise Mastodon::InvalidParameterError, "Unknown order: #{value}" end end @@ -114,7 +114,7 @@ class RelationshipFilter when 'dormant' AccountStat.where(last_status_at: nil).or(AccountStat.where(AccountStat.arel_table[:last_status_at].lt(1.month.ago))) else - raise "Unknown activity: #{value}" + raise Mastodon::InvalidParameterError, "Unknown activity: #{value}" end end end diff --git a/app/models/report_filter.rb b/app/models/report_filter.rb index dc444a552..c9b3bce2d 100644 --- a/app/models/report_filter.rb +++ b/app/models/report_filter.rb @@ -38,7 +38,7 @@ class ReportFilter when :target_origin target_origin_scope(value) else - raise "Unknown filter: #{key}" + raise Mastodon::InvalidParameterError, "Unknown filter: #{key}" end end @@ -49,7 +49,7 @@ class ReportFilter when :remote Report.where(target_account: Account.remote) else - raise "Unknown value: #{value}" + raise Mastodon::InvalidParameterError, "Unknown value: #{value}" end end end diff --git a/app/models/rule.rb b/app/models/rule.rb index 7b62f2b35..602e5d587 100644 --- a/app/models/rule.rb +++ b/app/models/rule.rb @@ -18,5 +18,5 @@ class Rule < ApplicationRecord validates :text, presence: true, length: { maximum: 300 } - scope :ordered, -> { kept.order(priority: :asc) } + scope :ordered, -> { kept.order(priority: :asc, id: :asc) } end diff --git a/app/models/trends/preview_card_filter.rb b/app/models/trends/preview_card_filter.rb index 0a81146d4..f0214c3f0 100644 --- a/app/models/trends/preview_card_filter.rb +++ b/app/models/trends/preview_card_filter.rb @@ -40,7 +40,7 @@ class Trends::PreviewCardFilter when 'locale' PreviewCardTrend.where(language: value) else - raise "Unknown filter: #{key}" + raise Mastodon::InvalidParameterError, "Unknown filter: #{key}" end end diff --git a/app/models/trends/preview_card_provider_filter.rb b/app/models/trends/preview_card_provider_filter.rb index abfdd07e8..219793f01 100644 --- a/app/models/trends/preview_card_provider_filter.rb +++ b/app/models/trends/preview_card_provider_filter.rb @@ -30,7 +30,7 @@ class Trends::PreviewCardProviderFilter when 'status' status_scope(value) else - raise "Unknown filter: #{key}" + raise Mastodon::InvalidParameterError, "Unknown filter: #{key}" end end @@ -43,7 +43,7 @@ class Trends::PreviewCardProviderFilter when 'pending_review' PreviewCardProvider.pending_review else - raise "Unknown status: #{value}" + raise Mastodon::InvalidParameterError, "Unknown status: #{value}" end end end diff --git a/app/models/trends/status_filter.rb b/app/models/trends/status_filter.rb index cb0f75d67..de435a026 100644 --- a/app/models/trends/status_filter.rb +++ b/app/models/trends/status_filter.rb @@ -40,7 +40,7 @@ class Trends::StatusFilter when 'locale' StatusTrend.where(language: value) else - raise "Unknown filter: #{key}" + raise Mastodon::InvalidParameterError, "Unknown filter: #{key}" end end diff --git a/app/services/import_service.rb b/app/services/import_service.rb index ece5b9ef0..2f48abc36 100644 --- a/app/services/import_service.rb +++ b/app/services/import_service.rb @@ -136,7 +136,7 @@ class ImportService < BaseService end def import_data - Paperclip.io_adapters.for(@import.data).read + Paperclip.io_adapters.for(@import.data).read.force_encoding(Encoding::UTF_8) end def relations_map_for_account(account, account_ids) diff --git a/app/views/admin/announcements/edit.html.haml b/app/views/admin/announcements/edit.html.haml index 0f9727014..fa69c6fab 100644 --- a/app/views/admin/announcements/edit.html.haml +++ b/app/views/admin/announcements/edit.html.haml @@ -1,7 +1,7 @@ - content_for :page_title do = t('.title') -= simple_form_for @announcement, url: admin_announcement_path(@announcement) do |f| += simple_form_for @announcement, url: admin_announcement_path(@announcement), html: { novalidate: false } do |f| = render 'shared/error_messages', object: @announcement .fields-group diff --git a/app/views/admin/announcements/new.html.haml b/app/views/admin/announcements/new.html.haml index b2f0c01ec..cb39672e1 100644 --- a/app/views/admin/announcements/new.html.haml +++ b/app/views/admin/announcements/new.html.haml @@ -1,7 +1,7 @@ - content_for :page_title do = t('.title') -= simple_form_for @announcement, url: admin_announcements_path do |f| += simple_form_for @announcement, url: admin_announcements_path, html: { novalidate: false } do |f| = render 'shared/error_messages', object: @announcement .fields-group diff --git a/app/views/admin/settings/registrations/show.html.haml b/app/views/admin/settings/registrations/show.html.haml index 0d7d49dc8..455fa5eca 100644 --- a/app/views/admin/settings/registrations/show.html.haml +++ b/app/views/admin/settings/registrations/show.html.haml @@ -5,7 +5,7 @@ %h2= t('admin.settings.title') = render partial: 'admin/settings/shared/links' -= simple_form_for @admin_settings, url: admin_settings_branding_path, html: { method: :patch } do |f| += simple_form_for @admin_settings, url: admin_settings_registrations_path, html: { method: :patch } do |f| = render 'shared/error_messages', object: @admin_settings %p.lead= t('admin.settings.registrations.preamble') diff --git a/config/initializers/paperclip.rb b/config/initializers/paperclip.rb index 26b0a2f7c..a2285427c 100644 --- a/config/initializers/paperclip.rb +++ b/config/initializers/paperclip.rb @@ -67,6 +67,12 @@ if ENV['S3_ENABLED'] == 'true' retry_limit: 0, } ) + + if ENV['S3_PERMISSION'] == '' + Paperclip::Attachment.default_options.merge!( + s3_permissions: ->(*) { nil } + ) + end if ENV.has_key?('S3_ENDPOINT') Paperclip::Attachment.default_options[:s3_options].merge!( @@ -119,6 +125,8 @@ elsif ENV['SWIFT_ENABLED'] == 'true' openstack_region: ENV['SWIFT_REGION'], openstack_cache_ttl: ENV.fetch('SWIFT_CACHE_TTL') { 60 }, }, + + fog_file: { 'Cache-Control' => 'public, max-age=315576000, immutable' }, fog_directory: ENV['SWIFT_CONTAINER'], fog_host: ENV['SWIFT_OBJECT_URL'], diff --git a/config/initializers/rack_attack.rb b/config/initializers/rack_attack.rb index 745eb5d3b..72ef7ba80 100644 --- a/config/initializers/rack_attack.rb +++ b/config/initializers/rack_attack.rb @@ -17,6 +17,18 @@ class Rack::Attack @remote_ip ||= (@env["action_dispatch.remote_ip"] || ip).to_s end + def throttleable_remote_ip + @throttleable_remote_ip ||= begin + ip = IPAddr.new(remote_ip) + + if ip.ipv6? + ip.mask(64) + else + ip + end + end.to_s + end + def authenticated_user_id authenticated_token&.resource_owner_id end @@ -29,6 +41,10 @@ class Rack::Attack path.start_with?('/api') end + def path_matches?(other_path) + /\A#{Regexp.escape(other_path)}(\..*)?\z/ =~ path + end + def web_request? !api_request? end @@ -51,19 +67,19 @@ class Rack::Attack end throttle('throttle_unauthenticated_api', limit: 300, period: 5.minutes) do |req| - req.remote_ip if req.api_request? && req.unauthenticated? + req.throttleable_remote_ip if req.api_request? && req.unauthenticated? end throttle('throttle_api_media', limit: 30, period: 30.minutes) do |req| - req.authenticated_user_id if req.post? && req.path.match?('^/api/v\d+/media') + req.authenticated_user_id if req.post? && req.path.match?(/\A\/api\/v\d+\/media\z/i) end throttle('throttle_media_proxy', limit: 30, period: 10.minutes) do |req| - req.remote_ip if req.path.start_with?('/media_proxy') + req.throttleable_remote_ip if req.path.start_with?('/media_proxy') end throttle('throttle_api_sign_up', limit: 5, period: 30.minutes) do |req| - req.remote_ip if req.post? && req.path == '/api/v1/accounts' + req.throttleable_remote_ip if req.post? && req.path == '/api/v1/accounts' end throttle('throttle_authenticated_paging', limit: 300, period: 15.minutes) do |req| @@ -71,39 +87,34 @@ class Rack::Attack end throttle('throttle_unauthenticated_paging', limit: 300, period: 15.minutes) do |req| - req.remote_ip if req.paging_request? && req.unauthenticated? + req.throttleable_remote_ip if req.paging_request? && req.unauthenticated? end - API_DELETE_REBLOG_REGEX = /\A\/api\/v1\/statuses\/[\d]+\/unreblog/.freeze - API_DELETE_STATUS_REGEX = /\A\/api\/v1\/statuses\/[\d]+/.freeze + API_DELETE_REBLOG_REGEX = /\A\/api\/v1\/statuses\/[\d]+\/unreblog\z/.freeze + API_DELETE_STATUS_REGEX = /\A\/api\/v1\/statuses\/[\d]+\z/.freeze throttle('throttle_api_delete', limit: 30, period: 30.minutes) do |req| req.authenticated_user_id if (req.post? && req.path.match?(API_DELETE_REBLOG_REGEX)) || (req.delete? && req.path.match?(API_DELETE_STATUS_REGEX)) end throttle('throttle_sign_up_attempts/ip', limit: 25, period: 5.minutes) do |req| - if req.post? && req.path == '/auth' - addr = req.remote_ip - addr = IPAddr.new(addr) if addr.is_a?(String) - addr = addr.mask(64) if addr.ipv6? - addr.to_s - end + req.throttleable_remote_ip if req.post? && req.path_matches?('/auth') end throttle('throttle_password_resets/ip', limit: 25, period: 5.minutes) do |req| - req.remote_ip if req.post? && req.path == '/auth/password' + req.throttleable_remote_ip if req.post? && req.path_matches?('/auth/password') end throttle('throttle_password_resets/email', limit: 5, period: 30.minutes) do |req| - req.params.dig('user', 'email').presence if req.post? && req.path == '/auth/password' + req.params.dig('user', 'email').presence if req.post? && req.path_matches?('/auth/password') end throttle('throttle_email_confirmations/ip', limit: 25, period: 5.minutes) do |req| - req.remote_ip if req.post? && %w(/auth/confirmation /api/v1/emails/confirmations).include?(req.path) + req.throttleable_remote_ip if req.post? && (req.path_matches?('/auth/confirmation') || req.path == '/api/v1/emails/confirmations') end throttle('throttle_email_confirmations/email', limit: 5, period: 30.minutes) do |req| - if req.post? && req.path == '/auth/password' + if req.post? && req.path_matches?('/auth/password') req.params.dig('user', 'email').presence elsif req.post? && req.path == '/api/v1/emails/confirmations' req.authenticated_user_id @@ -111,11 +122,11 @@ class Rack::Attack end throttle('throttle_login_attempts/ip', limit: 25, period: 5.minutes) do |req| - req.remote_ip if req.post? && req.path == '/auth/sign_in' + req.throttleable_remote_ip if req.post? && req.path_matches?('/auth/sign_in') end throttle('throttle_login_attempts/email', limit: 25, period: 1.hour) do |req| - req.session[:attempt_user_id] || req.params.dig('user', 'email').presence if req.post? && req.path == '/auth/sign_in' + req.session[:attempt_user_id] || req.params.dig('user', 'email').presence if req.post? && req.path_matches?('/auth/sign_in') end self.throttled_responder = lambda do |request| diff --git a/config/locales/activerecord.ru.yml b/config/locales/activerecord.ru.yml index fb8c6dde5..17b13fc7b 100644 --- a/config/locales/activerecord.ru.yml +++ b/config/locales/activerecord.ru.yml @@ -29,6 +29,10 @@ ru: attributes: website: invalid: не является допустимым URL + import: + attributes: + data: + malformed: неверный формат status: attributes: reblog: diff --git a/config/locales/af.yml b/config/locales/af.yml index 72b1b3c08..0903af744 100644 --- a/config/locales/af.yml +++ b/config/locales/af.yml @@ -27,6 +27,11 @@ af: back_to_limited: Beperk moderation: limited: Beperk + roles: + categories: + devops: DevOps + privileges: + view_devops: DevOps settings: about: title: Aangaande @@ -109,6 +114,13 @@ af: descriptions: account: Publieke plasings vanaf @%{acct} tag: 'Publieke plasings met die #%{hashtag} etiket' + sessions: + browsers: + blackberry: BlackBerry + uc_browser: UC Browser + platforms: + blackberry: BlackBerry + chrome_os: ChromeOS settings: edit_profile: Redigeer profiel preferences: Voorkeure diff --git a/config/locales/ar.yml b/config/locales/ar.yml index 2e5c82a33..278fc52e6 100644 --- a/config/locales/ar.yml +++ b/config/locales/ar.yml @@ -609,7 +609,6 @@ ar: manage_user_access: إدارة وصول المستخدم manage_users: إدارة المستخدمين view_dashboard: عرض لوحة التحكم - view_devops: DevOps view_devops_description: السماح للمستخدمين بالوصول إلى لوحة Sidekiq و pgHero title: الأدوار rules: @@ -1231,7 +1230,6 @@ ar: browser: المتصفح browsers: alipay: أليباي - blackberry: بلاك بيري chrome: كروم edge: مايكروسوفت إيدج electron: إلكترون @@ -1245,7 +1243,6 @@ ar: phantom_js: فانتوم جي آس qq: متصفح كيوكيو safari: سفاري - uc_browser: متصفح يوسي براوزر weibo: وايبو current_session: الجلسة الحالية description: "%{browser} على %{platform}" @@ -1254,8 +1251,6 @@ ar: platforms: adobe_air: أدوبي إيير android: أندرويد - blackberry: بلاك بيري - chrome_os: نظام كروم أواس firefox_os: نظام فايرفكس أواس ios: نظام آي أواس linux: لينكس diff --git a/config/locales/ast.yml b/config/locales/ast.yml index 18aa48947..acbdeb655 100644 --- a/config/locales/ast.yml +++ b/config/locales/ast.yml @@ -325,7 +325,6 @@ ast: browser: Restolador browsers: alipay: Alipay - blackberry: Blackberry chrome: Chrome edge: Microsoft Edge electron: Electron @@ -336,7 +335,6 @@ ast: opera: Opera otter: Otter phantom_js: PhantomJS - uc_browser: UCBrowser weibo: Weibo current_session: Sesión actual description: "%{browser} en %{platform}" @@ -344,8 +342,6 @@ ast: platforms: adobe_air: Adobe Air android: Android - blackberry: Blackberry - chrome_os: Chrome OS firefox_os: Firefox OS ios: iOS linux: GNU/Linux diff --git a/config/locales/bg.yml b/config/locales/bg.yml index 104e256a0..c0287923f 100644 --- a/config/locales/bg.yml +++ b/config/locales/bg.yml @@ -602,7 +602,6 @@ bg: browser: Браузър browsers: alipay: Alipay - blackberry: Blackberry chrome: Chrome edge: Edge на Майкрософт electron: Electron @@ -616,7 +615,6 @@ bg: phantom_js: PhantomJS qq: Браузър QQ safari: Сафари - uc_browser: UCBrowser weibo: Weibo current_session: Текуща сесия description: "%{browser} на %{platform}" @@ -624,8 +622,6 @@ bg: platforms: adobe_air: Adobe Air android: Android - blackberry: Blackberry - chrome_os: Оп. сист. Chrome firefox_os: Оп. сист. Firefox ios: iOS linux: Линукс diff --git a/config/locales/br.yml b/config/locales/br.yml index a6b971eb7..e7bc88eab 100644 --- a/config/locales/br.yml +++ b/config/locales/br.yml @@ -249,7 +249,6 @@ br: browser: Merdeer browsers: alipay: Alipay - blackberry: Blackberry chrome: Chrome edge: Microsoft Edge electron: Electron @@ -263,7 +262,6 @@ br: phantom_js: PhantomJS qq: QQ Browser safari: Safari - uc_browser: UCBrowser weibo: Weibo description: "%{browser} war %{platform}" platforms: diff --git a/config/locales/ca.yml b/config/locales/ca.yml index b75af2463..1652ab8ee 100644 --- a/config/locales/ca.yml +++ b/config/locales/ca.yml @@ -1097,7 +1097,7 @@ ca: public: Línies de temps públiques thread: Converses edit: - add_keyword: Afegeix paraula clau + add_keyword: Afegeix una paraula clau keywords: Paraules clau statuses: Publicacions individuals statuses_hint_html: Aquest filtre s'aplica a la selecció de publicacions individuals, independentment de si coincideixen amb les paraules clau següents. <a href="%{path}">Revisa o elimina publicacions del filtre</a>. @@ -1122,7 +1122,7 @@ ca: other: "%{count} publicacions individuals ocultades" title: Filtres new: - save: Desa el nou filtre + save: Desa el filtre nou title: Afegir un nou filtre statuses: back_to_filter: Tornar al filtre @@ -1387,7 +1387,7 @@ ca: phantom_js: PhantomJS qq: QQ Browser safari: Safari - uc_browser: UCBrowser + uc_browser: Navegador UC weibo: Weibo current_session: Sessió actual description: "%{browser} de %{platform}" diff --git a/config/locales/ckb.yml b/config/locales/ckb.yml index 93a92043e..483734fea 100644 --- a/config/locales/ckb.yml +++ b/config/locales/ckb.yml @@ -933,7 +933,6 @@ ckb: activity: دوایین چالاکی browser: وێبگەڕ browsers: - blackberry: بلاکبێری chrome: کرۆم edge: مایکرۆسۆفت ئیچ electron: ئەلکترۆن @@ -947,15 +946,12 @@ ckb: phantom_js: فانتۆم جەی ئێس qq: وێبگەڕی QQ safari: سافری - uc_browser: وێبگەڕی UC current_session: دانیشتنی ئێستا description: "%{browser} لەسەر %{platform}" explanation: ئەمانە وێبگەڕەکەن کە ئێستا چووەتە ژوورەوە بۆ ئەژمێری ماستۆدۆنی خۆت. ip: ئایپی platforms: android: ئەندرۆید - blackberry: بلاکبێری - chrome_os: سیستەمی کارگێڕی کرۆم firefox_os: سیستەمی کارگێڕی فایەرفۆکس linux: لینۆکس mac: ماک diff --git a/config/locales/co.yml b/config/locales/co.yml index 6e2066acc..c9d22cd12 100644 --- a/config/locales/co.yml +++ b/config/locales/co.yml @@ -914,7 +914,6 @@ co: browser: Navigatore browsers: alipay: Alipay - blackberry: Blackberry chrome: Chrome edge: Microsoft Edge electron: Electron @@ -928,7 +927,6 @@ co: phantom_js: PhantomJS qq: QQ Browser safari: Safari - uc_browser: UCBrowser weibo: Weibo current_session: Sessione attuale description: "%{browser} nant’à %{platform}" @@ -937,8 +935,6 @@ co: platforms: adobe_air: Adobe Air android: Android - blackberry: Blackberry - chrome_os: ChromeOS firefox_os: Firefox OS ios: iOS linux: Linux diff --git a/config/locales/cs.yml b/config/locales/cs.yml index b93ec3072..4a1674893 100644 --- a/config/locales/cs.yml +++ b/config/locales/cs.yml @@ -634,7 +634,7 @@ cs: other: "%{count} uživatelů" categories: administration: Administrace - devops: Devops + devops: DevOps invites: Pozvánky moderation: Moderování special: Speciální @@ -687,7 +687,7 @@ cs: view_audit_log_description: Umožňuje uživatelům vidět historii administrativních akcí na serveru view_dashboard: Zobrazit ovládací panel view_dashboard_description: Umožňuje uživatelům přístup k ovládacímu panelu a různým metrikám - view_devops: Devops + view_devops: DevOps view_devops_description: Umožňuje uživatelům přístup k ovládacím panelům Sidekiq a pgHero title: Role rules: @@ -1177,6 +1177,16 @@ cs: trending_now: Právě populární generic: all: Všechny + all_items_on_page_selected_html: + few: "<strong>%{count}</strong> položky na této stránce jsou vybrány." + many: "<strong>%{count}</strong> položek na této stránce je vybráno." + one: "<strong>%{count}</strong> položka na této stránce vybrána." + other: Všech <strong>%{count}</strong> položek na této stránce vybráno. + all_matching_items_selected_html: + few: "<strong>%{count}</strong> položky odpovídající vašemu hledání jsou vybrány." + many: "<strong>%{count}</strong> položek odpovídající vašemu hledání je vybráno." + one: "<strong>%{count}</strong> položka odpovídající vašemu hledání je vybrána." + other: Všech <strong>%{count}</strong> položek odpovídající vašemu hledání je vybráno. changes_saved_msg: Změny byly úspěšně uloženy! copy: Kopírovat delete: Smazat @@ -1429,7 +1439,7 @@ cs: phantom_js: PhantomJS qq: QQ Browser safari: Safari - uc_browser: UCBrowser + uc_browser: UC Browser weibo: Weibo current_session: Aktuální relace description: "%{browser} na systému %{platform}" @@ -1438,8 +1448,8 @@ cs: platforms: adobe_air: Adobe Air android: Android - blackberry: Blackberry - chrome_os: Chrome OS + blackberry: BlackBerry + chrome_os: ChromeOS firefox_os: Firefox OS ios: iOS linux: Linux diff --git a/config/locales/cy.yml b/config/locales/cy.yml index 88edb06d1..91ef6a172 100644 --- a/config/locales/cy.yml +++ b/config/locales/cy.yml @@ -773,7 +773,6 @@ cy: description: "%{browser} ar %{platform}" explanation: Dyma'r porwyr gwê sydd wedi mewngofnodi i'ch cyfrif Mastododon ar hyn o bryd. platforms: - chrome_os: OS Chrome firefox_os: OS Firefox mac: Mac other: platfform anhysbys diff --git a/config/locales/da.yml b/config/locales/da.yml index b09bb77f7..f9fd00387 100644 --- a/config/locales/da.yml +++ b/config/locales/da.yml @@ -608,7 +608,6 @@ da: other: "%{count} brugere" categories: administration: Håndtering - devops: Devops invites: Invitationer moderation: Moderering special: Speciel @@ -659,7 +658,6 @@ da: view_audit_log_description: Tillader brugere at se en historik over administrative handlinger på serveren view_dashboard: Vis Dashboard view_dashboard_description: Tillader brugere at tilgå Dashboard'et og forskellige målinger - view_devops: Devops view_devops_description: Tillader brugere at tilgå Sidekiq- og pgHero-dashboards title: Roller rules: @@ -1373,7 +1371,6 @@ da: browser: Browser browsers: alipay: Alipay - blackberry: Blackberry chrome: Chrome edge: Microsoft Edge electron: Electron @@ -1387,7 +1384,6 @@ da: phantom_js: PhantomJS qq: QQ Browser safari: Safari - uc_browser: UCbrowser weibo: Weibo current_session: Aktuelle session description: "%{browser} på %{platform}" @@ -1396,8 +1392,6 @@ da: platforms: adobe_air: Adobe Air android: Android - blackberry: Blackberry - chrome_os: Chrome OS firefox_os: Firefox OS ios: iOS linux: Linux diff --git a/config/locales/de.yml b/config/locales/de.yml index d6f8ba94e..7bc73dcb4 100644 --- a/config/locales/de.yml +++ b/config/locales/de.yml @@ -580,7 +580,7 @@ de: create_and_resolve: Mit Kommentar lösen create_and_unresolve: Mit Kommentar wieder öffnen delete: Löschen - placeholder: Bitte beschreiben, welche Maßnahmen ergriffen wurden oder andere damit verbundene Aktualisierungen … + placeholder: Bitte beschreibe, welche Maßnahmen ergriffen wurden oder andere damit verbundene Aktualisierungen … title: Notizen notes_description_html: Zeige und hinterlasse Notizen an andere Moderator_innen und dein zukünftiges Ich quick_actions_description_html: 'Führe eine schnelle Aktion aus oder scrolle nach unten, um gemeldete Inhalte zu sehen:' @@ -676,17 +676,17 @@ de: rules_hint: Es gibt einen eigenen Bereich für Regeln, die deine Benutzer*innen einhalten müssen. title: Über appearance: - preamble: Passen Sie Mastodons Weboberfläche an. - title: Darstellung + preamble: Passe die Weboberfläche von Mastodon an. + title: Erscheinungsbild branding: - preamble: Das Branding Ihres Servers unterscheidet ihn von anderen Servern im Netzwerk. Diese Informationen können in einer Vielzahl von Umgebungen angezeigt werden, z. B. in der Weboberfläche von Mastodon, in nativen Anwendungen, in Linkvorschauen auf anderen Websites und in Messaging-Apps und so weiter. Aus diesem Grund ist es am besten, diese Informationen klar, kurz und prägnant zu halten. + preamble: Das Branding deines Servers unterscheidet ihn von anderen Servern im Netzwerk. Diese Informationen können in einer Vielzahl von Umgebungen angezeigt werden, z. B. in der Weboberfläche von Mastodon, in nativen Anwendungen, in Linkvorschauen auf anderen Websites und in Messaging-Apps und so weiter. Aus diesem Grund ist es am besten, diese Informationen klar, kurz und prägnant zu halten. title: Branding content_retention: preamble: Steuern Sie, wie nutzergenerierte Inhalte in Mastodon gespeichert werden. title: Aufbewahrung von Inhalten discovery: follow_recommendations: Folgeempfehlungen - preamble: Das Auffinden interessanter Inhalte ist wichtig, um neue Nutzer einzubinden, die Mastodon noch nicht kennen. Bestimmen Sie, wie verschiedene Suchfunktionen auf Ihrem Server funktionieren. + preamble: Das Auffinden interessanter Inhalte ist wichtig, um neue Nutzer einzubinden, die Mastodon noch nicht kennen. Bestimme, wie verschiedene Suchfunktionen auf deinem Server funktionieren. profile_directory: Profilverzeichnis public_timelines: Öffentliche Timelines title: Entdecken @@ -796,7 +796,7 @@ de: not_discoverable: Der Autor hat sich nicht dafür entschieden, entdeckt zu werden shared_by: one: Einmal geteilt oder favorisiert - other: "%{friendly_count} mal geteilt oder favorisiert" + other: "%{friendly_count}-mal geteilt oder favorisiert" title: Angesagte Beiträge tags: current_score: Aktuelle Punktzahl %{score} @@ -889,7 +889,7 @@ de: remove: Alle Aliase aufheben appearance: advanced_web_interface: Fortgeschrittene Benutzeroberfläche - advanced_web_interface_hint: Wenn du mehr aus deiner Bildschirmbreite herausholen möchtest, kannst du mit der fortgeschrittenen Benutzeroberfläche weitere Spalten hinzufügen und dadurch mehr Informationen auf einmal sehen, z. B. deine Startseite, die Mitteilungen, die vereinigte Timeline sowie beliebig viele deiner Listen und Hashtags. + advanced_web_interface_hint: Wenn du mehr aus deiner Bildschirmbreite herausholen möchtest, kannst du mit der fortgeschrittenen Benutzeroberfläche weitere Spalten hinzufügen und dadurch mehr Informationen auf einmal sehen, z. B. deine Startseite, die Mitteilungen, die föderierte Timeline sowie beliebig viele deiner Listen und Hashtags. animations_and_accessibility: Animationen und Barrierefreiheit confirmation_dialogs: Bestätigungsfenster discovery: Entdecken @@ -1373,7 +1373,7 @@ de: browser: Browser browsers: alipay: Alipay - blackberry: Blackberry + blackberry: BlackBerry chrome: Chrome edge: Microsoft Edge electron: Electron @@ -1387,7 +1387,7 @@ de: phantom_js: PhantomJS qq: QQ Browser safari: Safari - uc_browser: UCBrowser + uc_browser: UC Browser weibo: Weibo current_session: Aktuelle Sitzung description: "%{browser} auf %{platform}" @@ -1396,7 +1396,7 @@ de: platforms: adobe_air: Adobe Air android: Android - blackberry: Blackberry + blackberry: BlackBerry chrome_os: ChromeOS firefox_os: Firefox OS ios: iOS @@ -1414,7 +1414,7 @@ de: account: Konto account_settings: Kontoeinstellungen aliases: Kontoaliase - appearance: Aussehen + appearance: Erscheinungsbild authorized_apps: Autorisierte Anwendungen back: Zurück zu Mastodon delete: Konto löschen @@ -1472,7 +1472,7 @@ de: show_more: Mehr anzeigen show_newer: Neuere anzeigen show_older: Ältere anzeigen - show_thread: Unterhaltung anzeigen + show_thread: Thread anzeigen sign_in_to_participate: Melde dich an, um an der Konversation teilzuhaben title: '%{name}: "%{quote}"' visibilities: diff --git a/config/locales/devise.th.yml b/config/locales/devise.th.yml index 38d7a0c52..e46500796 100644 --- a/config/locales/devise.th.yml +++ b/config/locales/devise.th.yml @@ -91,7 +91,7 @@ th: signed_up: ยินดีต้อนรับ! คุณได้ลงทะเบียนสำเร็จ signed_up_but_inactive: คุณได้ลงทะเบียนสำเร็จ อย่างไรก็ตามเราไม่สามารถลงชื่อคุณเข้าได้เนื่องจากยังไม่ได้เปิดใช้งานบัญชีของคุณ signed_up_but_locked: คุณได้ลงทะเบียนสำเร็จ อย่างไรก็ตามเราไม่สามารถลงชื่อคุณเข้าได้เนื่องจากมีการล็อคบัญชีของคุณอยู่ - signed_up_but_pending: ส่งข้อความพร้อมลิงก์ยืนยันไปยังที่อยู่อีเมลของคุณแล้ว หลังจากคุณคลิกลิงก์ เราจะตรวจทานใบสมัครของคุณ คุณจะได้รับการแจ้งเตือนหากใบสมัครได้รับการอนุมัติ + signed_up_but_pending: ส่งข้อความพร้อมลิงก์ยืนยันไปยังที่อยู่อีเมลของคุณแล้ว หลังจากคุณคลิกลิงก์ เราจะตรวจทานใบสมัครของคุณ คุณจะได้รับการแจ้งเตือนหากมีการอนุมัติใบสมัคร signed_up_but_unconfirmed: ส่งข้อความพร้อมลิงก์ยืนยันไปยังที่อยู่อีเมลของคุณแล้ว โปรดไปตามลิงก์เพื่อเปิดใช้งานบัญชีของคุณ โปรดตรวจสอบโฟลเดอร์สแปมของคุณหากคุณไม่ได้รับอีเมลนี้ update_needs_confirmation: คุณได้อัปเดตบัญชีของคุณสำเร็จ แต่เราจำเป็นต้องยืนยันที่อยู่อีเมลใหม่ของคุณ โปรดตรวจสอบอีเมลของคุณแล้วไปตามลิงก์ยืนยันเพื่อยืนยันที่อยู่อีเมลใหม่ของคุณ โปรดตรวจสอบโฟลเดอร์สแปมของคุณหากคุณไม่ได้รับอีเมลนี้ updated: อัปเดตบัญชีของคุณสำเร็จ diff --git a/config/locales/doorkeeper.ca.yml b/config/locales/doorkeeper.ca.yml index 954ef2a6e..203388823 100644 --- a/config/locales/doorkeeper.ca.yml +++ b/config/locales/doorkeeper.ca.yml @@ -172,9 +172,9 @@ ca: write: modificar totes les dades del teu compte write:accounts: modifica el teu perfil write:blocks: bloqueja comptes i dominis - write:bookmarks: publicacions a marcadors + write:bookmarks: marcar publicacions write:conversations: silencia i esborra converses - write:favourites: afavorir publicacions + write:favourites: marcar publicacions write:filters: crear filtres write:follows: seguir usuaris write:lists: crear llistes diff --git a/config/locales/doorkeeper.eo.yml b/config/locales/doorkeeper.eo.yml index 419b58b94..e239da785 100644 --- a/config/locales/doorkeeper.eo.yml +++ b/config/locales/doorkeeper.eo.yml @@ -60,6 +60,7 @@ eo: error: title: Eraro okazis new: + review_permissions: Revizu permesojn title: Rajtigo bezonata show: title: Kopiu ĉi tiun rajtigan kodon kaj gluu ĝin al la aplikaĵo. @@ -69,6 +70,8 @@ eo: confirmations: revoke: Ĉu vi certas? index: + never_used: Neniam uzata + scopes: Permesoj superapp: Interna title: Viaj rajtigitaj aplikaĵoj errors: @@ -111,10 +114,13 @@ eo: all: Ĉio blocks: Blokita bookmarks: Legosignoj + conversations: Konversacioj favourites: Preferaĵoj filters: Filtriloj + follows: Sekvas lists: Listoj mutes: Silentigitaj + notifications: Sciigoj reports: Raportoj search: Serĉi statuses: Afiŝoj diff --git a/config/locales/el.yml b/config/locales/el.yml index 499347866..20d74a6a4 100644 --- a/config/locales/el.yml +++ b/config/locales/el.yml @@ -438,6 +438,8 @@ el: devops: Devops invites: Προσκλήσεις delete: Διαγραφή + privileges: + view_devops: DevOps rules: add_new: Προσθήκη κανόνα delete: Διαγραφή @@ -936,11 +938,15 @@ el: activity: Τελευταία δραστηριότητα browser: Φυλλομετρητής (Browser) browsers: + blackberry: BlackBerry generic: Άγνωστος φυλλομετρητής + uc_browser: UC Browser current_session: Τρέχουσα σύνδεση description: "%{browser} σε %{platform}" explanation: Αυτοί είναι οι φυλλομετρητές (browsers) που είναι συνδεδεμένοι στον λογαριασμό σου στο Mastodon αυτή τη στιγμή. platforms: + blackberry: BlackBerry + chrome_os: ChromeOS mac: Mac other: άγνωστη πλατφόρμα revoke: Ανακάλεσε diff --git a/config/locales/en.yml b/config/locales/en.yml index c50fc074c..679e356b4 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -608,7 +608,7 @@ en: other: "%{count} users" categories: administration: Administration - devops: Devops + devops: DevOps invites: Invites moderation: Moderation special: Special @@ -659,7 +659,7 @@ en: view_audit_log_description: Allows users to see a history of administrative actions on the server view_dashboard: View Dashboard view_dashboard_description: Allows users to access the dashboard and various metrics - view_devops: Devops + view_devops: DevOps view_devops_description: Allows users to access Sidekiq and pgHero dashboards title: Roles rules: @@ -1374,7 +1374,7 @@ en: browser: Browser browsers: alipay: Alipay - blackberry: Blackberry + blackberry: BlackBerry chrome: Chrome edge: Microsoft Edge electron: Electron @@ -1388,7 +1388,7 @@ en: phantom_js: PhantomJS qq: QQ Browser safari: Safari - uc_browser: UCBrowser + uc_browser: UC Browser weibo: Weibo current_session: Current session description: "%{browser} on %{platform}" @@ -1397,8 +1397,8 @@ en: platforms: adobe_air: Adobe Air android: Android - blackberry: Blackberry - chrome_os: Chrome OS + blackberry: BlackBerry + chrome_os: ChromeOS firefox_os: Firefox OS ios: iOS linux: Linux diff --git a/config/locales/eo.yml b/config/locales/eo.yml index de18f97b2..5c890ffda 100644 --- a/config/locales/eo.yml +++ b/config/locales/eo.yml @@ -317,6 +317,7 @@ eo: other: "<strong>%{count}</strong> pritraktotaj kradvortoj" resolved_reports: raportoj solvitaj software: Programo + sources: Fontoj de konto-kreado space: Memorspaca uzado title: Kontrolpanelo top_languages: Plej aktivaj lingvoj @@ -526,7 +527,6 @@ eo: other: "%{count} uzantoj" categories: administration: Administrado - devops: Programado kaj Operaciado invites: Invitoj moderation: Kontrolado special: Specialaj @@ -552,7 +552,6 @@ eo: manage_invites: Administri Invitojn manage_roles: Administri Rolojn manage_rules: Administri Regulojn - view_devops: Programado kaj Operaciado title: Roloj rules: add_new: Aldoni regulon @@ -689,7 +688,7 @@ eo: confirmation_dialogs: Konfirmaj fenestroj discovery: Eltrovo localization: - body: Mastodon estas tradukita per volontuloj. + body: Mastodon estas tradukita de volontuloj. guide_link: https://crowdin.com/project/mastodon guide_link_text: Ĉiu povas kontribui. sensitive_content: Tikla enhavo @@ -714,7 +713,7 @@ eo: delete_account_html: Se vi deziras forigi vian konton, vi povas <a href="%{path}">fari tion ĉi tie</a>. Vi bezonos konfirmi vian peton. description: prefix_invited_by_user: "@%{name} invitigi vin aligiĝi ĉi tiu servilo de Mastodon!" - prefix_sign_up: Registriĝi ĉe Mastodon hodiaŭ! + prefix_sign_up: Registriĝu ĉe Mastodon hodiaŭ! suffix: Kun konto, vi povos sekvi aliajn homojn, skribi afiŝojn kaj interŝanĝi mesaĝojn kun la uzantoj de iu ajn Mastodon'a servilo kaj multe pli! didnt_get_confirmation: Ĉu vi ne ricevis la instrukciojn por konfirmi? dont_have_your_security_key: Ne havas vi vian sekurecan ŝlosilon? @@ -722,7 +721,7 @@ eo: invalid_reset_password_token: Ĵetono por restarigi pasvorton nevalida aŭ eksvalida. Bonvolu peti novan. link_to_webauth: Uzi vian sekurecan ŝlosilon log_in_with: Ensaluti per - login: Saluti + login: Ensaluti logout: Adiaŭi migrate_account: Movi al alia konto migrate_account_html: Se vi deziras alidirekti ĉi tiun konton al alia, vi povas <a href="%{path}">agordi ĝin ĉi tie</a>. @@ -730,7 +729,7 @@ eo: providers: cas: CAS saml: SAML - register: Registriĝi + register: Krei konton registration_closed: "%{instance} ne estas akcepti nova uzantojn" resend_confirmation: Resendi la instrukciojn por konfirmi reset_password: Restarigi pasvorton @@ -957,6 +956,9 @@ eo: navigation: toggle_menu: Baskuli menuon notification_mailer: + admin: + sign_up: + subject: "%{name} registriĝis" favourite: body: "%{name} stelumis vian mesaĝon:" subject: "%{name} stelumis vian mesaĝon" @@ -1075,7 +1077,7 @@ eo: phantom_js: PhantomJS qq: QQ Browser safari: Safari - uc_browser: UCBrowser + uc_browser: UC Browser weibo: Weibo current_session: Nuna seanco description: "%{browser} en %{platform}" @@ -1155,7 +1157,7 @@ eo: show_newer: Montri pli novajn show_older: Montri pli malnovajn show_thread: Montri la mesaĝaron - sign_in_to_participate: Ensaluti por partopreni en la konversacio + sign_in_to_participate: Ensalutu por partopreni la konversacion title: "%{name}: “%{quote}”" visibilities: direct: Rekta diff --git a/config/locales/es-AR.yml b/config/locales/es-AR.yml index c3ddd7443..e0def87ca 100644 --- a/config/locales/es-AR.yml +++ b/config/locales/es-AR.yml @@ -1397,7 +1397,7 @@ es-AR: adobe_air: Adobe Air android: Android blackberry: BlackBerry - chrome_os: Chrome OS + chrome_os: ChromeOS firefox_os: Firefox OS ios: iOS linux: GNU/Linux diff --git a/config/locales/es-MX.yml b/config/locales/es-MX.yml index c864536ce..ab0d9be1d 100644 --- a/config/locales/es-MX.yml +++ b/config/locales/es-MX.yml @@ -608,7 +608,6 @@ es-MX: other: "%{count} usuarios" categories: administration: Administración - devops: DevOps invites: Invitaciones moderation: Moderación special: Especial @@ -659,7 +658,6 @@ es-MX: view_audit_log_description: Permite a los usuarios ver un historial de acciones administrativas en el servidor view_dashboard: Ver Panel de Control view_dashboard_description: Permite a los usuarios acceder al panel de control y varias métricas - view_devops: DevOps view_devops_description: Permite a los usuarios acceder a los paneles de control Sidekiq y pgHero title: Roles rules: @@ -1373,7 +1371,6 @@ es-MX: browser: Navegador browsers: alipay: Alipay - blackberry: Blackberry chrome: Chrome edge: Microsoft Edge electron: Electron @@ -1387,7 +1384,6 @@ es-MX: phantom_js: PhantomJS qq: Navegador QQ safari: Safari - uc_browser: UCBrowser weibo: Weibo current_session: Sesión actual description: "%{browser} en %{platform}" @@ -1396,8 +1392,6 @@ es-MX: platforms: adobe_air: Adobe Air android: Android - blackberry: Blackberry - chrome_os: ChromeOS firefox_os: Firefox OS ios: iOS linux: GNU Linux diff --git a/config/locales/es.yml b/config/locales/es.yml index 6bd34034b..94478df9b 100644 --- a/config/locales/es.yml +++ b/config/locales/es.yml @@ -608,7 +608,6 @@ es: other: "%{count} usuarios" categories: administration: Administración - devops: DevOps invites: Invitaciones moderation: Moderación special: Especial @@ -659,7 +658,6 @@ es: view_audit_log_description: Permite a los usuarios ver un historial de acciones administrativas en el servidor view_dashboard: Ver Panel de Control view_dashboard_description: Permite a los usuarios acceder al panel de control y varias métricas - view_devops: DevOps view_devops_description: Permite a los usuarios acceder a los paneles de control Sidekiq y pgHero title: Roles rules: @@ -1373,7 +1371,6 @@ es: browser: Navegador browsers: alipay: Alipay - blackberry: Blackberry chrome: Chrome edge: Microsoft Edge electron: Electron @@ -1387,7 +1384,6 @@ es: phantom_js: PhantomJS qq: Navegador QQ safari: Safari - uc_browser: UCBrowser weibo: Weibo current_session: Sesión actual description: "%{browser} en %{platform}" @@ -1396,8 +1392,6 @@ es: platforms: adobe_air: Adobe Air android: Android - blackberry: Blackberry - chrome_os: ChromeOS firefox_os: Firefox OS ios: iOS linux: GNU Linux diff --git a/config/locales/eu.yml b/config/locales/eu.yml index 4a8d9bd50..11dcec2bc 100644 --- a/config/locales/eu.yml +++ b/config/locales/eu.yml @@ -608,7 +608,7 @@ eu: other: "%{count} erabiltzaile" categories: administration: Administrazioa - devops: Devops + devops: DevOps invites: Gonbidapenak moderation: Moderazioa special: Berezia @@ -659,7 +659,7 @@ eu: view_audit_log_description: Baimendu erabiltzaileek zerbitzariko administrazio-ekintzen historia ikustea view_dashboard: Ikusi aginte-panela view_dashboard_description: Baimendu erabiltzaileek aginte-panela eta hainbat estatistika ikustea - view_devops: Devops + view_devops: DevOps view_devops_description: Baimendu erabiltzaileek Sidekiq eta pgHero aginte-paneletara sarbidea izatea title: Rolak rules: @@ -1373,7 +1373,7 @@ eu: browser: Nabigatzailea browsers: alipay: Alipay - blackberry: Blackberry + blackberry: BlackBerry chrome: Chrome edge: Microsoft Edge electron: Electron @@ -1387,7 +1387,7 @@ eu: phantom_js: PhantomJS qq: QQ nabigatzailea safari: Safari - uc_browser: UCBrowser + uc_browser: UC nabigatzailea weibo: Weibo current_session: Uneko saioa description: "%{browser} - %{platform}" @@ -1396,7 +1396,7 @@ eu: platforms: adobe_air: Adobe Air android: Android - blackberry: Blackberry + blackberry: BlackBerry chrome_os: ChromeOS firefox_os: Firefox OS ios: iOS diff --git a/config/locales/fa.yml b/config/locales/fa.yml index 6c3690aee..9601162de 100644 --- a/config/locales/fa.yml +++ b/config/locales/fa.yml @@ -544,7 +544,6 @@ fa: add_new: افزودن نقش categories: administration: مدیریت - devops: دواپس invites: دعوتها moderation: نظارت special: ویژه @@ -1104,7 +1103,6 @@ fa: browser: مرورگر browsers: alipay: علیپی - blackberry: بلکبری chrome: کروم edge: مایکروسافت اج electron: الکترون @@ -1118,7 +1116,6 @@ fa: phantom_js: فنتومجیاس qq: مرورگر کیوکیو safari: سافاری - uc_browser: مرورگر یوسی weibo: وبیو current_session: نشست فعلی description: "%{browser} روی %{platform}" @@ -1127,8 +1124,6 @@ fa: platforms: adobe_air: ایر ادوبی android: اندروید - blackberry: بلکبری - chrome_os: سیستمعامل کروم firefox_os: سیستمعامل فایرفاکس ios: آیاواس linux: لینوکس diff --git a/config/locales/fi.yml b/config/locales/fi.yml index dc8703af6..3a72387e2 100644 --- a/config/locales/fi.yml +++ b/config/locales/fi.yml @@ -608,7 +608,7 @@ fi: other: "%{count} käyttäjää" categories: administration: Ylläpito - devops: Operaattorit + devops: DevOps invites: Kutsut moderation: Moderointi special: Erikois @@ -659,7 +659,7 @@ fi: view_audit_log_description: Sallii käyttäjien nähdä palvelimen hallinnollisten toimien historian view_dashboard: Näytä koontinäyttö view_dashboard_description: Sallii käyttäjien käyttää kojelautaa ja erilaisia mittareita - view_devops: Operaattorit + view_devops: DevOps view_devops_description: Sallii käyttäjille oikeuden käyttää Sidekiq ja pgHero dashboardeja title: Roolit rules: @@ -1065,7 +1065,7 @@ fi: content: Valitettavasti jokin meni pieleen meidän päässämme. title: Sivu ei ole oikein '503': Sivua ei voitu näyttää palvelimen väliaikaisen vian vuoksi. - noscript_html: Mastodon-selainsovelluksen käyttöön vaaditaan JavaScript. Voit vaihtoehtoisesti kokeilla jotakin omalle käyttöjärjestelmällesi tehtyä Mastodon<a href="%{apps_path}">sovellusta</a>. + noscript_html: Käyttääksesi Mastodon-verkkopalvelua, ota JavaScript käyttöön. Vaihtoehtoisesti voit kokeilla myös jotakin juuri käyttämällesi alustalle kehitettyä Mastodon-<a href="%{apps_path}">sovellusta</a>. existing_username_validator: not_found: paikallista käyttäjää ei löydy kyseisellä käyttäjänimellä not_found_multiple: "%{usernames} ei löytynyt" @@ -1373,7 +1373,7 @@ fi: browser: Selain browsers: alipay: Alipay - blackberry: Blackberry + blackberry: BlackBerry chrome: Chrome edge: Microsoft Edge electron: Electron @@ -1387,22 +1387,22 @@ fi: phantom_js: PhantomJS qq: QQ Browser safari: Safari - uc_browser: UCBrowser + uc_browser: UC Browser weibo: Weibo current_session: Nykyinen istunto - description: "%{browser}, %{platform}" + description: "%{browser} alustalla %{platform}" explanation: Nämä verkkoselaimet ovat tällä hetkellä kirjautuneet Mastodon-tilillesi. ip: IP-osoite platforms: - adobe_air: Adobe Air + adobe_air: Adobe AIR android: Android - blackberry: Blackberry - chrome_os: Chrome OS + blackberry: BlackBerry + chrome_os: ChromeOS firefox_os: Firefox OS ios: iOS linux: Linux mac: macOS - other: tuntematon järjestelmä + other: tuntematon alusta windows: Windows windows_mobile: Windows Mobile windows_phone: Windows Phone diff --git a/config/locales/fr.yml b/config/locales/fr.yml index a177d6fa5..191e14deb 100644 --- a/config/locales/fr.yml +++ b/config/locales/fr.yml @@ -608,7 +608,7 @@ fr: other: "%{count} utilisateur·rice·s" categories: administration: Administration - devops: Devops + devops: DevOps invites: Invitations moderation: Modération special: Spécial @@ -659,7 +659,7 @@ fr: view_audit_log_description: Permet aux utilisateur⋅rice⋅s de voir l'historique des opérations d'administration sur le serveur view_dashboard: Voir le tableau de bord view_dashboard_description: Permet aux utilisateur⋅rice⋅s d'accéder au tableau de bord et à diverses statistiques - view_devops: Devops + view_devops: DevOps view_devops_description: Permet aux utilisateur⋅rice⋅s d'accéder aux tableaux de bord Sidekiq et pgHero title: Rôles rules: @@ -1397,7 +1397,7 @@ fr: adobe_air: Adobe Air android: Android blackberry: BlackBerry - chrome_os: Chrome OS + chrome_os: ChromeOS firefox_os: Firefox OS ios: iOS linux: Linux diff --git a/config/locales/ga.yml b/config/locales/ga.yml index 33408ddb7..9df952ef1 100644 --- a/config/locales/ga.yml +++ b/config/locales/ga.yml @@ -1,7 +1,10 @@ --- ga: about: + about_mastodon_html: 'Líonra sóisialta a sheasfaidh an aimsir: Gan fógraíocht, gan faire chorparáideach, le leagan amach eiticiúil agus dílárú. Bíodh do chuid sonraí agatsa féin le Mastodon!' + contact_missing: Gan socrú contact_unavailable: N/B + hosted_on: Mastodon arna óstáil ar %{domain} title: Maidir le accounts: follow: Lean @@ -17,7 +20,7 @@ ga: admin: account_actions: action: Déan gníomh - title: Déan modhnóireacht ar %{acct} + title: Dean gníomh modhnóireachta ar %{acct} account_moderation_notes: create: Fág nóta accounts: @@ -30,12 +33,12 @@ ga: label: Athraigh ríomhphost new_email: Ríomhphost nua submit: Athraigh ríomhphost - title: Athraigh ríomhphost %{username} + title: Athraigh ríomhphost do %{username} change_role: - changed_msg: D'athraigh ró go rathúil! + changed_msg: Athraíodh ról go rathúil! label: Athraigh ról - no_role: Níl aon ról ann - title: Athraigh ról %{username} + no_role: Gan ról + title: Athraigh ról do %{username} confirm: Deimhnigh confirmed: Deimhnithe confirming: Ag deimhniú @@ -62,31 +65,48 @@ ga: local: Áitiúil remote: Cian promote: Ardaigh + protocol: Prótacal public: Poiblí + redownload: Athnuaigh próifíl reject: Diúltaigh + remove_avatar: Bain abhatár + remove_header: Bain ceanntásc + resend_confirmation: + success: Seoladh go rathúil ríomhphost deimhnithe! + reset: Athshocraigh + reset_password: Athshocraigh pasfhocal + resubscribe: Athchláraigh role: Ról search: Cuardaigh statuses: Postálacha + subscribe: Cláraigh title: Cuntais web: Gréasán action_logs: action_types: - assigned_to_self_report: Sann tuairisc - create_account_warning: Cruthaigh rabhadh + assigned_to_self_report: Sann Tuairisc + create_account_warning: Cruthaigh Rabhadh destroy_announcement: Scrios Fógra destroy_ip_block: Scrios riail IP - destroy_status: Scrios postáil + destroy_status: Scrios Postáil + remove_avatar_user: Bain Abhatár reopen_report: Athoscail tuairisc + reset_password_user: Athshocraigh Pasfhocal resolve_report: Réitigh tuairisc - unassigned_report: Cealaigh tuairisc a shann + unassigned_report: Díshann Tuairisc + update_announcement: Nuashonraigh Fógra + update_status: Nuashonraigh Postáil + update_user_role: Nuashonraigh Ról actions: - create_account_warning_html: Sheol %{name} rabhadh do %{target} + create_account_warning_html: Sheol %{name} rabhadh chuig %{target} deleted_account: cuntas scriosta announcements: live: Beo publish: Foilsigh custom_emojis: + created_msg: Cruthaíodh emoji go rathúil! delete: Scrios + destroyed_msg: Scriosadh emoji go rathúil! disable: Díchumasaigh disabled: Díchumasaithe emoji: Emoji @@ -98,6 +118,7 @@ ga: title: Deais website: Suíomh Gréasáin domain_blocks: + domain: Fearann new: severity: silence: Ciúnaigh @@ -115,6 +136,8 @@ ga: unavailable: Níl ar fáil moderation: all: Uile + purge: Glan + title: Cónascadh invites: filter: all: Uile @@ -134,10 +157,11 @@ ga: disabled: Díchumasaithe enable: Cumasaigh enabled: Ar chumas + save_and_enable: Sábháil agus cumasaigh status: Stádas reports: category: Catagóir - delete_and_resolve: Scrios postála + delete_and_resolve: Scrios postálacha no_one_assigned: Duine ar bith notes: delete: Scrios @@ -147,7 +171,7 @@ ga: roles: delete: Scrios privileges: - delete_user_data: Scrios sonraí úsáideora + delete_user_data: Scrios Sonraí Úsáideora rules: delete: Scrios site_uploads: @@ -156,17 +180,25 @@ ga: account: Údar deleted: Scriosta language: Teanga + media: + title: Meáin + metadata: Meiteashonraí open: Oscail postáil original_status: Bunphostáil + reblogs: Athbhlaganna + status_changed: Athraíodh postáil + trending: Ag treochtáil with_media: Le meáin strikes: actions: - delete_statuses: Scrios %{name} postála %{target} + delete_statuses: Scrios %{name} postálacha de chuid %{target} tags: review: Stádas athbhreithnithe trends: allow: Ceadaigh disallow: Dícheadaigh + preview_card_providers: + title: Foilsitheoirí statuses: allow: Ceadaigh postáil allow_account: Ceadaigh údar @@ -177,17 +209,17 @@ ga: admin_mailer: new_appeal: actions: - delete_statuses: chun postála acu a scrios + delete_statuses: a gcuid postálacha a scrios none: rabhadh auth: delete_account: Scrios cuntas - too_fast: Chuireadh foirm róthapa, bain triail arís. + too_fast: Cuireadh an fhoirm isteach róthapa, triail arís. deletes: proceed: Scrios cuntas disputes: strikes: appeal_submitted_at: Achomharc curtha isteach - appealed_msg: Bhí d'achomharc curtha isteach. Má ceadaítear é, cuirfidh ar an eolas tú. + appealed_msg: Cuireadh isteach d'achomharc. Má ceadófar é, cuirfear ar an eolas tú. appeals: submit: Cuir achomharc isteach title_actions: @@ -219,7 +251,7 @@ ga: statuses: content_warning: 'Rabhadh ábhair: %{warning}' show_more: Taispeáin níos mó - show_newer: Taispeáin níos déanaí + show_newer: Taispeáin níos nuaí show_thread: Taispeáin snáithe user_mailer: warning: diff --git a/config/locales/gd.yml b/config/locales/gd.yml index 99f432ea4..24dc6e7ca 100644 --- a/config/locales/gd.yml +++ b/config/locales/gd.yml @@ -634,7 +634,6 @@ gd: two: "%{count} chleachdaiche" categories: administration: Rianachd - devops: DevOps invites: Cuiridhean moderation: Maorsainneachd special: Sònraichte @@ -687,7 +686,6 @@ gd: view_audit_log_description: Leigidh seo le cleachdaichean coimhead air eachdraidh gnìomhan na rianachd air an fhrithealaiche view_dashboard: Coimhead air an deas-bhòrd view_dashboard_description: Leigidh seo le cleachdaichean an deas-bhòrd agus meatrachdan inntrigeadh - view_devops: DevOps view_devops_description: Leigidh seo le cleachdaichean na deas-bhùird aig Sidekiq is pgHero inntrigeadh title: Dreuchdan rules: @@ -1425,7 +1423,6 @@ gd: browser: Brabhsair browsers: alipay: Alipay - blackberry: Blackberry chrome: Chrome edge: Microsoft Edge electron: Electron @@ -1439,7 +1436,6 @@ gd: phantom_js: PhantomJS qq: QQ Browser safari: Safari - uc_browser: UCBrowser weibo: Weibo current_session: An seisean làithreach description: "%{browser} air %{platform}" @@ -1448,8 +1444,6 @@ gd: platforms: adobe_air: Adobe Air android: Android - blackberry: Blackberry - chrome_os: ChromeOS firefox_os: Firefox OS ios: iOS linux: Linux diff --git a/config/locales/gl.yml b/config/locales/gl.yml index afdd51394..cb15fc513 100644 --- a/config/locales/gl.yml +++ b/config/locales/gl.yml @@ -11,7 +11,7 @@ gl: followers: one: Seguidora other: Seguidoras - following: Seguindo + following: A Seguir instance_actor_flash: Esta conta é un actor virtual utilizado para representar ó servidor mesmo e non a unha usuaria individual. Utilízase por motivos de federación e non debería estar suspendida. last_active: última actividade link_verified_on: A propiedade desta ligazón foi verificada en %{date} @@ -71,7 +71,7 @@ gl: enabled: Activado enabled_msg: Desbloqueada a conta de %{username} followers: Seguidoras - follows: Seguindo + follows: Segue header: Cabeceira inbox_url: URL da caixa de entrada invite_request_text: Razóns para unirte @@ -608,7 +608,6 @@ gl: other: "%{count} usuarias" categories: administration: Administración - devops: DevOps invites: Convites moderation: Moderación special: Especial @@ -659,7 +658,6 @@ gl: view_audit_log_description: Permite ver o historial de accións administrativas no servidor view_dashboard: Ver Taboleiro view_dashboard_description: Permite acceder ao taboleiro e varias métricas do servidor - view_devops: Devops view_devops_description: Permite acceder aos taboleiros Sidekiq e phHero title: Roles rules: @@ -1077,12 +1075,12 @@ gl: in_progress: Xerando o seu ficheiro... request: Solicite o ficheiro size: Tamaño - blocks: Bloqueos + blocks: Bloqueadas bookmarks: Marcadores csv: CSV domain_blocks: Bloqueos de dominio lists: Listaxes - mutes: Silenciados + mutes: Silenciadas storage: Almacenamento de multimedia featured_tags: add_new: Engadir novo @@ -1342,7 +1340,7 @@ gl: dormant: En repouso follow_selected_followers: Seguir seguidoras seleccionadas followers: Seguidoras - following: Seguindo + following: A Seguir invited: Convidado last_active: Último activo most_recent: Máis recente @@ -1373,7 +1371,6 @@ gl: browser: Navegador browsers: alipay: Alipay - blackberry: Blackberry chrome: Chrome edge: Microsoft Edge electron: Electron @@ -1387,7 +1384,6 @@ gl: phantom_js: PhantomJS qq: Navegador QQ safari: Safari - uc_browser: UCBrowser weibo: Weibo current_session: Sesión actual description: "%{browser} en %{platform}" @@ -1396,8 +1392,6 @@ gl: platforms: adobe_air: Adobe Air android: Android - blackberry: Blackberry - chrome_os: ChromeOS firefox_os: Firefox OS ios: iOS linux: Linux diff --git a/config/locales/he.yml b/config/locales/he.yml index 28cf52e1c..bc51c21ac 100644 --- a/config/locales/he.yml +++ b/config/locales/he.yml @@ -634,7 +634,7 @@ he: two: "%{count} שני משתמשים" categories: administration: ניהול מערכת - devops: פיתוח + devops: DevOps invites: הזמנות moderation: פיקוח special: מיוחדים @@ -687,7 +687,7 @@ he: view_audit_log_description: מאפשר למשתשמשים לצפות בהיסטוריה של פעולות מנהלתיות על השרת view_dashboard: הצג לוח מחוונים view_dashboard_description: אפשר למשתמשים לגשת ללוח המחוונים - view_devops: פיתוח + view_devops: DevOps view_devops_description: מאפשר למשתמשים לגשת ללוחות המחוונים של Sidekiq ושל pgHero title: תפקידים rules: @@ -1424,7 +1424,7 @@ he: phantom_js: PhantomJS qq: דפדפן QQ safari: ספארי - uc_browser: UCBrowser + uc_browser: דפדפן UC weibo: Weibo current_session: חיבור נוכחי description: "%{browser} על %{platform}" @@ -1434,7 +1434,7 @@ he: adobe_air: אדובה אייר android: אנדרואיד blackberry: בלקברי - chrome_os: Chrome OS + chrome_os: ChromeOS firefox_os: Firefox OS ios: iOS linux: לינוקס diff --git a/config/locales/hu.yml b/config/locales/hu.yml index 078668eba..529d4dadf 100644 --- a/config/locales/hu.yml +++ b/config/locales/hu.yml @@ -608,7 +608,6 @@ hu: other: "%{count} felhasználó" categories: administration: Adminisztráció - devops: Devops invites: Meghívások moderation: Moderáció special: Speciális @@ -659,7 +658,6 @@ hu: view_audit_log_description: Lehetővé teszi, hogy a felhasználó megtekintse a kiszolgáló adminisztratív eseményeinek történetét view_dashboard: Irányítópult megtekintése view_dashboard_description: Lehetővé teszi, hogy a felhasználó elérje az irányítópultot és vele számos metrikát - view_devops: Devops view_devops_description: Lehetővé teszi, hogy a felhasználó elérje a Sidekiq és pgHero irányítópultjait title: Szerepek rules: @@ -1373,7 +1371,6 @@ hu: browser: Böngésző browsers: alipay: Alipay - blackberry: Blackberry chrome: Chrome edge: Microsoft Edge electron: Electron @@ -1387,7 +1384,6 @@ hu: phantom_js: PhantomJS qq: QQ Browser safari: Safari - uc_browser: UCBrowser weibo: Weibo current_session: Jelenlegi munkamenet description: "%{browser} az alábbi platformon: %{platform}" @@ -1396,8 +1392,6 @@ hu: platforms: adobe_air: Adobe Air android: Android - blackberry: Blackberry - chrome_os: ChromeOS firefox_os: Firefox OS ios: iOS linux: Linux diff --git a/config/locales/hy.yml b/config/locales/hy.yml index 5094ca898..e854fb44a 100644 --- a/config/locales/hy.yml +++ b/config/locales/hy.yml @@ -716,7 +716,6 @@ hy: browser: Դիտարկիչ browsers: alipay: Alipay - blackberry: Blackberry chrome: Chrome edge: Microsoft Edge electron: Electron @@ -730,7 +729,6 @@ hy: phantom_js: PhantomJS qq: QQ Browser safari: Safari - uc_browser: UCBrowser weibo: Weibo current_session: Ընթացիկ սեսսիա description: "%{browser}, %{platform}" @@ -738,8 +736,6 @@ hy: platforms: adobe_air: Adobe Air android: Անդրոիդ - blackberry: Blackberry - chrome_os: Chrome OS firefox_os: Firefox OS ios: iOS linux: Լինուքս diff --git a/config/locales/id.yml b/config/locales/id.yml index b42ded815..95660e16d 100644 --- a/config/locales/id.yml +++ b/config/locales/id.yml @@ -595,7 +595,6 @@ id: other: "%{count} pengguna" categories: administration: Administrasi - devops: DevOps invites: Undangan moderation: Moderasi special: Khusus @@ -645,7 +644,6 @@ id: view_audit_log_description: Memungkinkan pengguna untuk melihat riwayat tindakan administratif di server view_dashboard: Lihat Dasbor view_dashboard_description: Memungkinkan pengguna untuk mengakses dasbor dan berbagai metrik - view_devops: DevOps view_devops_description: Memungkinkan pengguna untuk mengakses dasbor Sidekiq dan pgHero title: Peran rules: @@ -1347,7 +1345,6 @@ id: browser: Peramban browsers: alipay: Alipay - blackberry: Blackberry chrome: Chrome edge: Microsoft Edge electron: Electron @@ -1361,7 +1358,6 @@ id: phantom_js: PhantomJS qq: QQ Browser safari: Safari - uc_browser: UCBrowser weibo: Weibo current_session: Sesi sekarang description: "%{browser} di %{platform}" @@ -1370,8 +1366,6 @@ id: platforms: adobe_air: Adobe Air android: Android - blackberry: Blackberry - chrome_os: ChromeOS firefox_os: Firefox OS ios: iOS linux: Linux diff --git a/config/locales/io.yml b/config/locales/io.yml index 5a513f4f7..f8d233475 100644 --- a/config/locales/io.yml +++ b/config/locales/io.yml @@ -605,7 +605,6 @@ io: other: "%{count} uzanti" categories: administration: Administro - devops: Developeri invites: Inviti moderation: Jero special: Specala @@ -656,7 +655,6 @@ io: view_audit_log_description: Permisez uzanti vidar historio di administrala agi en la servilo view_dashboard: Videz chefpanelo view_dashboard_description: Permisez uzanti uzar chefpanelo e diversa opcioni - view_devops: Developeri view_devops_description: Permisez uzanti uzar chefpaneli Sidekiq e pgHero title: Roli rules: @@ -1355,7 +1353,6 @@ io: browser: Vidilo browsers: alipay: Alipay - blackberry: Blackberry chrome: Chrome edge: Microsoft Edge electron: Electron @@ -1369,7 +1366,6 @@ io: phantom_js: PhantomJS qq: Vidilo QQ safari: Safari - uc_browser: UCBrowser weibo: Weibo current_session: Nuna sesiono description: "%{browser} che %{platform}" @@ -1378,8 +1374,6 @@ io: platforms: adobe_air: Adobe Air android: Android - blackberry: Blackberry - chrome_os: Chrome OS firefox_os: Firefox OS ios: iOS linux: Linux diff --git a/config/locales/is.yml b/config/locales/is.yml index 37d8f21b1..3aa43ac22 100644 --- a/config/locales/is.yml +++ b/config/locales/is.yml @@ -608,7 +608,7 @@ is: other: "%{count} notendur" categories: administration: Stjórnun - devops: Kerfisstjórar + devops: DevOps invites: Boðsgestir moderation: Umsjón special: Sérstakt @@ -659,7 +659,7 @@ is: view_audit_log_description: Leyfir notendum að skoða feril stjórnunaraðgerða á netþjóninum view_dashboard: Skoða stjórnborð view_dashboard_description: Leyfir notendum að skoða stjórnborðið og sjá ýmsar mælingar - view_devops: Kerfisstjórar + view_devops: DevOps view_devops_description: Leyfir notendum að skoða Sidekiq og pgHero stjórnborð title: Hlutverk rules: @@ -1387,7 +1387,7 @@ is: phantom_js: PhantomJS qq: QQ vafri safari: Safari - uc_browser: UCBrowser + uc_browser: UC-vafrinn weibo: Weibo current_session: Núverandi seta description: "%{browser} á %{platform}" diff --git a/config/locales/it.yml b/config/locales/it.yml index d3bf4734b..76469eb6a 100644 --- a/config/locales/it.yml +++ b/config/locales/it.yml @@ -608,7 +608,7 @@ it: other: "%{count} utenti" categories: administration: Amministrazione - devops: Devops + devops: DevOps invites: Inviti moderation: Moderazione special: Speciale @@ -659,7 +659,7 @@ it: view_audit_log_description: Consente agli utenti di vedere una cronologia delle azioni amministrative sul server view_dashboard: Mostra dashboard view_dashboard_description: Consente agli utenti di accedere alla dashboard e alle varie metriche - view_devops: Devops + view_devops: DevOps view_devops_description: Consente agli utenti di accedere alle dashboard Sidekiq e pgHero title: Ruoli rules: @@ -1375,7 +1375,7 @@ it: browser: Browser browsers: alipay: Alipay - blackberry: Blackberry + blackberry: BlackBerry chrome: Chrome edge: Microsoft Edge electron: Electron @@ -1389,7 +1389,7 @@ it: phantom_js: PhantomJS qq: QQ Browser safari: Safari - uc_browser: UCBrowser + uc_browser: UC Browser weibo: Weibo current_session: Sessione corrente description: "%{browser} su %{platform}" @@ -1398,7 +1398,7 @@ it: platforms: adobe_air: Adobe Air android: Android - blackberry: Blackberry + blackberry: BlackBerry chrome_os: ChromeOS firefox_os: Firefox OS ios: iOS diff --git a/config/locales/ja.yml b/config/locales/ja.yml index e6ba07305..a60f0298b 100644 --- a/config/locales/ja.yml +++ b/config/locales/ja.yml @@ -1347,7 +1347,7 @@ ja: browser: ブラウザ browsers: alipay: Alipay - blackberry: Blackberry + blackberry: BlackBerry chrome: Chrome edge: Microsoft Edge electron: Electron @@ -1361,7 +1361,7 @@ ja: phantom_js: PhantomJS qq: QQ Browser safari: Safari - uc_browser: UCBrowser + uc_browser: UC Browser weibo: Weibo current_session: 現在のセッション description: "%{platform}上の%{browser}" @@ -1370,7 +1370,7 @@ ja: platforms: adobe_air: Adobe Air android: Android - blackberry: Blackberry + blackberry: BlackBerry chrome_os: ChromeOS firefox_os: Firefox OS ios: iOS diff --git a/config/locales/ka.yml b/config/locales/ka.yml index 5a2fb56a7..464e88268 100644 --- a/config/locales/ka.yml +++ b/config/locales/ka.yml @@ -403,7 +403,6 @@ ka: browser: ბრაუზერი browsers: alipay: ალიფეი - blackberry: ბლექბერი chrome: ქრომი edge: მაიკროსოფთ ედჯი electron: ელექტრონი @@ -417,7 +416,6 @@ ka: phantom_js: ფანტომჯეიესი qq: ქქ ბრაუზერი safari: საფარი - uc_browser: იუსიბიბრაუზერი weibo: ვეიბო current_session: მიმდინარე სესია description: "%{browser} %{platform}-ზე" @@ -426,8 +424,6 @@ ka: platforms: adobe_air: ედობ ეარი android: ანდროიდი - blackberry: ბლექბერი - chrome_os: ქრომო-ოსი firefox_os: ფაირფოქს-ოსი ios: აი-ოსი linux: ლინუქსი diff --git a/config/locales/kab.yml b/config/locales/kab.yml index 1cd5d72d6..9c2539ce7 100644 --- a/config/locales/kab.yml +++ b/config/locales/kab.yml @@ -621,7 +621,6 @@ kab: browser: Iminig browsers: alipay: Alipay - blackberry: Blackberry chrome: Chrome edge: Microsoft Edge electron: Electron @@ -635,7 +634,6 @@ kab: phantom_js: PhantomJS qq: Iminig QQ safari: Safari - uc_browser: UCBrowser weibo: Weibo current_session: Tiγimit tamirant description: "%{browser} s %{platform}" @@ -643,8 +641,6 @@ kab: platforms: adobe_air: Adobe Air android: Android - blackberry: Blackberry - chrome_os: Chrome OS firefox_os: Firefox OS ios: iOS linux: Linux diff --git a/config/locales/kk.yml b/config/locales/kk.yml index 1ac423e99..a48707097 100644 --- a/config/locales/kk.yml +++ b/config/locales/kk.yml @@ -630,7 +630,6 @@ kk: browser: Браузер browsers: alipay: Аlipay - blackberry: Blаckberry chrome: Chrоme edge: Microsоft Edge electron: Electrоn @@ -644,7 +643,6 @@ kk: phantom_js: PhаntomJS qq: QQ Brоwser safari: Safаri - uc_browser: UCBrоwser weibo: Weibо current_session: Қазіргі сессия description: "%{browser} - %{platform}" @@ -653,8 +651,6 @@ kk: platforms: adobe_air: Adobе Air android: Andrоid - blackberry: Blackbеrry - chrome_os: ChromеOS firefox_os: Firefоx OS ios: iОS linux: Lіnux diff --git a/config/locales/ko.yml b/config/locales/ko.yml index f222b0887..74f6f56a8 100644 --- a/config/locales/ko.yml +++ b/config/locales/ko.yml @@ -1363,7 +1363,7 @@ ko: phantom_js: 팬텀JS qq: QQ 브라우저 safari: 사파리 - uc_browser: UC브라우저 + uc_browser: UC 브라우저 weibo: 웨이보 current_session: 현재 세션 description: "%{platform}의 %{browser}" diff --git a/config/locales/ku.yml b/config/locales/ku.yml index 4c2283c21..1c1271c5d 100644 --- a/config/locales/ku.yml +++ b/config/locales/ku.yml @@ -610,7 +610,6 @@ ku: other: "%{count} bikarhêner" categories: administration: Rêvebirî - devops: Devops invites: Vexwendin moderation: Çavdêrî special: Taybet @@ -661,7 +660,6 @@ ku: view_audit_log_description: Mafê dide bikarhêneran ku dîroka çalakiyên rêveberî yên li ser rajekarê bibînin view_dashboard: Destgehê nîşan bide view_dashboard_description: Mafê dide bikarhêneran ku bigihîjin destgehê û pîvanên cuda - view_devops: Pêşdebir view_devops_description: Mafê dide bikarhêneran ku bigihîjin destgehên Sidekiq û pgHero title: Rol rules: @@ -1368,7 +1366,6 @@ ku: browser: Gerok browsers: alipay: Alipay - blackberry: Blackberry chrome: Chrome edge: Microsoft Edge electron: Electron @@ -1382,7 +1379,6 @@ ku: phantom_js: PhantomJS qq: Geroka QQ safari: Safari - uc_browser: Geroka UCB weibo: Weibo current_session: Danişîna heyî description: "%{platform} ser %{browser}" @@ -1391,8 +1387,6 @@ ku: platforms: adobe_air: Adobe Air android: Android - blackberry: Blackberry - chrome_os: Chrome OS firefox_os: Firefox OS ios: iOS linux: Linux diff --git a/config/locales/lv.yml b/config/locales/lv.yml index a7641064b..2c1eaef62 100644 --- a/config/locales/lv.yml +++ b/config/locales/lv.yml @@ -621,7 +621,7 @@ lv: zero: "%{count} lietotāju" categories: administration: Administrēšana - devops: Izstrādātāji + devops: DevOps invites: Uzaicinājumi moderation: Moderācija special: Īpašās @@ -673,7 +673,7 @@ lv: view_audit_log_description: Ļauj lietotājiem redzēt serverī veikto administratīvo darbību vēsturi view_dashboard: Skatīt Informācijas Paneli view_dashboard_description: Ļauj lietotājiem piekļūt informācijas panelim un dažādiem rādītājiem - view_devops: Izstrādātāji + view_devops: DevOps view_devops_description: Ļauj lietotājiem piekļūt Sidekiq un pgHero informācijas paneļiem title: Lomas rules: @@ -1399,7 +1399,7 @@ lv: browser: Pārlūks browsers: alipay: Alipay - blackberry: Blackberry + blackberry: BlackBerry chrome: Chrome edge: Microsoft Edge electron: Electron @@ -1413,7 +1413,7 @@ lv: phantom_js: PhantomJS qq: QQ Browser safari: Safari - uc_browser: UCBrowser + uc_browser: UC Pārlūks weibo: Weibo current_session: Pašreizējā sesija description: "%{browser} uz %{platform}" @@ -1422,8 +1422,8 @@ lv: platforms: adobe_air: Adobe Air android: Android - blackberry: Blackberry - chrome_os: Chrome OS + blackberry: BlackBerry + chrome_os: ChromeOS firefox_os: Firefox OS ios: iOS linux: Linux diff --git a/config/locales/nl.yml b/config/locales/nl.yml index 6d7f8d6aa..6b6f33c16 100644 --- a/config/locales/nl.yml +++ b/config/locales/nl.yml @@ -608,7 +608,6 @@ nl: other: "%{count} gebruikers" categories: administration: Beheer - devops: Devops invites: Uitnodigingen moderation: Moderatie special: Speciaal @@ -659,7 +658,6 @@ nl: view_audit_log_description: Staat gebruikers toe om een geschiedenis van beheeracties op de server te bekijken view_dashboard: Dashboard bekijken view_dashboard_description: Geeft gebruikers toegang tot het dashboard en verschillende statistieken - view_devops: Devops view_devops_description: Geeft gebruikers toegang tot de dashboards van Sidekiq en pgHero title: Rollen rules: @@ -1387,7 +1385,7 @@ nl: phantom_js: PhantomJS qq: QQ Browser safari: Safari - uc_browser: UCBrowser + uc_browser: QQ Browser weibo: Weibo current_session: Huidige sessie description: "%{browser} op %{platform}" @@ -1397,7 +1395,7 @@ nl: adobe_air: Adobe Air android: Android blackberry: Blackberry - chrome_os: Chrome OS + chrome_os: ChromeOS firefox_os: Firefox OS ios: iOS linux: Linux diff --git a/config/locales/nn.yml b/config/locales/nn.yml index 052e7fe8c..4f07c685e 100644 --- a/config/locales/nn.yml +++ b/config/locales/nn.yml @@ -275,7 +275,10 @@ nn: unassigned_report_html: "%{name} løyste ein rapport %{target}" unblock_email_account_html: "%{name} avblokkerte %{target} si e-postadresse" unsensitive_account_html: "%{name} avmarkerte %{target} sitt media som sensitivt" - update_custom_emoji_html: "%{name} oppdaterte emoji %{target}" + unsilence_account_html: "%{name} fjernet begrensningen av %{target}s konto" + update_announcement_html: "%{name} oppdaterte kunngjeringa %{target}" + update_custom_emoji_html: "%{name} oppdaterte emojien %{target}" + update_domain_block_html: "%{name} oppdaterte domeneblokkeringa for %{target}" update_ip_block_html: "%{name} endret regel for IP %{target}" update_status_html: "%{name} oppdaterte innlegg av %{target}" update_user_role_html: "%{name} endret %{target} -rolle" @@ -370,6 +373,7 @@ nn: destroyed_msg: Domeneblokkering har nå blitt angret domain: Domene edit: Rediger domeneblokkering + existing_domain_block: Du har allerede pålagt strengere begrensninger på %{name}. existing_domain_block_html: Du har allerede pålagt strengere begrensninger på %{name}, du kan være nødt til <a href="%{unblock_url}">oppheve blokkeringen av den</a> først. new: create: Lag blokkering @@ -381,7 +385,7 @@ nn: suspend: Utvis title: Ny domeneblokkering obfuscate: Obfuskere domenenavn - obfuscate_hint: Delvis skjule domenenavnet i listen hvis det er aktivert for å annonsere listen over domenebegrensninger + obfuscate_hint: Skjul deler av domenenavnet i listen hvis annonsering av listen over domenebegrensninger er slått på private_comment: Privat kommentar private_comment_hint: Kommenter angående denne domenebegrensningen for internt bruk av moderatorene. public_comment: Offentleg kommentar @@ -431,6 +435,7 @@ nn: comment: Internt notat policies: reject_media: Avvis media + silence: Begrens reason: Offentlig årsak title: Retningslinjer for innhold dashboard: @@ -512,6 +517,8 @@ nn: one: "%{count} notis" other: "%{count} notiser" action_taken_by: Handling gjort av + actions: + silence_description_html: Profilen vil kun være synlig for dem som allerede følger den eller manuelt slår den opp, noe som sterkt begrenser dens rekkevidde. Kan alltid tilbakestilles. are_you_sure: Er du sikker? assign_to_self: Tilegn til meg assigned: Tilsett moderator @@ -551,6 +558,8 @@ nn: administration: Administrasjon devops: DevOps invites: Invitasjoner + privileges: + view_devops: DevOps rules: add_new: Legg til et filter delete: Slett @@ -579,6 +588,9 @@ nn: no_status_selected: Ingen statusar vart endra sidan ingen vart valde title: Kontostatusar with_media: Med media + strikes: + actions: + silence: "%{name} begrenset %{target}s konto" system_checks: database_schema_check: message_html: Det venter på databaseoverføringer. Vennligst kjør disse for å sikre at applikasjonen oppfører seg som forventet @@ -595,6 +607,9 @@ nn: edit_preset: Endr åtvaringsoppsett title: Handsam åtvaringsoppsett admin_mailer: + new_appeal: + actions: + silence: for å begrense deres konto new_pending_account: body: Detaljer om den nye kontoen er nedenfor. Du kan godkjenne eller avvise denne søknaden. subject: Ny konto opp til vurdering på %{instance} (%{username}) @@ -671,6 +686,7 @@ nn: confirming: Ventar på stadfesting av e-post. pending: Søknaden din ventar på gjennomgang frå personalet vårt. Dette kan taka litt tid. Du får ein e-post om søknaden din vert godkjend. redirecting_to: Kontoen din er inaktiv fordi den for øyeblikket omdirigerer til %{acct}. + view_strikes: Vis tidligere advarsler mot kontoen din use_security_key: Bruk sikkerhetsnøkkel authorize_follow: already_following: Du fylgjer allereie denne kontoen @@ -724,6 +740,11 @@ nn: more_details_html: For fleire detaljar, sjå <a href="%{terms_path}">personvernsvilkåra</a>. username_available: Brukarnamnet ditt vert tilgjengeleg igjen username_unavailable: Brukarnamnet ditt kjem til å halda seg utilgjengeleg + disputes: + strikes: + appeal_approved: Denne advarselen ble anket og er ikke lenger gyldig + title_actions: + silence: Begrensning av konto domain_validator: invalid_domain: er ikkje eit gangbart domenenamn errors: @@ -797,6 +818,8 @@ nn: html_validator: invalid_markup: 'rommar ugild HTML-kode: %{error}' imports: + errors: + over_rows_processing_limit: inneholder flere enn %{count} rader modes: merge: Set saman merge_long: Hald på eksisterande data og legg til nye @@ -998,7 +1021,7 @@ nn: phantom_js: PhantomJS qq: QQ-lesar safari: Safari - uc_browser: UC-lesar + uc_browser: QQ-lesar weibo: Weibo current_session: Noverande økt description: "%{browser} på %{platform}" @@ -1008,7 +1031,7 @@ nn: adobe_air: Adobe Air android: Android blackberry: BlackBerry - chrome_os: Chrome OS + chrome_os: ChromeOS firefox_os: Firefox OS ios: IOS linux: Linux diff --git a/config/locales/no.yml b/config/locales/no.yml index 0e379da21..7ce3d16d4 100644 --- a/config/locales/no.yml +++ b/config/locales/no.yml @@ -92,14 +92,14 @@ active: Aktive all: Alle pending: Avventer - silenced: Stilnet + silenced: Begrenset suspended: Utvist title: Moderasjon moderation_notes: Moderasjonsnotater most_recent_activity: Nyligste aktivitet most_recent_ip: Nyligste IP no_account_selected: Ingen brukere ble forandret da ingen var valgt - no_limits_imposed: Ingen grenser er tatt i bruk + no_limits_imposed: Ingen pålagte begrensninger no_role_assigned: Ingen rolle tildelt not_subscribed: Ikke abonnért pending: Avventer gjennomgang @@ -140,8 +140,8 @@ show: created_reports: Rapporter laget av denne kontoen targeted_reports: Rapporter laget om denne kontoen - silence: Målbind - silenced: Stilnet + silence: Begrens + silenced: Begrenset statuses: Statuser strikes: Tidligere advarsler subscribe: Abonnere @@ -154,9 +154,9 @@ unblocked_email_msg: Fjernet blokkering av %{username} sin e-postadresse unconfirmed_email: Ubekreftet E-postadresse undo_sensitized: Gjør om tving sensitiv - undo_silenced: Angre målbinding + undo_silenced: Angre begrensning undo_suspension: Angre utvisning - unsilenced_msg: Opphevde vellykket begrensningen av %{username} sin konto + unsilenced_msg: Opphevde begrensningen av %{username}s konto unsubscribe: Avslutt abonnementet unsuspended_msg: Opphevde vellykket suspenderingen av %{username} sin konto username: Brukernavn @@ -211,11 +211,12 @@ reset_password_user: Tilbakestill passord resolve_report: Løs rapport sensitive_account: Tving sensitiv konto - silence_account: Demp konto + silence_account: Begrens konto suspend_account: Suspender kontoen unassigned_report: Fjern tilordnet rapport unblock_email_account: Fjern blokkering av e-postadresse unsensitive_account: Angre tving sensitiv konto + unsilence_account: Angre begrensning av konto unsuspend_account: Opphev suspensjonen av kontoen update_announcement: Oppdater kunngjøringen update_custom_emoji: Oppdater tilpasset Emoji @@ -244,7 +245,8 @@ destroy_user_role_html: "%{name} slettet %{target} -rolle" reject_user_html: "%{name} avslo registrering fra %{target}" reset_password_user_html: "%{name} tilbakestille passordet for brukeren %{target}" - silence_account_html: "%{name} begrenset %{target} sin konto" + silence_account_html: "%{name} begrenset %{target}s konto" + unsilence_account_html: "%{name} fjernet begrensningen av %{target}s konto" update_custom_emoji_html: "%{name} oppdaterte emoji %{target}" update_ip_block_html: "%{name} endret regel for IP %{target}" update_status_html: "%{name} oppdaterte innlegg av %{target}" @@ -330,7 +332,8 @@ destroyed_msg: Domeneblokkering har nå blitt angret domain: Domene edit: Rediger domeneblokkering - existing_domain_block_html: Du har allerede pålagt strengere begrensninger på %{name}, du kan være nødt til <a href="%{unblock_url}">oppheve blokkeringen av den</a> først. + existing_domain_block: Du har allerede pålagt strengere begrensninger på %{name}. + existing_domain_block_html: Du har allerede pålagt strengere begrensninger på %{name}, du må <a href="%{unblock_url}">oppheve blokkeringen av den</a> først. new: create: Lag blokkering hint: Domeneblokkeringen vil ikke hindre opprettelse av kontooppføringer i databasen, men vil retroaktivt og automatisk benytte spesifikke moderasjonsmetoder på de kontoene. @@ -341,11 +344,11 @@ suspend: Utvis title: Ny domeneblokkering obfuscate: Obfuskere domenenavn - obfuscate_hint: Delvis skjule domenenavnet i listen hvis det er aktivert for å annonsere listen over domenebegrensninger + obfuscate_hint: Skjul deler av domenenavnet i listen hvis annonsering av listen over domenebegrensninger er slått på private_comment: Privat kommentar - private_comment_hint: Kommenter angående denne domenebegrensningen for internt bruk av moderatorene. + private_comment_hint: Kommentar angående denne domenebegrensningen for internt bruk av moderatorene. public_comment: Offentlig kommentar - public_comment_hint: Kommenter angående denne domenebegrensningen for offentligheten, hvis publisering av domenebegrensningslisten er slått på. + public_comment_hint: Kommentar angående denne domenebegrensningen for offentligheten, hvis publisering av listen over domenebegrensninger er slått på. reject_media: Avvis mediefiler reject_media_hint: Fjerner lokalt lagrede mediefiler og nekter å laste dem ned i fremtiden. Irrelevant for utvisninger reject_reports: Avslå rapporter @@ -386,6 +389,7 @@ comment: Internt notat policies: reject_media: Avvis media + silence: Begrens reason: Offentlig årsak title: Retningslinjer for innhold dashboard: @@ -455,7 +459,7 @@ pending: Avventer overgangens godkjenning save_and_enable: Lagre og skru på setup: Sett opp en overgangsforbindelse - signatures_not_enabled: Overganger vil ikke fungere riktig mens sikkermodus eller hvitelistingsmodus er skrudd på + signatures_not_enabled: Videreformidlere vil ikke fungere riktig mens sikkermodus eller begrenset føderasjon er aktiv status: Status title: Overganger report_notes: @@ -467,6 +471,8 @@ one: "%{count} notis" other: "%{count} notiser" action_taken_by: Handling utført av + actions: + silence_description_html: Profilen vil kun være synlig for dem som allerede følger den eller manuelt slår den opp, noe som sterkt begrenser dens rekkevidde. Kan alltid tilbakestilles. are_you_sure: Er du sikker? assign_to_self: Tilegn til meg assigned: Tilegnet moderator @@ -506,6 +512,8 @@ administration: Administrasjon devops: DevOps invites: Invitasjoner + privileges: + view_devops: DevOps rules: add_new: Legg til et filter delete: Slett @@ -534,6 +542,9 @@ no_status_selected: Ingen statuser ble endret da ingen ble valgt title: Kontostatuser with_media: Med media + strikes: + actions: + silence: "%{name} begrenset %{target}s konto" system_checks: database_schema_check: message_html: Det venter på databaseoverføringer. Vennligst kjør disse for å sikre at applikasjonen oppfører seg som forventet @@ -547,6 +558,9 @@ add_new: Legg til ny delete: Slett admin_mailer: + new_appeal: + actions: + silence: for å begrense deres konto new_pending_account: body: Detaljer om den nye kontoen er nedenfor. Du kan godkjenne eller avvise denne søknaden. subject: Ny konto opp til vurdering på %{instance} (%{username}) @@ -569,7 +583,7 @@ body: Mastodon er oversatt av frivillige. guide_link_text: Alle kan bidra. sensitive_content: Sensitivt innhold - toot_layout: Tut-utseende + toot_layout: Innleggsoppsett application_mailer: notification_preferences: Endre E-postinnstillingene salutation: "%{name}," @@ -621,6 +635,7 @@ confirming: Venter på at e-postbekreftelsen er fullført. pending: Søknaden din avventer gjennomgang av styret vårt. Dette kan ta litt tid. Du vil motta en E-post dersom søknaden din blir godkjent. redirecting_to: Kontoen din er inaktiv fordi den for øyeblikket omdirigerer til %{acct}. + view_strikes: Vis tidligere advarsler mot kontoen din use_security_key: Bruk sikkerhetsnøkkel authorize_follow: already_following: Du følger allerede denne kontoen @@ -673,6 +688,11 @@ more_details_html: For mere detaljer, se <a href="%{terms_path}">privatlivsretningslinjene</a>. username_available: Brukernavnet ditt vil bli gjort tilgjengelig igjen username_unavailable: Brukernavnet ditt vil forbli utilgjengelig + disputes: + strikes: + appeal_approved: Denne advarselen ble anket og er ikke lenger gyldig + title_actions: + silence: Begrensning av konto domain_validator: invalid_domain: er ikke et gyldig domenenavn errors: @@ -710,6 +730,8 @@ storage: Medialagring featured_tags: add_new: Legg til ny + errors: + limit: Du har allerede fremhevet det maksimale antal hashtags hint_html: "<strong>Hva er utvalgte emneknagger?</strong> De vises frem tydelig på din offentlige profil, og lar folk bla i dine offentlige innlegg som spesifikt har de emneknaggene. De er et bra verktøy for å holde styr på kreative verk eller langtidsprosjekter." filters: contexts: @@ -740,6 +762,8 @@ one: Noe er ikke helt riktig ennå. Vennligst se etter en gang til other: Noe er ikke helt riktig ennå. Det er ennå %{count} feil å rette på imports: + errors: + over_rows_processing_limit: inneholder flere enn %{count} rader modes: merge: Slå sammen overwrite: Overskriv @@ -892,7 +916,7 @@ public_timelines: Offentlige tidslinjer reactions: errors: - limit_reached: Grensen for forskjellige reaksjoner nådd + limit_reached: Grensen for ulike reaksjoner nådd unrecognized_emoji: er ikke en gjenkjent emoji relationships: activity: Kontoaktivitet @@ -919,7 +943,7 @@ tag: 'Offentlige innlegg merket med #%{hashtag}' scheduled_statuses: over_daily_limit: Du har overskredet grensen på %{limit} planlagte tuter for den dagen - over_total_limit: Du har overskredet grensen på %{limit} planlagte tuter + over_total_limit: Du har overskredet grensen på %{limit} planlagte innlegg too_soon: Den planlagte datoen må være i fremtiden sessions: activity: Siste aktivitet @@ -950,7 +974,7 @@ adobe_air: Adobe Air android: Android blackberry: BlackBerry - chrome_os: Chrome OS + chrome_os: ChromeOS firefox_os: Firefox OS ios: iOS linux: Linux @@ -1007,10 +1031,10 @@ errors: in_reply_not_found: Posten du prøver å svare ser ikke ut til eksisterer. open_in_web: Åpne i nettleser - over_character_limit: grense på %{max} tegn overskredet + over_character_limit: grensen på %{max} tegn overskredet pin_errors: direct: Innlegg som bare er synlige for nevnte brukere kan ikke festes - limit: Du har allerede festet det maksimale antall tuter + limit: Du har allerede festet det maksimale antall innlegg ownership: Kun egne tuter kan festes reblog: En fremheving kan ikke festes poll: @@ -1053,6 +1077,9 @@ pinned: Festet tut reblogged: fremhevde sensitive_content: Følsomt innhold + strikes: + errors: + too_late: Det er for sent å klage på denne advarselen tags: does_not_match_previous_name: samsvarer ikke med det forrige navnet themes: diff --git a/config/locales/oc.yml b/config/locales/oc.yml index 37c470d31..d6bf5a531 100644 --- a/config/locales/oc.yml +++ b/config/locales/oc.yml @@ -806,7 +806,6 @@ oc: browser: Navigator browsers: alipay: Alipay - blackberry: Blackberry chrome: Chrome edge: Microsoft Edge electron: Electron @@ -820,7 +819,6 @@ oc: phantom_js: PhantomJS qq: QQ Browser safari: Safari - uc_browser: UCBrowser weibo: Weibo current_session: Session en cors description: "%{browser} sus %{platform}" @@ -829,8 +827,6 @@ oc: platforms: adobe_air: Adobe Air android: Android - blackberry: Blackberry - chrome_os: ChromeOS firefox_os: Firefox OS ios: iOS linux: Linux diff --git a/config/locales/pl.yml b/config/locales/pl.yml index 72bd61bd3..dc96acee7 100644 --- a/config/locales/pl.yml +++ b/config/locales/pl.yml @@ -1,10 +1,10 @@ --- pl: about: - about_mastodon_html: Mastodon jest wolną i otwartą siecią społecznościową, zdecentralizowaną alternatywą dla zamkniętych, komercyjnych platform. + about_mastodon_html: 'Sieć społecznościowa przyszłości: Bez reklam, bez inwigilacji, zaprojektowana etycznie i zdecentralizowanie! Władaj swoimi danymi z Mastodonem!' contact_missing: Nie ustawiono contact_unavailable: Nie dotyczy - hosted_on: Mastodon uruchomiony na %{domain} + hosted_on: Mastodon hostowany na %{domain} title: O nas accounts: follow: Obserwuj @@ -63,7 +63,7 @@ pl: destroyed_msg: Dane %{username} są teraz w kolejce do natychmiastowego usunięcia disable: Dezaktywuj disable_sign_in_token_auth: Wyłącz uwierzytelnianie tokenu e-mail - disable_two_factor_authentication: Wyłącz uwierzytelnianie dwuetapowe + disable_two_factor_authentication: Wyłącz uwierzytelnianie dwuskładnikowe disabled: Dezaktywowano display_name: Wyświetlana nazwa domain: Domena @@ -81,7 +81,7 @@ pl: invite_request_text: Powody rejestracji invited_by: Zaproszony(-a) przez ip: Adres IP - joined: Dołączył(-a) + joined: Dołączono location: all: Wszystkie local: Lokalne @@ -135,13 +135,13 @@ pl: resubscribe: Ponów subskrypcję role: Rola search: Szukaj - search_same_email_domain: Inni użytkownicy z e-mail w tej domenie + search_same_email_domain: Inni użytkownicy z tym samym e-mail w tej domenie search_same_ip: Inni użytkownicy z tym samym IP security_measures: only_password: Tylko hasło password_and_2fa: Hasło i 2FA sensitive: Wrażliwe - sensitized: oznaczono jako wrażliwe + sensitized: Oznaczono jako wrażliwe shared_inbox_url: Adres udostępnianej skrzynki show: created_reports: Zgłoszenia tego użytkownika @@ -259,7 +259,7 @@ pl: destroy_status_html: "%{name} usunął(-ęła) wpis użytkownika %{target}" destroy_unavailable_domain_html: "%{name} wznowił(a) doręczanie do domeny %{target}" destroy_user_role_html: "%{name} usunął rolę %{target}" - disable_2fa_user_html: "%{name} wyłączył(a) uwierzytelnianie dwustopniowe użytkownikowi %{target}" + disable_2fa_user_html: "%{name} wyłączył(a) uwierzytelnianie dwuskładnikowe użytkownikowi %{target}" disable_custom_emoji_html: "%{name} wyłączył(a) emoji %{target}" disable_sign_in_token_auth_user_html: "%{name} wyłączył/a uwierzytelnianie tokenem e-mail dla %{target}" disable_user_html: "%{name} zablokował(a) możliwość logowania użytkownikowi %{target}" @@ -687,7 +687,7 @@ pl: view_audit_log_description: Pozwala użytkownikom zobaczyć historię działań administracyjnych na serwerze view_dashboard: Wyświetl panel view_dashboard_description: Pozwala użytkownikom na dostęp do panelu i różnych metryk - view_devops: Devops + view_devops: DevOps view_devops_description: Pozwala użytkownikom na dostęp do paneli Sidekiq i pgHero title: Role rules: @@ -1425,7 +1425,7 @@ pl: browser: Przeglądarka browsers: alipay: Alipay - blackberry: Blackberry + blackberry: BlackBerry chrome: Chrome edge: Microsoft Edge electron: Electron @@ -1439,7 +1439,7 @@ pl: phantom_js: PhantomJS qq: QQ Browser safari: Safari - uc_browser: UCBrowser + uc_browser: UC Browser weibo: Weibo current_session: Obecna sesja description: "%{browser} na %{platform}" @@ -1448,7 +1448,7 @@ pl: platforms: adobe_air: Adobe Air android: Android - blackberry: Blackberry + blackberry: BlackBerry chrome_os: ChromeOS firefox_os: Firefox OS ios: iOS @@ -1609,7 +1609,7 @@ pl: enabled_success: Pomyślnie aktywowano uwierzytelnianie dwuetapowe generate_recovery_codes: Generuj kody zapasowe lost_recovery_codes: Kody zapasowe pozwolą uzyskać dostęp do portalu, jeżeli utracisz dostęp do telefonu. Jeżeli utracisz dostęp do nich, możesz wygenerować je ponownie tutaj. Poprzednie zostaną unieważnione. - methods: Metody uwierzytelniania dwuetapowego + methods: Metody uwierzytelniania dwuskładnikowego otp: Aplikacja uwierzytelniająca recovery_codes: Przywróć kody zapasowe recovery_codes_regenerated: Pomyślnie wygenerowano ponownie kody zapasowe @@ -1682,7 +1682,7 @@ pl: invalid_otp_token: Kod uwierzytelniający jest niepoprawny otp_lost_help_html: Jeżeli utracisz dostęp do obu, możesz skontaktować się z %{email} seamless_external_login: Zalogowano z użyciem zewnętrznej usługi, więc ustawienia hasła i adresu e-mail nie są dostępne. - signed_in_as: 'Zalogowany jako:' + signed_in_as: 'Zalogowano jako:' verification: explanation_html: 'Możesz <strong>zweryfikować siebie jako właściciela stron, do których odnośniki znajdują się w metadanych</strong>. Aby to zrobić, strona musi zawierać odnośnik do Twojego profilu na Mastodonie. Odnośnik <strong>musi</strong> zawierać atrybut <code>rel="me"</code>. Jego zawartość nie ma znaczenia. Przykład:' verification: Weryfikacja diff --git a/config/locales/pt-BR.yml b/config/locales/pt-BR.yml index 8279f68f0..6d3fbf60f 100644 --- a/config/locales/pt-BR.yml +++ b/config/locales/pt-BR.yml @@ -610,7 +610,6 @@ pt-BR: other: "%{count} usuários" categories: administration: Administração - devops: Devops invites: Convites moderation: Moderação special: Especial @@ -661,7 +660,6 @@ pt-BR: view_audit_log_description: Permite aos usuários ver um histórico de ações administrativas no servidor view_dashboard: Ver painel view_dashboard_description: Permite que os usuários acessem o painel e várias métricas - view_devops: Devops view_devops_description: Permite aos usuários acessar os painéis da Sidekiq e pgHero title: Funções rules: @@ -810,6 +808,9 @@ pt-BR: trending_rank: 'Em alta #%{rank}' usable: Pode ser usado usage_comparison: Usado %{today} vezes hoje, em comparação com %{yesterday} de ontem + used_by_over_week: + one: Usado por uma pessoa na última semana + other: Usado por %{count} pessoas na última semana title: Em alta trending: Em alta warning_presets: @@ -1333,7 +1334,6 @@ pt-BR: browser: Navegador browsers: alipay: Alipay - blackberry: BlackBerry chrome: Chrome edge: Microsoft Edge electron: Electron @@ -1347,7 +1347,6 @@ pt-BR: phantom_js: PhantomJS qq: QQ Browser safari: Safari - uc_browser: UCBrowser weibo: Weibo current_session: Sessão atual description: "%{browser} em %{platform}" @@ -1356,8 +1355,6 @@ pt-BR: platforms: adobe_air: Adobe Air android: Android - blackberry: BlackBerry - chrome_os: Chrome OS firefox_os: Firefox OS ios: iOS linux: Linux diff --git a/config/locales/pt-PT.yml b/config/locales/pt-PT.yml index e299cee8b..a477b07d0 100644 --- a/config/locales/pt-PT.yml +++ b/config/locales/pt-PT.yml @@ -1387,7 +1387,7 @@ pt-PT: phantom_js: PhantomJS qq: QQ Browser safari: Safari - uc_browser: UCBrowser + uc_browser: Navegador UC weibo: Weibo current_session: Sessão atual description: "%{browser} em %{platform}" diff --git a/config/locales/ru.yml b/config/locales/ru.yml index cfdceff8e..4ad5fc83a 100644 --- a/config/locales/ru.yml +++ b/config/locales/ru.yml @@ -619,7 +619,6 @@ ru: other: "%{count} пользователей" categories: administration: Администрация - devops: DevOps invites: Приглашения moderation: Модерация special: Особые @@ -653,7 +652,6 @@ ru: view_audit_log: Посмотреть журнал аудита view_audit_log_description: Позволяет пользователям просматривать историю административных действий на сервере view_dashboard: Открыть панель управления - view_devops: DevOps title: Роли rules: add_new: Добавить правило @@ -1313,7 +1311,6 @@ ru: browser: Браузер browsers: alipay: Alipay - blackberry: Blackberry chrome: Chrome edge: Microsoft Edge electron: Electron @@ -1327,7 +1324,6 @@ ru: phantom_js: PhantomJS qq: QQ Browser safari: Safari - uc_browser: UCBrowser weibo: Weibo current_session: Текущая сессия description: "%{browser} на %{platform}" @@ -1336,8 +1332,6 @@ ru: platforms: adobe_air: Adobe Air android: Android - blackberry: Blackberry - chrome_os: ChromeOS firefox_os: Firefox OS ios: iOS linux: Linux diff --git a/config/locales/sc.yml b/config/locales/sc.yml index bf24b2686..00ccd22db 100644 --- a/config/locales/sc.yml +++ b/config/locales/sc.yml @@ -862,7 +862,6 @@ sc: browser: Navigadore browsers: alipay: Alipay - blackberry: Blackberry chrome: Chrome edge: Microsoft Edge electron: Electron @@ -876,7 +875,6 @@ sc: phantom_js: PhantomJS qq: QQ Browser safari: Safari - uc_browser: UCBrowser weibo: Weibo current_session: Sessione atuale description: "%{browser} de %{platform}" @@ -885,8 +883,6 @@ sc: platforms: adobe_air: Adobe Air android: Android - blackberry: Blackberry - chrome_os: ChromeOS firefox_os: Firefox OS ios: iOS linux: Linux diff --git a/config/locales/si.yml b/config/locales/si.yml index 2c41e40b8..42aaf6c89 100644 --- a/config/locales/si.yml +++ b/config/locales/si.yml @@ -1194,7 +1194,6 @@ si: browser: අතිරික්සුව browsers: alipay: අලිපේ - blackberry: බ්ලැක්බෙරි chrome: ක්රෝම් edge: මයික්රොසොෆ්ට් එඩ්ගේ electron: ඉලෙක්ට්රෝන් @@ -1207,7 +1206,6 @@ si: otter: ඔටර් qq: කියුකියු අතිරික්සුව safari: සෆාරි - uc_browser: යූසී අතිරික්සුව weibo: වෙයිබො current_session: වත්මන් සැසිය description: "%{browser} මත %{platform}" @@ -1216,8 +1214,6 @@ si: platforms: adobe_air: ඇඩෝබි එයාර් android: ඇන්ඩ්රොයිඩ් - blackberry: බ්ලැක්බෙරි - chrome_os: ක්රෝම් ඕඑස් firefox_os: ෆයර්ෆොක්ස් ඕඑස් ios: අයිඕඑස් linux: ලිනක්ස් diff --git a/config/locales/simple_form.ar.yml b/config/locales/simple_form.ar.yml index fe381cce9..6eaff01a8 100644 --- a/config/locales/simple_form.ar.yml +++ b/config/locales/simple_form.ar.yml @@ -64,9 +64,36 @@ ar: domain_allow: domain: سيكون بإمكان هذا النطاق جلب البيانات من هذا الخادم ومعالجة وتخزين البيانات الواردة منه email_domain_block: + domain: يمكن أن يكون هذا اسم المجال الذي يظهر في عنوان البريد الإلكتروني أو سجل MX الذي يستخدمه. سيتم التحقق منه عند التسجيل. with_dns_records: سوف تُبذل محاولة لحل سجلات DNS الخاصة بالنطاق المعني، كما ستُمنع النتائج + featured_tag: + name: 'فيما يلي بعض الوسوم التي استخدمتها مؤخراً:' + filters: + action: اختر الإجراء الذي سينفذ عند تطابق المشاركة فلتر التصفية + actions: + hide: إخفاء المحتويات التي تم تصفيتها، والتصرف كما لو أنها غير موجودة + warn: إخفاء المحتوى الذي تم تصفيته خلف تحذير يذكر عنوان الفلتر form_admin_settings: + backups_retention_period: الاحتفاظ بأرشيف المستخدم الذي تم إنشاؤه لعدد محدد من الأيام. + bootstrap_timeline_accounts: سيتم تثبيت هذه الحسابات على قمة التوصيات للمستخدمين الجدد. + closed_registrations_message: ما سيعرض عند إغلاق التسجيلات + content_cache_retention_period: سيتم حذف المشاركات من الخوادم الأخرى بعد عدد الأيام المحدد عند تعيينها إلى قيمة موجبة. قد يكون هذا لا رجعة فيه. + custom_css: يمكنك تطبيق أساليب مخصصة على نسخة الويب من ماستدون. + mascot: تجاوز الرسوم التوضيحية في واجهة الويب المتقدمة. + media_cache_retention_period: سيتم حذف ملفات الوسائط التي تم تنزيلها بعد عدد الأيام المحدد عند تعيينها إلى قيمة موجبة، وإعادة تنزيلها عند الطلب. + profile_directory: دليل الملف الشخصي يسرد جميع المستخدمين الذين اختاروا الدخول ليكونوا قابلين للاكتشاف. + require_invite_text: عندما تتطلب التسجيلات الموافقة اليدوية، اجعل إدخال النص "لماذا تريد الانضمام ؟" إلزاميا بدلا من اختياري + site_contact_email: كيف يمكن للأشخاص أن يصلوا إليك للحصول على استفسارات قانونية أو استفسارات دعم. site_contact_username: كيف يمكن للناس أن يصلوا إليك في ماستدون. + site_extended_description: أي معلومات إضافية قد تكون مفيدة للزوار والمستخدمين. يمكن تنظيمها مع بناء بنية Markdown. + site_short_description: وصف قصير للمساعدة في التعرف على الخادم الخاص بك. من يقوم بتشغيله، ولمن ؟ + site_terms: استخدم سياسة الخصوصية الخاصة بك أو اتركها فارغة لاستخدام الافتراضي. يمكن هيكلتها مع بناء الجملة المصغرة مارك داون. + site_title: كيف يمكن للناس الرجوع إلى الخادم الخاص بك إلى جانب اسم النطاق. + theme: الشكل الذي يشاهده الزوار الجدد و الغير مسجلين الدخول. + thumbnail: عرض حوالي 2:1 صورة إلى جانب معلومات الخادم الخاص بك. + timeline_preview: الزوار الذين سجلوا خروجهم سيكونون قادرين على تصفح أحدث المشاركات العامة المتاحة على الخادم. + trendable_by_default: تخطي مراجعة المحتوى التريند اليدوي. لا يزال من الممكن الإزالة اللاحقة للعناصر الفردية من التريندات. + trends: تظهر التريندز أي المشاركات وعلامات وقصص الأخبار التي تجذب الانتباه على الخادم الخاص بك. form_challenge: current_password: إنك بصدد الدخول إلى منطقة آمنة imports: @@ -91,6 +118,13 @@ ar: name: يمكنك فقط تغيير غلاف الحروف ، على سبيل المثال ، لجعلها أكثر قابلية للقراءة user: chosen_languages: إن تم اختيارها، فلن تظهر على الخيوط العامة إلّا الرسائل المنشورة في تلك اللغات + role: الوظيفة تتحكم في الصلاحيات التي يملكها المستخدم + user_role: + color: اللون الذي سيتم استخدامه للوظيفه في جميع وحدات واجهة المستخدم، كـ RGB بتنسيق hex + highlighted: وهذا يجعل الوظيفه مرئيا علنا + name: الاسم العام للوظيفه، إذا تم تعيين الوظيفه ليتم عرضه كشارة + permissions_as_keys: سيكون للمستخدمين الذين لديهم هذه الوظيفة حق الصلاحيه إلى... + position: وتقرر الوظيفة الأعلى تسوية النزاعات في حالات معينة، ولا يمكن القيام ببعض الإجراءات إلا على أساس الوظائف ذات الأولوية الأقل labels: account: fields: diff --git a/config/locales/simple_form.de.yml b/config/locales/simple_form.de.yml index 67add72b0..f9880a38f 100644 --- a/config/locales/simple_form.de.yml +++ b/config/locales/simple_form.de.yml @@ -51,13 +51,13 @@ de: setting_aggregate_reblogs: Zeige denselben Beitrag nicht nochmal an, wenn er erneut geteilt wurde (dies betrifft nur neulich erhaltene erneut geteilte Beiträge) setting_always_send_emails: Normalerweise werden Benachrichtigungen nicht per E-Mail verschickt, wenn du gerade auf Mastodon aktiv bist setting_default_sensitive: Medien, die mit einer Inhaltswarnung (NSFW) versehen worden sind, werden – je nach Einstellung – erst nach einem zusätzlichen Klick angezeigt - setting_display_media_default: Verberge alle Medien, die mit einer Inhaltswarnung (NSFW) versehen sind - setting_display_media_hide_all: Alle Medien immer verstecken + setting_display_media_default: Alle Medien verbergen, die mit einer Inhaltswarnung (NSFW) versehen sind + setting_display_media_hide_all: Alle Medien immer verbergen setting_display_media_show_all: Alle Medien immer anzeigen setting_hide_network: Wem du folgst und wer dir folgt, wird in deinem Profil nicht angezeigt setting_noindex: Betrifft alle öffentlichen Daten deines Profils, z. B. deine Beiträge, Account-Empfehlungen und „Über mich“ setting_show_application: Die Anwendung die du nutzt wird in der detaillierten Ansicht deiner Beiträge angezeigt - setting_use_blurhash: Die Farbverläufe basieren auf den Farben der versteckten Medien, aber verstecken jegliche Details + setting_use_blurhash: Die Farbverläufe basieren auf den Farben der verborgenen Medien, aber verstecken jegliche Details setting_use_pending_items: Neue Beiträge hinter einem Klick verstecken, anstatt automatisch zu scrollen username: Dein Benutzername wird auf %{domain} einzigartig sein whole_word: Wenn das Wort oder die Formulierung nur aus Buchstaben oder Zahlen besteht, tritt der Filter nur dann in Kraft, wenn er exakt dieser Zeichenfolge entspricht @@ -78,22 +78,22 @@ de: bootstrap_timeline_accounts: Diese Konten werden bei den Folge-Empfehlungen für neue Nutzerinnen und Nutzer oben angeheftet. closed_registrations_message: Wird angezeigt, wenn Anmeldungen geschlossen sind content_cache_retention_period: Beiträge von anderen Servern werden nach der angegebenen Anzahl von Tagen, wenn sie auf einen positiven Wert gesetzt werden, gelöscht. Dies kann eventuell nicht rückgängig gemacht werden. - custom_css: Sie können benutzerdefinierte Stile auf die Web-Version von Mastodon anwenden. + custom_css: Du kannst benutzerdefinierte Stile auf die Web-Version von Mastodon anwenden. mascot: Überschreibt die Abbildung in der erweiterten Weboberfläche. media_cache_retention_period: Heruntergeladene Mediendateien werden nach der angegebenen Anzahl von Tagen, wenn sie auf einen positiven Wert gesetzt werden, gelöscht und bei Bedarf erneut heruntergeladen. profile_directory: Das Profilverzeichnis listet alle Benutzer auf, die sich für die Auffindbarkeit entschieden haben. - require_invite_text: Wenn Anmeldungen eine manuelle Genehmigung erfordern, machen Sie die Texteingabe „Warum möchten Sie beitreten?” obligatorisch und nicht optional. - site_contact_email: Wie man Sie bei rechtlichen oder unterstützenden Fragen erreichen kann. - site_contact_username: Wie man Sie auf Mastodon erreichen kann. + require_invite_text: Wenn Registrierungen eine manuelle Genehmigung erfordern, dann werden Nutzer einen Grund für ihre Registrierung angeben müssen + site_contact_email: Wie man dich oder dein Team bei rechtlichen oder unterstützenden Fragen erreichen kann. + site_contact_username: Wie man dich oder dein Team auf Mastodon erreichen kann. site_extended_description: Alle zusätzlichen Informationen, die für Besucher und Nutzer nützlich sein könnten. Kann mit der Markdown-Syntax strukturiert werden. - site_short_description: Eine kurze Beschreibung zur eindeutigen Identifizierung Ihres Servers. Wer betreibt ihn, für wen ist er bestimmt? - site_terms: Verwenden Sie Ihre eigene Datenschutzrichtlinie oder lassen Sie sie leer, um die Standardeinstellung zu verwenden. Kann mit Markdown-Syntax strukturiert werden. - site_title: Wie Personen neben dem Domainnamen auf Ihren Server verweisen können. - theme: Design, das abgemeldete und neue Benutzer*innen. + site_short_description: Eine kurze Beschreibung zur eindeutigen Identifizierung des Servers. Wer betreibt ihn, für wen ist er bestimmt? + site_terms: Verwende eine eigene Datenschutzrichtlinie oder lasse das Feld leer, um die Standardeinstellung zu verwenden. Kann mit Markdown-Syntax strukturiert werden. + site_title: Wie Personen neben dem Domainnamen auf deinen Server verweisen können. + theme: Das Design, das abgemeldete Besucher und neue Benutzer sehen. thumbnail: Ein Bild ungefähr im 2:1-Format, das neben den Server-Informationen angezeigt wird. timeline_preview: Ausgeloggte Besucherinnen und Besucher können die neuesten öffentlichen Beiträge auf dem Server ansehen. trendable_by_default: Manuelles Überprüfen angesagter Inhalte überspringen. Einzelne Elemente können später noch aus den Trends entfernt werden. - trends: Trends zeigen, welche Beiträge, Hashtags und Nachrichten auf Ihrem Server an Bedeutung gewinnen. + trends: Trends zeigen, welche Beiträge, Hashtags und Nachrichten auf deinem Server immer beliebter werden. form_challenge: current_password: Du betrittst einen sicheren Bereich imports: @@ -197,7 +197,7 @@ de: setting_default_privacy: Beitragssichtbarkeit setting_default_sensitive: Eigene Medien immer mit einer Inhaltswarnung (NSFW) versehen setting_delete_modal: Bestätigungsdialog anzeigen, bevor ein Beitrag gelöscht wird - setting_disable_swiping: Deaktiviere Wischgesten + setting_disable_swiping: Wischgesten deaktivieren setting_display_media: Medien-Anzeige setting_display_media_default: Standard setting_display_media_hide_all: Alle Medien verstecken @@ -211,7 +211,7 @@ de: setting_theme: Design setting_trends: Heutige Trends anzeigen setting_unfollow_modal: Bestätigungsdialog anzeigen, bevor jemandem entfolgt wird - setting_use_blurhash: Farbverlauf für versteckte Medien anzeigen + setting_use_blurhash: Farbverlauf für verborgene Medien anzeigen setting_use_pending_items: Langsamer Modus severity: Schweregrad sign_in_token_attempt: Sicherheitscode diff --git a/config/locales/simple_form.eo.yml b/config/locales/simple_form.eo.yml index c4e4bc06e..e8577d35b 100644 --- a/config/locales/simple_form.eo.yml +++ b/config/locales/simple_form.eo.yml @@ -75,7 +75,7 @@ eo: comment: Laŭvola. Memoru, kial vi aldonis ĉi tiun regulon. severities: no_access: Bloki aliron al ĉiuj rimedoj - sign_up_requires_approval: Novaj registriĝoj devigos vian aprobon + sign_up_requires_approval: Novaj registriĝoj bezonos vian aprobon severity: Elektu, kio okazos pri petoj de ĉi tiu IP rule: text: Priskribu regulon aŭ neceson por uzantoj en ĉi tiu servilo. Provu fari ĝin mallonga kaj simpla @@ -182,6 +182,8 @@ eo: actions: hide: Kaŝi komplete warn: Kaŝi malantaŭ averto + form_admin_settings: + registrations_mode: Kiu povas krei konton interactions: must_be_follower: Bloki sciigojn de nesekvantoj must_be_following: Bloki sciigojn de homoj, kiujn vi ne sekvas diff --git a/config/locales/simple_form.no.yml b/config/locales/simple_form.no.yml index c6193c545..b3d9613e7 100644 --- a/config/locales/simple_form.no.yml +++ b/config/locales/simple_form.no.yml @@ -12,10 +12,10 @@ admin_account_action: include_statuses: Brukeren vil se hvilke tuter som forårsaket moderator-handlingen eller -advarselen send_email_notification: Brukeren vil motta en forklaring på hva som har skjedd med deres bruker - text_html: Valgfritt. Du kan bruke tut syntaks. Du kan <a href="%{path}">legge til advarsels-forhåndsinnstillinger</a> for å spare tid + text_html: Valgfritt. Du kan bruke innlegg-syntaks. Du kan <a href="%{path}">legge til advarsels-forhåndsinnstillinger</a> for å spare tid type_html: Velg hva du vil gjøre med <strong>%{acct}</strong> types: - disable: Forhindre brukeren å bruke kontoen sin, men ikke slett eller skjule innholdet deres. + disable: Forhindre brukeren fra å bruke kontoen sin, men ikke slett eller skjul innholdet deres. none: Bruk dette for å sende en advarsel til brukeren uten å utløse noen andre handlinger. sensitive: Tving alle denne brukerens medievedlegg til å bli markert som følsom. silence: Hindre brukeren i å kunne skrive offentlig synlighet, skjule sine innlegg og varsler for personer som ikke kan følge dem. @@ -60,6 +60,7 @@ domain_allow: domain: Dette domenet vil være i stand til å hente data fra denne serveren og dets innkommende data vil bli prosessert og lagret email_domain_block: + domain: Dette kan være domenenavnet som vises i e-postadressen eller MX-oppføringen den bruker. De vil bli sjekket ved oppretting av konto. with_dns_records: Et forsøk på å løse det gitte domenets DNS-poster vil bli gjort, og resultatene vil også bli svartelistet form_challenge: current_password: Du går inn i et sikkert område @@ -104,7 +105,7 @@ disable: Deaktiver pålogging none: Ikke gjør noe sensitive: Sensitiv - silence: Stilne + silence: Begrens suspend: Suspender og ugjenkallelig slett brukerdata warning_preset_id: Bruk en advarsels-forhåndsinnstilling announcement: diff --git a/config/locales/simple_form.pt-BR.yml b/config/locales/simple_form.pt-BR.yml index 16dd4cb43..2d26cf848 100644 --- a/config/locales/simple_form.pt-BR.yml +++ b/config/locales/simple_form.pt-BR.yml @@ -77,6 +77,10 @@ pt-BR: backups_retention_period: Manter os arquivos de usuário gerados pelo número de dias especificados. bootstrap_timeline_accounts: Estas contas serão fixadas no topo das recomendações de novos usuários para seguir. closed_registrations_message: Exibido quando as inscrições estiverem fechadas + content_cache_retention_period: Postagens de outros servidores serão excluídas após o número de dias especificados, quando definido com um valor positivo. Isso pode ser irreversível. + custom_css: Você pode aplicar estilos personalizados na versão da web do Mastodon. + mascot: Substitui a ilustração na interface web avançada. + media_cache_retention_period: Os arquivos de mídia baixados serão excluídos após o número especificado de dias, quando definido para um valor positivo, e baixados novamente na demanda. site_contact_username: Como as pessoas podem chegar até você no Mastodon. site_extended_description: Quaisquer informações adicionais que possam ser úteis para os visitantes e seus usuários. Podem ser estruturadas com formato Markdown. site_title: Como as pessoas podem se referir ao seu servidor além do nome do domínio. diff --git a/config/locales/simple_form.sk.yml b/config/locales/simple_form.sk.yml index 5f0825327..b621ced66 100644 --- a/config/locales/simple_form.sk.yml +++ b/config/locales/simple_form.sk.yml @@ -52,6 +52,9 @@ sk: data: CSV súbor vyexportovaný z iného Mastodon serveru invite_request: text: Toto pomôže s vyhodnocovaním tvojej žiadosti + ip_block: + severities: + sign_up_block: Nové registrácie nebudú možné sessions: otp: 'Napíš sem dvoj-faktorový kód z telefónu, alebo použi jeden z tvojích obnovovacích kódov:' tag: diff --git a/config/locales/simple_form.th.yml b/config/locales/simple_form.th.yml index eb4d2c873..05b35852d 100644 --- a/config/locales/simple_form.th.yml +++ b/config/locales/simple_form.th.yml @@ -33,7 +33,7 @@ th: autofollow: ผู้คนที่ลงทะเบียนผ่านคำเชิญจะติดตามคุณโดยอัตโนมัติ avatar: PNG, GIF หรือ JPG สูงสุด %{size} จะถูกย่อขนาดเป็น %{dimensions}px bot: ส่งสัญญาณให้ผู้อื่นว่าบัญชีทำการกระทำแบบอัตโนมัติเป็นหลักและอาจไม่ได้รับการสังเกตการณ์ - context: บริบทจำนวนหนึ่งหรือมากกว่าที่ตัวกรองควรใช้ + context: หนึ่งหรือหลายบริบทที่ตัวกรองควรนำไปใช้ current_password: เพื่อวัตถุประสงค์ด้านความปลอดภัย โปรดป้อนรหัสผ่านของบัญชีปัจจุบัน current_username: เพื่อยืนยัน โปรดป้อนชื่อผู้ใช้ของบัญชีปัจจุบัน digest: ส่งเฉพาะหลังจากไม่มีการใช้งานเป็นเวลานานและในกรณีที่คุณได้รับข้อความส่วนบุคคลใด ๆ เมื่อคุณไม่อยู่เท่านั้น @@ -74,17 +74,24 @@ th: hide: ซ่อนเนื้อหาที่กรองอยู่อย่างสมบูรณ์ ทำเสมือนว่าไม่มีเนื้อหาอยู่ warn: ซ่อนเนื้อหาที่กรองอยู่หลังคำเตือนที่กล่าวถึงชื่อเรื่องของตัวกรอง form_admin_settings: + backups_retention_period: เก็บการเก็บถาวรผู้ใช้ที่สร้างขึ้นตามจำนวนวันที่ระบุ bootstrap_timeline_accounts: จะปักหมุดบัญชีเหล่านี้ไว้ด้านบนสุดของคำแนะนำการติดตามของผู้ใช้ใหม่ closed_registrations_message: แสดงเมื่อมีการปิดการลงทะเบียน + content_cache_retention_period: จะลบโพสต์จากเซิร์ฟเวอร์อื่น ๆ หลังจากจำนวนวันที่ระบุเมื่อตั้งเป็นค่าบวก นี่อาจย้อนกลับไม่ได้ + custom_css: คุณสามารถนำไปใช้ลักษณะที่กำหนดเองใน Mastodon รุ่นเว็บ mascot: เขียนทับภาพประกอบในส่วนติดต่อเว็บขั้นสูง + media_cache_retention_period: จะลบไฟล์สื่อที่ดาวน์โหลดหลังจากจำนวนวันที่ระบุเมื่อตั้งเป็นค่าบวก และดาวน์โหลดใหม่ตามความต้องการ profile_directory: ไดเรกทอรีโปรไฟล์แสดงรายการผู้ใช้ทั้งหมดที่ได้เลือกรับให้สามารถค้นพบได้ site_contact_email: วิธีที่ผู้คนสามารถเข้าถึงคุณสำหรับการสอบถามด้านกฎหมายหรือการสนับสนุน site_contact_username: วิธีที่ผู้คนสามารถเข้าถึงคุณใน Mastodon + site_extended_description: ข้อมูลเพิ่มเติมใด ๆ ที่อาจเป็นประโยชน์กับผู้เยี่ยมชมและผู้ใช้ของคุณ สามารถจัดโครงสร้างด้วยไวยากรณ์ Markdown + site_short_description: คำอธิบายแบบสั้นเพื่อช่วยระบุเซิร์ฟเวอร์ของคุณโดยเฉพาะ ผู้ดำเนินการเซิร์ฟเวอร์ เซิร์ฟเวอร์สำหรับใคร? site_terms: ใช้นโยบายความเป็นส่วนตัวของคุณเองหรือเว้นว่างไว้เพื่อใช้ค่าเริ่มต้น สามารถจัดโครงสร้างด้วยไวยากรณ์ Markdown site_title: วิธีที่ผู้คนอาจอ้างอิงถึงเซิร์ฟเวอร์ของคุณนอกเหนือจากชื่อโดเมนของเซิร์ฟเวอร์ theme: ชุดรูปแบบที่ผู้เยี่ยมชมที่ออกจากระบบและผู้ใช้ใหม่เห็น thumbnail: แสดงภาพ 2:1 โดยประมาณควบคู่ไปกับข้อมูลเซิร์ฟเวอร์ของคุณ timeline_preview: ผู้เยี่ยมชมที่ออกจากระบบจะสามารถเรียกดูโพสต์สาธารณะล่าสุดที่มีในเซิร์ฟเวอร์ + trendable_by_default: ข้ามการตรวจทานเนื้อหาที่กำลังนิยมด้วยตนเอง ยังคงสามารถเอาแต่ละรายการออกจากแนวโน้มได้หลังเกิดเหตุ trends: แนวโน้มแสดงว่าโพสต์, แฮชแท็ก และเรื่องข่าวใดกำลังได้รับความสนใจในเซิร์ฟเวอร์ของคุณ form_challenge: current_password: คุณกำลังเข้าสู่พื้นที่ปลอดภัย @@ -147,7 +154,7 @@ th: announcement: all_day: เหตุการณ์ตลอดทั้งวัน ends_at: การสิ้นสุดเหตุการณ์ - scheduled_at: จัดกำหนดการเผยแพร่ + scheduled_at: จัดกำหนดการสำหรับการเผยแพร่ starts_at: การเริ่มต้นเหตุการณ์ text: ประกาศ appeal: diff --git a/config/locales/sk.yml b/config/locales/sk.yml index e1b2ae99a..51c447122 100644 --- a/config/locales/sk.yml +++ b/config/locales/sk.yml @@ -5,6 +5,7 @@ sk: contact_missing: Nezadaný contact_unavailable: Neuvedený/á hosted_on: Mastodon hostovaný na %{domain} + title: O accounts: follow: Následuj followers: @@ -534,6 +535,7 @@ sk: didnt_get_confirmation: Neobdržal/a si kroky na potvrdenie? forgot_password: Zabudnuté heslo? invalid_reset_password_token: Token na obnovu hesla vypršal. Prosím vypítaj si nový. + log_in_with: Prihlás sa s login: Prihlás sa logout: Odhlás sa migrate_account: Presúvam sa na iný účet @@ -845,7 +847,6 @@ sk: activity: Najnovšia aktivita browser: Prehliadač browsers: - blackberry: RIM Blackberry chrome: Google Chrome firefox: Mozilla Firefox generic: Neznámy prehliadač @@ -859,7 +860,6 @@ sk: explanation: Tieto sú prehliadače ktoré sú teraz prihlásené na tvoj Mastodon účet. ip: IP adresa platforms: - chrome_os: Google ChromeOS ios: Apple iOS linux: GNU/Linux mac: MacOSX diff --git a/config/locales/sl.yml b/config/locales/sl.yml index 4b196cbf0..7967723ae 100644 --- a/config/locales/sl.yml +++ b/config/locales/sl.yml @@ -634,7 +634,7 @@ sl: two: "%{count} uporabnika" categories: administration: Upravljanje - devops: Razvojniki + devops: DevOps invites: Povabila moderation: Moderiranje special: Posebno @@ -687,7 +687,7 @@ sl: view_audit_log_description: Omogoča, da uporabnik vidi zgodovino skrbniških opravil na strežniku view_dashboard: Pokaži nadzorno ploščo view_dashboard_description: Omogoča uporabnikom, da dostopajo do nadzorne plošče in različnih meritev - view_devops: Razvojniki + view_devops: DevOps view_devops_description: Omogoča uporabnikom, da dostopajo do nadzornih plošč Sidekiq in phHero title: Vloge rules: @@ -1449,7 +1449,7 @@ sl: adobe_air: Adobe Air android: Android blackberry: BlackBerry - chrome_os: Chrome OS + chrome_os: ChromeOS firefox_os: Firefox OS ios: iOS linux: Linux diff --git a/config/locales/sq.yml b/config/locales/sq.yml index ceb57ec4f..5dfdf806c 100644 --- a/config/locales/sq.yml +++ b/config/locales/sq.yml @@ -1368,7 +1368,7 @@ sq: browser: Shfletues browsers: alipay: Alipay - blackberry: Blackberry + blackberry: BlackBerry chrome: Chrome edge: Microsoft Edge electron: Electron @@ -1382,7 +1382,7 @@ sq: phantom_js: PhantomJS qq: QQ Browser safari: Safari - uc_browser: UCBrowser + uc_browser: Shfletues UC weibo: Weibo current_session: Sesioni i tanishëm description: "%{browser} në %{platform}" @@ -1391,7 +1391,7 @@ sq: platforms: adobe_air: Adobe Air android: Android - blackberry: Blackberry + blackberry: BlackBerry chrome_os: ChromeOS firefox_os: Firefox OS ios: iOS diff --git a/config/locales/sr-Latn.yml b/config/locales/sr-Latn.yml index 0d4b6581d..cd142af77 100644 --- a/config/locales/sr-Latn.yml +++ b/config/locales/sr-Latn.yml @@ -296,7 +296,6 @@ sr-Latn: activity: Poslednja aktivnost browser: Veb čitač browsers: - blackberry: Blekberi chrome: Hrom generic: Nepoznati veb čitač current_session: Trenutna sesija @@ -305,8 +304,6 @@ sr-Latn: platforms: adobe_air: Adobe Air-a android: Androida - blackberry: Blekberija - chrome_os: Hrom OS-a firefox_os: Fajerfoks OS-a linux: Linuksa mac: Mac-a diff --git a/config/locales/sr.yml b/config/locales/sr.yml index 36bd3ebf4..acb2289e7 100644 --- a/config/locales/sr.yml +++ b/config/locales/sr.yml @@ -445,7 +445,6 @@ sr: browser: Веб читач browsers: alipay: Алипеј - blackberry: Блекберија chrome: Хром edge: Мајкрософт Еџ electron: Електрон @@ -459,7 +458,6 @@ sr: phantom_js: ФантомЏејЕс qq: КјуКју Претраживач safari: Сафари - uc_browser: УЦПретраживач weibo: Веибо current_session: Тренутна сесија description: "%{browser} са %{platform}" @@ -467,8 +465,6 @@ sr: platforms: adobe_air: Адоб Ер-а android: Андроида - blackberry: Блекберија - chrome_os: Хром ОС-а firefox_os: Фајерфокс ОС-а ios: иОС-а linux: Линукса diff --git a/config/locales/sv.yml b/config/locales/sv.yml index cf311b3cb..bd3c1693a 100644 --- a/config/locales/sv.yml +++ b/config/locales/sv.yml @@ -608,7 +608,7 @@ sv: other: "%{count} användare" categories: administration: Administration - devops: Devops + devops: DevOps invites: Inbjudningar moderation: Moderering special: Särskild @@ -659,7 +659,7 @@ sv: view_audit_log_description: Tillåter användare att se historiken över administrativa åtgärder på servern view_dashboard: Visa instrumentpanel view_dashboard_description: Ger användare tillgång till instrumentpanelen och olika mätvärden - view_devops: Devops + view_devops: DevOps view_devops_description: Ger användare tillgång till instrumentpanelerna Sidekiq och pgHero title: Roller rules: @@ -1373,7 +1373,7 @@ sv: browser: Webbläsare browsers: alipay: Alipay - blackberry: Blackberry + blackberry: BlackBerry chrome: Chrome edge: Microsoft Edge electron: Electron @@ -1387,7 +1387,7 @@ sv: phantom_js: PhantomJS qq: QQ browser safari: Safari - uc_browser: UCBrowser + uc_browser: UC Browser weibo: Weibo current_session: Nuvarande session description: "%{browser} på %{platform}" @@ -1396,8 +1396,8 @@ sv: platforms: adobe_air: Adobe Air android: Android - blackberry: Blackberry - chrome_os: Chrome OS + blackberry: BlackBerry + chrome_os: ChromeOS firefox_os: Firefox OS ios: iOS linux: Linux diff --git a/config/locales/th.yml b/config/locales/th.yml index 8f5fa3ccd..9a4c665ec 100644 --- a/config/locales/th.yml +++ b/config/locales/th.yml @@ -11,7 +11,7 @@ th: followers: other: ผู้ติดตาม following: กำลังติดตาม - instance_actor_flash: บัญชีนี้เป็นตัวดำเนินการเสมือนที่ใช้เพื่อเป็นตัวแทนของเซิร์ฟเวอร์เองและไม่ใช่ผู้ใช้รายบุคคลใด ๆ บัญชีใช้สำหรับวัตถุประสงค์ในการติดต่อกับภายนอกและไม่ควรได้รับการระงับ + instance_actor_flash: บัญชีนี้เป็นตัวดำเนินการเสมือนที่ใช้เพื่อเป็นตัวแทนของเซิร์ฟเวอร์เองและไม่ใช่ผู้ใช้รายบุคคลใด ๆ มีการใช้บัญชีสำหรับวัตถุประสงค์ในการติดต่อกับภายนอกและไม่ควรได้รับการระงับ last_active: ใช้งานล่าสุด link_verified_on: ตรวจสอบความเป็นเจ้าของของลิงก์นี้เมื่อ %{date} nothing_here: ไม่มีสิ่งใดที่นี่! @@ -296,8 +296,8 @@ th: title: ประกาศใหม่ publish: เผยแพร่ published_msg: เผยแพร่ประกาศสำเร็จ! - scheduled_for: จัดกำหนดไว้สำหรับ %{time} - scheduled_msg: จัดกำหนดการเผยแพร่ประกาศแล้ว! + scheduled_for: จัดกำหนดการไว้สำหรับ %{time} + scheduled_msg: จัดกำหนดการสำหรับการเผยแพร่ประกาศแล้ว! title: ประกาศ unpublish: เลิกเผยแพร่ unpublished_msg: เลิกเผยแพร่ประกาศสำเร็จ! @@ -377,7 +377,7 @@ th: existing_domain_block_html: คุณได้กำหนดขีดจำกัดที่เข้มงวดกว่าใน %{name} ไปแล้ว คุณจำเป็นต้อง <a href="%{unblock_url}">เลิกปิดกั้น</a> ก่อน new: create: สร้างการปิดกั้น - hint: การปิดกั้นโดเมนจะไม่ป้องกันการสร้างรายการบัญชีในฐานข้อมูล แต่จะใช้วิธีการควบคุมที่เฉพาะเจาะจงกับบัญชีเหล่านั้นย้อนหลังและโดยอัตโนมัติ + hint: การปิดกั้นโดเมนจะไม่ป้องกันการสร้างรายการบัญชีในฐานข้อมูล แต่จะนำไปใช้วิธีการควบคุมที่เฉพาะเจาะจงกับบัญชีเหล่านั้นย้อนหลังและโดยอัตโนมัติ severity: desc_html: "<strong>ทำให้เงียบ</strong> จะทำให้โพสต์ของบัญชีไม่ปรากฏแก่ใครก็ตามที่ไม่ได้กำลังติดตามบัญชี <strong>ระงับ</strong> จะเอาเนื้อหา, สื่อ และข้อมูลโปรไฟล์ทั้งหมดของบัญชีออก ใช้ <strong>ไม่มี</strong> หากคุณเพียงแค่ต้องการปฏิเสธไฟล์สื่อ" noop: ไม่มี @@ -590,6 +590,7 @@ th: other: "%{count} ผู้ใช้" categories: administration: การดูแล + devops: DevOps invites: คำเชิญ moderation: การควบคุม special: พิเศษ @@ -637,6 +638,7 @@ th: view_audit_log_description: อนุญาตให้ผู้ใช้ดูประวัติการกระทำการดูแลในเซิร์ฟเวอร์ view_dashboard: ดูแดชบอร์ด view_dashboard_description: อนุญาตให้ผู้ใช้เข้าถึงแดชบอร์ดและเมตริกต่าง ๆ + view_devops: DevOps view_devops_description: อนุญาตให้ผู้ใช้เข้าถึงแดชบอร์ด Sidekiq และ pgHero title: บทบาท rules: @@ -716,6 +718,8 @@ th: appeal_approved: อุทธรณ์แล้ว appeal_pending: รอดำเนินการการอุทธรณ์ system_checks: + database_schema_check: + message_html: มีการโยกย้ายฐานข้อมูลที่รอดำเนินการ โปรดเรียกใช้การโยกย้ายเพื่อให้แน่ใจว่าแอปพลิเคชันทำงานตามที่คาดไว้ elasticsearch_running_check: message_html: ไม่สามารถเชื่อมต่อกับ Elasticsearch โปรดตรวจสอบว่าซอฟต์แวร์กำลังทำงาน หรือปิดใช้งานการค้นหาข้อความแบบเต็ม elasticsearch_version_check: @@ -804,6 +808,8 @@ th: other: "%{count} เหตุการณ์ที่เปิดใช้งาน" events: เหตุการณ์ new: เว็บฮุคใหม่ + rotate_secret: สับเปลี่ยนข้อมูลลับ + secret: ข้อมูลลับการเซ็น status: สถานะ title: เว็บฮุค webhook: เว็บฮุค @@ -914,7 +920,7 @@ th: account_status: สถานะบัญชี confirming: กำลังรอการยืนยันอีเมลให้เสร็จสมบูรณ์ functional: บัญชีของคุณทำงานได้อย่างเต็มที่ - pending: ใบสมัครของคุณกำลังรอดำเนินการตรวจทานโดยพนักงานของเรา นี่อาจใช้เวลาสักครู่ คุณจะได้รับอีเมลหากใบสมัครของคุณได้รับการอนุมัติ + pending: ใบสมัครของคุณกำลังรอดำเนินการตรวจทานโดยพนักงานของเรา นี่อาจใช้เวลาสักครู่ คุณจะได้รับอีเมลหากมีการอนุมัติใบสมัครของคุณ redirecting_to: บัญชีของคุณไม่ได้ใช้งานเนื่องจากบัญชีกำลังเปลี่ยนเส้นทางไปยัง %{acct} ในปัจจุบัน view_strikes: ดูการดำเนินการที่ผ่านมากับบัญชีของคุณ too_fast: ส่งแบบฟอร์มเร็วเกินไป ลองอีกครั้ง @@ -982,7 +988,7 @@ th: appeal_approved: อุทธรณ์การดำเนินการนี้สำเร็จและไม่มีผลบังคับอีกต่อไป appeal_rejected: ปฏิเสธการอุทธรณ์แล้ว appeal_submitted_at: ส่งการอุทธรณ์แล้ว - appealed_msg: ส่งการอุทธรณ์ของคุณแล้ว หากการอุทธรณ์ได้รับการอนุมัติ คุณจะได้รับการแจ้งเตือน + appealed_msg: ส่งการอุทธรณ์ของคุณแล้ว หากมีการอนุมัติการอุทธรณ์ คุณจะได้รับการแจ้งเตือน appeals: submit: ส่งการอุทธรณ์ approve_appeal: อนุมัติการอุทธรณ์ @@ -1042,6 +1048,8 @@ th: storage: ที่เก็บข้อมูลสื่อ featured_tags: add_new: เพิ่มใหม่ + errors: + limit: คุณได้แนะนำแฮชแท็กถึงจำนวนสูงสุดไปแล้ว filters: contexts: account: โปรไฟล์ @@ -1054,6 +1062,7 @@ th: keywords: คำสำคัญ title: แก้ไขตัวกรอง errors: + deprecated_api_multiple_keywords: ไม่สามารถเปลี่ยนพารามิเตอร์เหล่านี้จากแอปพลิเคชันนี้เนื่องจากพารามิเตอร์นำไปใช้กับคำสำคัญของตัวกรองมากกว่าหนึ่ง ใช้แอปพลิเคชันที่ใหม่กว่าหรือส่วนติดต่อเว็บ invalid_context: ไม่มีหรือบริบทที่ให้มาไม่ถูกต้อง index: contexts: กรองใน %{contexts} @@ -1074,6 +1083,7 @@ th: batch: remove: เอาออกจากตัวกรอง index: + hint: ตัวกรองนี้นำไปใช้เพื่อเลือกแต่ละโพสต์โดยไม่คำนึงถึงเกณฑ์อื่น ๆ คุณสามารถเพิ่มโพสต์เพิ่มเติมไปยังตัวกรองนี้ได้จากส่วนติดต่อเว็บ title: โพสต์ที่กรองอยู่ footer: trending_now: กำลังนิยม @@ -1239,6 +1249,7 @@ th: trillion: ล้านล้าน otp_authentication: code_hint: ป้อนรหัสที่สร้างโดยแอปตัวรับรองความถูกต้องของคุณเพื่อยืนยัน + description_html: หากคุณเปิดใช้งาน <strong>การรับรองความถูกต้องด้วยสองปัจจัย</strong> โดยใช้แอปตัวรับรองความถูกต้อง การเข้าสู่ระบบจะต้องการให้คุณอยู่ในความครอบครองโทรศัพท์ของคุณ ซึ่งจะสร้างโทเคนสำหรับให้คุณป้อน enable: เปิดใช้งาน instructions_html: "<strong>สแกนรหัส QR นี้ลงใน Google Authenticator หรือแอป TOTP ที่คล้ายกันในโทรศัพท์ของคุณ</strong> จากนี้ไป แอปนั้นจะสร้างโทเคนที่คุณจะต้องป้อนเมื่อเข้าสู่ระบบ" manual_instructions: 'หากคุณไม่สามารถสแกนรหัส QR และจำเป็นต้องป้อนรหัสด้วยตนเอง นี่คือรหัสลับแบบข้อความธรรมดา:' @@ -1298,12 +1309,15 @@ th: account: โพสต์สาธารณะจาก @%{acct} tag: 'โพสต์สาธารณะที่ได้รับการแท็ก #%{hashtag}' scheduled_statuses: - too_soon: วันที่ตามกำหนดการต้องอยู่ในอนาคต + over_daily_limit: คุณมีโพสต์ที่จัดกำหนดการไว้เกินขีดจำกัดที่ %{limit} สำหรับวันนี้ + over_total_limit: คุณมีโพสต์ที่จัดกำหนดการไว้เกินขีดจำกัดที่ %{limit} + too_soon: วันที่จัดกำหนดการต้องอยู่ในอนาคต sessions: activity: กิจกรรมล่าสุด browser: เบราว์เซอร์ browsers: alipay: Alipay + blackberry: BlackBerry chrome: Chrome edge: Microsoft Edge electron: Electron @@ -1317,6 +1331,7 @@ th: phantom_js: PhantomJS qq: เบราว์เซอร์ QQ safari: Safari + uc_browser: เบราว์เซอร์ UC weibo: Weibo current_session: เซสชันปัจจุบัน description: "%{browser} ใน %{platform}" @@ -1325,11 +1340,12 @@ th: platforms: adobe_air: Adobe Air android: Android - chrome_os: Chrome OS + blackberry: BlackBerry + chrome_os: ChromeOS firefox_os: Firefox OS ios: iOS linux: Linux - mac: Mac + mac: macOS other: แพลตฟอร์มที่ไม่รู้จัก windows: Windows windows_mobile: Windows Mobile @@ -1379,8 +1395,10 @@ th: errors: in_reply_not_found: ดูเหมือนว่าจะไม่มีโพสต์ที่คุณกำลังพยายามตอบกลับอยู่ open_in_web: เปิดในเว็บ + over_character_limit: เกินขีดจำกัดตัวอักษรที่ %{max} pin_errors: direct: ไม่สามารถปักหมุดโพสต์ที่ปรากฏแก่ผู้ใช้ที่กล่าวถึงเท่านั้น + limit: คุณได้ปักหมุดโพสต์ถึงจำนวนสูงสุดไปแล้ว ownership: ไม่สามารถปักหมุดโพสต์ของคนอื่น reblog: ไม่สามารถปักหมุดการดัน poll: diff --git a/config/locales/tr.yml b/config/locales/tr.yml index b041b63f1..cc2193a68 100644 --- a/config/locales/tr.yml +++ b/config/locales/tr.yml @@ -608,7 +608,6 @@ tr: other: "%{count} kullanıcı" categories: administration: Yönetim - devops: Devops invites: Davetler moderation: Denetim special: Özel @@ -659,7 +658,6 @@ tr: view_audit_log_description: Kullanıcıların sunucudaki yönetsel eylemlerin bir tarihçesini görüntülemesine izin verir view_dashboard: Ana Paneli Görüntüleme view_dashboard_description: Kullanıcıların ana panele ve çeşitli ölçütlere erişmesine izin verir - view_devops: Devops view_devops_description: Kullanıcıların Sidekiq ve pgHero panellerine erişmesine izin verir title: Roller rules: @@ -1373,7 +1371,6 @@ tr: browser: Tarayıcı browsers: alipay: Alipay - blackberry: Blackberry chrome: Chrome edge: Microsoft Edge electron: Electron @@ -1387,7 +1384,6 @@ tr: phantom_js: PhantomJS qq: QQ Browser safari: Safari - uc_browser: UC Browser weibo: Weibo current_session: Geçerli oturum description: "%{platform} - %{browser}" @@ -1396,8 +1392,6 @@ tr: platforms: adobe_air: Adobe Air android: Android - blackberry: Blackberry - chrome_os: ChromeOS firefox_os: Firefox OS ios: iOS linux: Linux diff --git a/config/locales/tt.yml b/config/locales/tt.yml index 40a0207e5..b2986602d 100644 --- a/config/locales/tt.yml +++ b/config/locales/tt.yml @@ -189,7 +189,6 @@ tt: browser: Браузер browsers: alipay: Аlipay - blackberry: Blаckberry chrome: Chrоme edge: Microsоft Edge electron: Electrоn @@ -202,15 +201,12 @@ tt: phantom_js: PhаntomJS qq: QQ Brоwser safari: Safаri - uc_browser: UCBrоwser weibo: Weibо description: "%{browser} - %{platform}" ip: ІР platforms: adobe_air: Adobе Air android: Andrоid - blackberry: Blаckberry - chrome_os: ChromеOS firefox_os: Firеfox OS ios: iОS linux: Lіnux diff --git a/config/locales/uk.yml b/config/locales/uk.yml index df73233df..94ac3f2b8 100644 --- a/config/locales/uk.yml +++ b/config/locales/uk.yml @@ -634,7 +634,6 @@ uk: other: "%{count} користувача" categories: administration: Адміністрування - devops: DevOps invites: Запрошення moderation: Модерація special: Спеціальні @@ -687,7 +686,6 @@ uk: view_audit_log_description: Дозволяє користувачам бачити історію адміністративних дій на сервері view_dashboard: Переглядати панель керування view_dashboard_description: Дозволяє користувачам доступ до панелі керування та різних метрик - view_devops: DevOps view_devops_description: Дозволяє користувачам доступ до Sidekiq і панелі pgHero title: Ролі rules: @@ -1425,7 +1423,6 @@ uk: browser: Браузер browsers: alipay: Alipay - blackberry: Blackberry chrome: Хром edge: Microsoft Edge electron: Electron @@ -1439,7 +1436,6 @@ uk: phantom_js: PhantomJS qq: QQ Browser safari: Сафарі - uc_browser: UCBrowser weibo: Weibo current_session: Активна сесія description: "%{browser} на %{platform}" @@ -1448,8 +1444,6 @@ uk: platforms: adobe_air: Adobe Air android: Android - blackberry: Blackberry - chrome_os: ChromeOS firefox_os: Firefox OS ios: iOS linux: Linux diff --git a/config/locales/vi.yml b/config/locales/vi.yml index f1b84de86..b3e37438f 100644 --- a/config/locales/vi.yml +++ b/config/locales/vi.yml @@ -595,7 +595,6 @@ vi: other: "%{count} người" categories: administration: Quản trị viên - devops: Nhà phát triển invites: Lời mời moderation: Kiểm duyệt special: Đặc biệt @@ -645,7 +644,6 @@ vi: view_audit_log_description: Cho phép xem lịch sử của các hành động quản trị trên máy chủ view_dashboard: Xem quản trị view_dashboard_description: Cho phép truy cập trang tổng quan và các chỉ số khác - view_devops: Nhà phát triển view_devops_description: Cho phép truy cập trang tổng quan Sidekiq và pgHero title: Danh sách vai trò rules: @@ -1347,7 +1345,6 @@ vi: browser: Trình duyệt browsers: alipay: Alipay - blackberry: Blackberry chrome: Chrome edge: Edge electron: Electron @@ -1361,7 +1358,6 @@ vi: phantom_js: PhantomJS qq: QQ safari: Safari - uc_browser: UC weibo: Weibo current_session: Phiên hiện tại description: "%{browser} trên %{platform}" @@ -1370,8 +1366,6 @@ vi: platforms: adobe_air: Adobe Air android: Android - blackberry: Blackberry - chrome_os: Chrome OS firefox_os: Hệ điều hành Firefox ios: iOS linux: Linux diff --git a/config/locales/zh-CN.yml b/config/locales/zh-CN.yml index a6c75ea71..4da6b6999 100644 --- a/config/locales/zh-CN.yml +++ b/config/locales/zh-CN.yml @@ -1007,7 +1007,7 @@ zh-CN: appeal: 申诉 appeal_approved: 此次处罚已申诉成功并不再生效 appeal_rejected: 此次申诉已被驳回 - appeal_submitted_at: 申诉已提交 + appeal_submitted_at: 已提出申诉 appealed_msg: 你的申诉已经提交。如果申诉通过,你将收到通知。 appeals: submit: 提交申诉 @@ -1361,7 +1361,7 @@ zh-CN: phantom_js: PhantomJS qq: QQ浏览器 safari: Safari - uc_browser: UC浏览器 + uc_browser: UC 浏览器 weibo: 新浪微博 current_session: 当前会话 description: "%{platform} 上的 %{browser}" @@ -1371,7 +1371,7 @@ zh-CN: adobe_air: Adobe Air android: Android blackberry: 黑莓 - chrome_os: Chrome OS + chrome_os: ChromeOS firefox_os: Firefox OS ios: iOS linux: Linux diff --git a/config/locales/zh-HK.yml b/config/locales/zh-HK.yml index acc6de3ad..92489882d 100644 --- a/config/locales/zh-HK.yml +++ b/config/locales/zh-HK.yml @@ -893,7 +893,6 @@ zh-HK: browser: 瀏覽器 browsers: alipay: 支付寶 - blackberry: 黑莓機 chrome: Chrome 瀏覽器 edge: Microsoft Edge 瀏覽器 electron: Electron 瀏覽器 @@ -907,7 +906,6 @@ zh-HK: phantom_js: PhantomJS 瀏覽器 qq: QQ瀏覽器 safari: Safari 瀏覽器 - uc_browser: UC瀏覽器 weibo: 新浪微博 current_session: 目前的作業階段 description: "%{platform} 上的 %{browser}" @@ -916,8 +914,6 @@ zh-HK: platforms: adobe_air: Adobe Air android: Android - blackberry: Blackberry - chrome_os: ChromeOS firefox_os: Firefox OS ios: iOS linux: Linux diff --git a/config/locales/zh-TW.yml b/config/locales/zh-TW.yml index 5953c2275..c9596c040 100644 --- a/config/locales/zh-TW.yml +++ b/config/locales/zh-TW.yml @@ -597,7 +597,7 @@ zh-TW: other: "%{count} 個使用者" categories: administration: 管理員 - devops: Devops + devops: DevOps invites: 邀請 moderation: 站務 special: 特殊 @@ -647,7 +647,7 @@ zh-TW: view_audit_log_description: 允許使用者檢視伺服器上的管理動作歷史 view_dashboard: 檢視儀表板 view_dashboard_description: 允許使用者存取儀表板與各種指標 - view_devops: Devops + view_devops: DevOps view_devops_description: 允許使用者存取 Sidekiq 與 pgHero 儀表板 title: 角色 rules: @@ -1349,7 +1349,6 @@ zh-TW: browser: 瀏覽器 browsers: alipay: 支付寶 - blackberry: 黑莓機 chrome: Chrome 瀏覽器 edge: Microsoft Edge 瀏覽器 electron: Electron 瀏覽器 @@ -1372,8 +1371,7 @@ zh-TW: platforms: adobe_air: Adobe Air android: Android - blackberry: 黑莓機 (Blackberry) - chrome_os: Chrome OS + chrome_os: ChromeOS firefox_os: Firefox OS ios: iOS linux: Linux diff --git a/config/routes.rb b/config/routes.rb index e1068bb58..8639f0ef5 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -74,7 +74,7 @@ Rails.application.routes.draw do end end - devise_for :users, path: 'auth', controllers: { + devise_for :users, path: 'auth', format: false, controllers: { omniauth_callbacks: 'auth/omniauth_callbacks', sessions: 'auth/sessions', registrations: 'auth/registrations', @@ -219,7 +219,7 @@ Rails.application.routes.draw do resource :relationships, only: [:show, :update] resource :statuses_cleanup, controller: :statuses_cleanup, only: [:show, :update] - get '/media_proxy/:id/(*any)', to: 'media_proxy#show', as: :media_proxy + get '/media_proxy/:id/(*any)', to: 'media_proxy#show', as: :media_proxy, format: false resource :authorize_interaction, only: [:show, :create] resource :share, only: [:show, :create] @@ -426,7 +426,7 @@ Rails.application.routes.draw do get '/admin', to: redirect('/admin/dashboard', status: 302) - namespace :api do + namespace :api, format: false do # OEmbed get '/oembed', to: 'oembed#show', as: :oembed @@ -516,18 +516,10 @@ Rails.application.routes.draw do resources :bookmarks, only: [:index] resources :reports, only: [:create] resources :trends, only: [:index], controller: 'trends/tags' - resources :filters, only: [:index, :create, :show, :update, :destroy] do - resources :keywords, only: [:index, :create], controller: 'filters/keywords' - resources :statuses, only: [:index, :create], controller: 'filters/statuses' - end + resources :filters, only: [:index, :create, :show, :update, :destroy] resources :endorsements, only: [:index] resources :markers, only: [:index, :create] - namespace :filters do - resources :keywords, only: [:show, :update, :destroy] - resources :statuses, only: [:show, :destroy] - end - namespace :apps do get :verify_credentials, to: 'credentials#show' end @@ -685,8 +677,16 @@ Rails.application.routes.draw do resources :media, only: [:create] resources :suggestions, only: [:index] - resources :filters, only: [:index, :create, :show, :update, :destroy] resource :instance, only: [:show] + resources :filters, only: [:index, :create, :show, :update, :destroy] do + resources :keywords, only: [:index, :create], controller: 'filters/keywords' + resources :statuses, only: [:index, :create], controller: 'filters/statuses' + end + + namespace :filters do + resources :keywords, only: [:show, :update, :destroy] + resources :statuses, only: [:show, :destroy] + end namespace :admin do resources :accounts, only: [:index] diff --git a/lib/exceptions.rb b/lib/exceptions.rb index 3c5ba226b..d3b92f4a0 100644 --- a/lib/exceptions.rb +++ b/lib/exceptions.rb @@ -11,6 +11,7 @@ module Mastodon class RaceConditionError < Error; end class RateLimitExceededError < Error; end class SyntaxError < Error; end + class InvalidParameterError < Error; end class UnexpectedResponseError < Error attr_reader :response diff --git a/lib/mastodon/maintenance_cli.rb b/lib/mastodon/maintenance_cli.rb index 6e5242bff..85937da81 100644 --- a/lib/mastodon/maintenance_cli.rb +++ b/lib/mastodon/maintenance_cli.rb @@ -14,7 +14,7 @@ module Mastodon end MIN_SUPPORTED_VERSION = 2019_10_01_213028 # rubocop:disable Style/NumericLiterals - MAX_SUPPORTED_VERSION = 2022_03_16_233212 # rubocop:disable Style/NumericLiterals + MAX_SUPPORTED_VERSION = 2022_11_04_133904 # rubocop:disable Style/NumericLiterals # Stubs to enjoy ActiveRecord queries while not depending on a particular # version of the code/database @@ -45,6 +45,7 @@ module Mastodon class FollowRecommendationSuppression < ApplicationRecord; end class CanonicalEmailBlock < ApplicationRecord; end class Appeal < ApplicationRecord; end + class Webhook < ApplicationRecord; end class PreviewCard < ApplicationRecord self.inheritance_column = false @@ -182,6 +183,7 @@ module Mastodon deduplicate_accounts! deduplicate_tags! deduplicate_webauthn_credentials! + deduplicate_webhooks! Scenic.database.refresh_materialized_view('instances', concurrently: true, cascade: false) if ActiveRecord::Migrator.current_version >= 2020_12_06_004238 Rails.cache.clear @@ -497,6 +499,7 @@ module Mastodon def deduplicate_tags! remove_index_if_exists!(:tags, 'index_tags_on_name_lower') + remove_index_if_exists!(:tags, 'index_tags_on_name_lower_btree') @prompt.say 'Deduplicating tags…' ActiveRecord::Base.connection.select_all("SELECT string_agg(id::text, ',') AS ids FROM tags GROUP BY lower((name)::text) HAVING count(*) > 1").each do |row| @@ -509,11 +512,10 @@ module Mastodon end @prompt.say 'Restoring tags indexes…' - ActiveRecord::Base.connection.add_index :tags, 'lower((name)::text)', name: 'index_tags_on_name_lower', unique: true - - if ActiveRecord::Base.connection.indexes(:tags).any? { |i| i.name == 'index_tags_on_name_lower_btree' } - @prompt.say 'Reindexing textual indexes on tags…' - ActiveRecord::Base.connection.execute('REINDEX INDEX index_tags_on_name_lower_btree;') + if ActiveRecord::Migrator.current_version < 20210421121431 + ActiveRecord::Base.connection.add_index :tags, 'lower((name)::text)', name: 'index_tags_on_name_lower', unique: true + else + ActiveRecord::Base.connection.execute 'CREATE UNIQUE INDEX CONCURRENTLY index_tags_on_name_lower_btree ON tags (lower(name) text_pattern_ops)' end end @@ -531,6 +533,20 @@ module Mastodon ActiveRecord::Base.connection.add_index :webauthn_credentials, ['external_id'], name: 'index_webauthn_credentials_on_external_id', unique: true end + def deduplicate_webhooks! + return unless ActiveRecord::Base.connection.table_exists?(:webhooks) + + remove_index_if_exists!(:webhooks, 'index_webhooks_on_url') + + @prompt.say 'Deduplicating webhooks…' + ActiveRecord::Base.connection.select_all("SELECT string_agg(id::text, ',') AS ids FROM webhooks GROUP BY url HAVING count(*) > 1").each do |row| + Webhooks.where(id: row['ids'].split(',')).sort_by(&:id).reverse.drop(1).each(&:destroy) + end + + @prompt.say 'Restoring webhooks indexes…' + ActiveRecord::Base.connection.add_index :webhooks, ['url'], name: 'index_webhooks_on_url', unique: true + end + def deduplicate_local_accounts!(accounts) accounts = accounts.sort_by(&:id).reverse diff --git a/lib/mastodon/version.rb b/lib/mastodon/version.rb index 7596a9663..f37553709 100644 --- a/lib/mastodon/version.rb +++ b/lib/mastodon/version.rb @@ -13,11 +13,11 @@ module Mastodon end def patch - 0 + 1 end def flags - 'rc3' + '' end def suffix diff --git a/lib/tasks/mastodon.rake b/lib/tasks/mastodon.rake index 3ec685c74..c1e5bd2b4 100644 --- a/lib/tasks/mastodon.rake +++ b/lib/tasks/mastodon.rake @@ -142,7 +142,40 @@ namespace :mastodon do prompt.say "\n" if prompt.yes?('Do you want to store uploaded files on the cloud?', default: false) - case prompt.select('Provider', ['Amazon S3', 'Wasabi', 'Minio', 'Google Cloud Storage']) + case prompt.select('Provider', ['DigitalOcean Spaces', 'Amazon S3', 'Wasabi', 'Minio', 'Google Cloud Storage']) + when 'DigitalOcean Spaces' + env['S3_ENABLED'] = 'true' + env['S3_PROTOCOL'] = 'https' + + env['S3_BUCKET'] = prompt.ask('Space name:') do |q| + q.required true + q.default "files.#{env['LOCAL_DOMAIN']}" + q.modify :strip + end + + env['S3_REGION'] = prompt.ask('Space region:') do |q| + q.required true + q.default 'nyc3' + q.modify :strip + end + + env['S3_HOSTNAME'] = prompt.ask('Space endpoint:') do |q| + q.required true + q.default 'nyc3.digitaloceanspaces.com' + q.modify :strip + end + + env['S3_ENDPOINT'] = "https://#{env['S3_HOSTNAME']}" + + env['AWS_ACCESS_KEY_ID'] = prompt.ask('Space access key:') do |q| + q.required true + q.modify :strip + end + + env['AWS_SECRET_ACCESS_KEY'] = prompt.ask('Space secret key:') do |q| + q.required true + q.modify :strip + end when 'Amazon S3' env['S3_ENABLED'] = 'true' env['S3_PROTOCOL'] = 'https' diff --git a/spec/config/initializers/rack_attack_spec.rb b/spec/config/initializers/rack_attack_spec.rb new file mode 100644 index 000000000..581021cb9 --- /dev/null +++ b/spec/config/initializers/rack_attack_spec.rb @@ -0,0 +1,82 @@ +require 'rails_helper' + +describe Rack::Attack do + include Rack::Test::Methods + + def app + Rails.application + end + + shared_examples 'throttled endpoint' do + context 'when the number of requests is lower than the limit' do + it 'does not change the request status' do + limit.times do + request.call + expect(last_response.status).to_not eq(429) + end + end + end + + context 'when the number of requests is higher than the limit' do + it 'returns http too many requests' do + (limit * 2).times do |i| + request.call + expect(last_response.status).to eq(429) if i > limit + end + end + end + end + + let(:remote_ip) { '1.2.3.5' } + + describe 'throttle excessive sign-up requests by IP address' do + context 'through the website' do + let(:limit) { 25 } + let(:request) { ->() { post path, {}, 'REMOTE_ADDR' => remote_ip } } + + context 'for exact path' do + let(:path) { '/auth' } + it_behaves_like 'throttled endpoint' + end + + context 'for path with format' do + let(:path) { '/auth.html' } + it_behaves_like 'throttled endpoint' + end + end + + context 'through the API' do + let(:limit) { 5 } + let(:request) { ->() { post path, {}, 'REMOTE_ADDR' => remote_ip } } + + context 'for exact path' do + let(:path) { '/api/v1/accounts' } + it_behaves_like 'throttled endpoint' + end + + context 'for path with format' do + let(:path) { '/api/v1/accounts.json' } + + it 'returns http not found' do + request.call + expect(last_response.status).to eq(404) + end + end + end + end + + describe 'throttle excessive sign-in requests by IP address' do + let(:limit) { 25 } + let(:request) { ->() { post path, {}, 'REMOTE_ADDR' => remote_ip } } + + context 'for exact path' do + let(:path) { '/auth/sign_in' } + it_behaves_like 'throttled endpoint' + end + + context 'for path with format' do + let(:path) { '/auth/sign_in.html' } + it_behaves_like 'throttled endpoint' + end + end +end diff --git a/spec/controllers/api/v1/admin/domain_allows_controller_spec.rb b/spec/controllers/api/v1/admin/domain_allows_controller_spec.rb index 26a391a60..8100363f6 100644 --- a/spec/controllers/api/v1/admin/domain_allows_controller_spec.rb +++ b/spec/controllers/api/v1/admin/domain_allows_controller_spec.rb @@ -94,25 +94,37 @@ RSpec.describe Api::V1::Admin::DomainAllowsController, type: :controller do describe 'POST #create' do let!(:domain_allow) { Fabricate(:domain_allow, domain: 'example.com') } - before do - post :create, params: { domain: 'foo.bar.com' } - end - - it_behaves_like 'forbidden for wrong scope', 'write:statuses' - it_behaves_like 'forbidden for wrong role', '' - it_behaves_like 'forbidden for wrong role', 'Moderator' - - it 'returns http success' do - expect(response).to have_http_status(200) + context do + before do + post :create, params: { domain: 'foo.bar.com' } + end + + it_behaves_like 'forbidden for wrong scope', 'write:statuses' + it_behaves_like 'forbidden for wrong role', '' + it_behaves_like 'forbidden for wrong role', 'Moderator' + + it 'returns http success' do + expect(response).to have_http_status(200) + end + + it 'returns expected domain name' do + json = body_as_json + expect(json[:domain]).to eq 'foo.bar.com' + end + + it 'creates a domain block' do + expect(DomainAllow.find_by(domain: 'foo.bar.com')).to_not be_nil + end end - it 'returns expected domain name' do - json = body_as_json - expect(json[:domain]).to eq 'foo.bar.com' - end + context 'with invalid domain name' do + before do + post :create, params: { domain: 'foo bar' } + end - it 'creates a domain block' do - expect(DomainAllow.find_by(domain: 'foo.bar.com')).to_not be_nil + it 'returns http unprocessable entity' do + expect(response).to have_http_status(422) + end end end end diff --git a/spec/controllers/api/v1/filters/keywords_controller_spec.rb b/spec/controllers/api/v2/filters/keywords_controller_spec.rb index aecb4e41c..1201a4ca2 100644 --- a/spec/controllers/api/v1/filters/keywords_controller_spec.rb +++ b/spec/controllers/api/v2/filters/keywords_controller_spec.rb @@ -1,6 +1,6 @@ require 'rails_helper' -RSpec.describe Api::V1::Filters::KeywordsController, type: :controller do +RSpec.describe Api::V2::Filters::KeywordsController, type: :controller do render_views let(:user) { Fabricate(:user) } diff --git a/spec/controllers/api/v1/filters/statuses_controller_spec.rb b/spec/controllers/api/v2/filters/statuses_controller_spec.rb index 3b2399dd8..9740c1eb3 100644 --- a/spec/controllers/api/v1/filters/statuses_controller_spec.rb +++ b/spec/controllers/api/v2/filters/statuses_controller_spec.rb @@ -1,6 +1,6 @@ require 'rails_helper' -RSpec.describe Api::V1::Filters::StatusesController, type: :controller do +RSpec.describe Api::V2::Filters::StatusesController, type: :controller do render_views let(:user) { Fabricate(:user) } diff --git a/spec/fixtures/files/utf8-followers.txt b/spec/fixtures/files/utf8-followers.txt new file mode 100644 index 000000000..9d4fe3485 --- /dev/null +++ b/spec/fixtures/files/utf8-followers.txt @@ -0,0 +1 @@ +@nare@թութ.հայ diff --git a/spec/models/account/field_spec.rb b/spec/models/account/field_spec.rb index fcb2a884a..b4beec048 100644 --- a/spec/models/account/field_spec.rb +++ b/spec/models/account/field_spec.rb @@ -89,6 +89,14 @@ RSpec.describe Account::Field, type: :model do expect(subject.verifiable?).to be false end end + + context 'for text which is blank' do + let(:value) { '' } + + it 'returns false' do + expect(subject.verifiable?).to be false + end + end end context 'for remote accounts' do @@ -133,6 +141,14 @@ RSpec.describe Account::Field, type: :model do expect(subject.verifiable?).to be false end end + + context 'for text which is blank' do + let(:value) { '' } + + it 'returns false' do + expect(subject.verifiable?).to be false + end + end end end end diff --git a/spec/models/custom_emoji_filter_spec.rb b/spec/models/custom_emoji_filter_spec.rb index d859f5c5f..2b1b5dc54 100644 --- a/spec/models/custom_emoji_filter_spec.rb +++ b/spec/models/custom_emoji_filter_spec.rb @@ -50,10 +50,10 @@ RSpec.describe CustomEmojiFilter do context 'else' do let(:params) { { else: 'else' } } - it 'raises RuntimeError' do + it 'raises Mastodon::InvalidParameterError' do expect do subject - end.to raise_error(RuntimeError, /Unknown filter: else/) + end.to raise_error(Mastodon::InvalidParameterError, /Unknown filter: else/) end end end diff --git a/spec/services/import_service_spec.rb b/spec/services/import_service_spec.rb index 764225aa7..e2d182920 100644 --- a/spec/services/import_service_spec.rb +++ b/spec/services/import_service_spec.rb @@ -172,6 +172,29 @@ RSpec.describe ImportService, type: :service do end end + # Based on the bug report 20571 where UTF-8 encoded domains were rejecting import of their users + # + # https://github.com/mastodon/mastodon/issues/20571 + context 'utf-8 encoded domains' do + subject { ImportService.new } + + let!(:nare) { Fabricate(:account, username: 'nare', domain: 'թութ.հայ', locked: false, protocol: :activitypub, inbox_url: 'https://թութ.հայ/inbox') } + + # Make sure to not actually go to the remote server + before do + stub_request(:post, "https://թութ.հայ/inbox").to_return(status: 200) + end + + let(:csv) { attachment_fixture('utf8-followers.txt') } + let(:import) { Import.create(account: account, type: 'following', data: csv) } + + it 'follows the listed account' do + expect(account.follow_requests.count).to eq 0 + subject.call(import) + expect(account.follow_requests.count).to eq 1 + end + end + context 'import bookmarks' do subject { ImportService.new } diff --git a/streaming/index.js b/streaming/index.js index ff7d48250..53a790ea0 100644 --- a/streaming/index.js +++ b/streaming/index.js @@ -689,7 +689,7 @@ const startWorker = async (workerId) => { queries.push(client.query('SELECT 1 FROM account_domain_blocks WHERE account_id = $1 AND domain = $2', [req.accountId, accountDomain])); } - if (!unpackedPayload.filter_results && !req.cachedFilters) { + if (!unpackedPayload.filtered && !req.cachedFilters) { queries.push(client.query('SELECT filter.id AS id, filter.phrase AS title, filter.context AS context, filter.expires_at AS expires_at, filter.action AS filter_action, keyword.keyword AS keyword, keyword.whole_word AS whole_word FROM custom_filter_keywords keyword JOIN custom_filters filter ON keyword.custom_filter_id = filter.id WHERE filter.account_id = $1 AND filter.expires_at IS NULL OR filter.expires_at > NOW()', [req.accountId])); } @@ -700,7 +700,7 @@ const startWorker = async (workerId) => { return; } - if (!unpackedPayload.filter_results && !req.cachedFilters) { + if (!unpackedPayload.filtered && !req.cachedFilters) { const filterRows = values[accountDomain ? 2 : 1].rows; req.cachedFilters = filterRows.reduce((cache, row) => { @@ -715,7 +715,7 @@ const startWorker = async (workerId) => { title: row.title, context: row.context, expires_at: row.expires_at, - filter_action: row.filter_action, + filter_action: ['warn', 'hide'][row.filter_action], }, }; } @@ -743,18 +743,18 @@ const startWorker = async (workerId) => { } // Check filters - if (req.cachedFilters && !unpackedPayload.filter_results) { + if (req.cachedFilters && !unpackedPayload.filtered) { const status = unpackedPayload; const searchContent = ([status.spoiler_text || '', status.content].concat((status.poll && status.poll.options) ? status.poll.options.map(option => option.title) : [])).concat(status.media_attachments.map(att => att.description)).join('\n\n').replace(/<br\s*\/?>/g, '\n').replace(/<\/p><p>/g, '\n\n'); const searchIndex = JSDOM.fragment(searchContent).textContent; const now = new Date(); - payload.filter_results = []; + payload.filtered = []; Object.values(req.cachedFilters).forEach((cachedFilter) => { if ((cachedFilter.expires_at === null || cachedFilter.expires_at > now)) { const keyword_matches = searchIndex.match(cachedFilter.regexp); if (keyword_matches) { - payload.filter_results.push({ + payload.filtered.push({ filter: cachedFilter.repr, keyword_matches, }); |