mirror of
https://github.com/glitch-soc/mastodon.git
synced 2024-11-23 08:34:13 -05:00
Merge commit '9cc4040308a758d4b77961f4da79cf63a044fffe' into glitch-soc/merge-upstream
This commit is contained in:
commit
be68f8f4af
@ -1,20 +1,15 @@
|
||||
# For details, see https://github.com/devcontainers/images/tree/main/src/ruby
|
||||
FROM mcr.microsoft.com/devcontainers/ruby:1-3.3-bookworm
|
||||
|
||||
# Install Rails
|
||||
# RUN gem install rails webdrivers
|
||||
# Install node version from .nvmrc
|
||||
WORKDIR /app
|
||||
COPY .nvmrc .
|
||||
RUN /bin/bash --login -i -c "nvm install"
|
||||
|
||||
ARG NODE_VERSION="20"
|
||||
RUN . /usr/local/share/nvm/nvm.sh && nvm install ${NODE_VERSION} 2>&1
|
||||
# Install additional OS packages
|
||||
RUN apt-get update && \
|
||||
export DEBIAN_FRONTEND=noninteractive && \
|
||||
apt-get -y install --no-install-recommends libicu-dev libidn11-dev ffmpeg imagemagick libvips42 libpam-dev
|
||||
|
||||
# [Optional] Uncomment this section to install additional OS packages.
|
||||
RUN apt-get update && export DEBIAN_FRONTEND=noninteractive \
|
||||
&& apt-get -y install --no-install-recommends libicu-dev libidn11-dev ffmpeg imagemagick libvips42 libpam-dev
|
||||
|
||||
# [Optional] Uncomment this line to install additional gems.
|
||||
RUN gem install foreman
|
||||
|
||||
# [Optional] Uncomment this line to install global node packages.
|
||||
RUN . /usr/local/share/nvm/nvm.sh && corepack enable 2>&1
|
||||
|
||||
COPY welcome-message.txt /usr/local/etc/vscode-dev-containers/first-run-notice.txt
|
||||
# Move welcome message to where VS Code expects it
|
||||
COPY .devcontainer/welcome-message.txt /usr/local/etc/vscode-dev-containers/first-run-notice.txt
|
||||
|
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "Mastodon on GitHub Codespaces",
|
||||
"dockerComposeFile": "../docker-compose.yml",
|
||||
"dockerComposeFile": "../compose.yaml",
|
||||
"service": "app",
|
||||
"workspaceFolder": "/workspaces/${localWorkspaceFolderBasename}",
|
||||
|
||||
|
@ -2,8 +2,8 @@ services:
|
||||
app:
|
||||
working_dir: /workspaces/mastodon/
|
||||
build:
|
||||
context: .
|
||||
dockerfile: Dockerfile
|
||||
context: ..
|
||||
dockerfile: .devcontainer/Dockerfile
|
||||
volumes:
|
||||
- ..:/workspaces/mastodon:cached
|
||||
environment:
|
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "Mastodon on local machine",
|
||||
"dockerComposeFile": "docker-compose.yml",
|
||||
"dockerComposeFile": "compose.yaml",
|
||||
"service": "app",
|
||||
"workspaceFolder": "/workspaces/${localWorkspaceFolderBasename}",
|
||||
|
||||
|
4
.github/codecov.yml
vendored
4
.github/codecov.yml
vendored
@ -3,9 +3,9 @@ coverage:
|
||||
status:
|
||||
project:
|
||||
default:
|
||||
# Github status check is not blocking
|
||||
# GitHub status check is not blocking
|
||||
informational: true
|
||||
patch:
|
||||
default:
|
||||
# Github status check is not blocking
|
||||
# GitHub status check is not blocking
|
||||
informational: true
|
||||
|
3
.github/renovate.json5
vendored
3
.github/renovate.json5
vendored
@ -2,6 +2,7 @@
|
||||
$schema: 'https://docs.renovatebot.com/renovate-schema.json',
|
||||
extends: [
|
||||
'config:recommended',
|
||||
'customManagers:dockerfileVersions',
|
||||
':labels(dependencies)',
|
||||
':prConcurrentLimitNone', // Remove limit for open PRs at any time.
|
||||
':prHourlyLimit2', // Rate limit PR creation to a maximum of two per hour.
|
||||
@ -59,7 +60,7 @@
|
||||
dependencyDashboardApproval: true,
|
||||
},
|
||||
{
|
||||
// Update Github Actions and Docker images weekly
|
||||
// Update GitHub Actions and Docker images weekly
|
||||
matchManagers: ['github-actions', 'dockerfile', 'docker-compose'],
|
||||
extends: ['schedule:weekly'],
|
||||
},
|
||||
|
2
.github/workflows/build-container-image.yml
vendored
2
.github/workflows/build-container-image.yml
vendored
@ -68,7 +68,7 @@ jobs:
|
||||
username: ${{ secrets.DOCKERHUB_USERNAME }}
|
||||
password: ${{ secrets.DOCKERHUB_TOKEN }}
|
||||
|
||||
- name: Log in to the Github Container registry
|
||||
- name: Log in to the GitHub Container registry
|
||||
if: contains(inputs.push_to_images, 'ghcr.io')
|
||||
uses: docker/login-action@v3
|
||||
with:
|
||||
|
4
.github/workflows/crowdin-download.yml
vendored
4
.github/workflows/crowdin-download.yml
vendored
@ -59,13 +59,13 @@ jobs:
|
||||
title: 'New Crowdin Translations (automated)'
|
||||
author: 'GitHub Actions <noreply@github.com>'
|
||||
body: |
|
||||
New Crowdin translations, automated with Github Actions
|
||||
New Crowdin translations, automated with GitHub Actions
|
||||
|
||||
See `.github/workflows/crowdin-download.yml`
|
||||
|
||||
This PR will be updated every day with new translations.
|
||||
|
||||
Due to a limitation in Github Actions, checks are not running on this PR without manual action.
|
||||
Due to a limitation in GitHub Actions, checks are not running on this PR without manual action.
|
||||
If you want to run the checks, then close and re-open it.
|
||||
branch: i18n/crowdin/translations
|
||||
base: main
|
||||
|
@ -11,8 +11,10 @@ ARG TARGETPLATFORM=${TARGETPLATFORM}
|
||||
ARG BUILDPLATFORM=${BUILDPLATFORM}
|
||||
|
||||
# Ruby image to use for base image, change with [--build-arg RUBY_VERSION="3.3.x"]
|
||||
# renovate: datasource=docker depName=docker.io/ruby
|
||||
ARG RUBY_VERSION="3.3.2"
|
||||
# # Node version to use in base image, change with [--build-arg NODE_MAJOR_VERSION="20"]
|
||||
# renovate: datasource=node-version depName=node
|
||||
ARG NODE_MAJOR_VERSION="20"
|
||||
# Debian image to use for base image, change with [--build-arg DEBIAN_VERSION="bookworm"]
|
||||
ARG DEBIAN_VERSION="bookworm"
|
||||
|
2
Gemfile
2
Gemfile
@ -57,7 +57,7 @@ gem 'hiredis', '~> 0.6'
|
||||
gem 'htmlentities', '~> 4.3'
|
||||
gem 'http', '~> 5.2.0'
|
||||
gem 'http_accept_language', '~> 2.1'
|
||||
gem 'httplog', '~> 1.6.2'
|
||||
gem 'httplog', '~> 1.7.0'
|
||||
gem 'i18n'
|
||||
gem 'idn-ruby', require: 'idn'
|
||||
gem 'inline_svg'
|
||||
|
12
Gemfile.lock
12
Gemfile.lock
@ -168,7 +168,7 @@ GEM
|
||||
climate_control (1.2.0)
|
||||
cocoon (1.2.15)
|
||||
color_diff (0.1)
|
||||
concurrent-ruby (1.3.1)
|
||||
concurrent-ruby (1.3.3)
|
||||
connection_pool (2.4.1)
|
||||
cose (1.3.0)
|
||||
cbor (~> 0.5.9)
|
||||
@ -321,7 +321,7 @@ GEM
|
||||
http-form_data (2.3.0)
|
||||
http_accept_language (2.1.1)
|
||||
httpclient (2.8.3)
|
||||
httplog (1.6.3)
|
||||
httplog (1.7.0)
|
||||
rack (>= 2.0)
|
||||
rainbow (>= 2.0.0)
|
||||
i18n (1.14.5)
|
||||
@ -453,7 +453,7 @@ GEM
|
||||
concurrent-ruby (~> 1.0, >= 1.0.2)
|
||||
sidekiq (>= 3.5)
|
||||
statsd-ruby (~> 1.4, >= 1.4.0)
|
||||
oj (3.16.3)
|
||||
oj (3.16.4)
|
||||
bigdecimal (>= 3.0)
|
||||
omniauth (2.1.2)
|
||||
hashie (>= 3.4.6)
|
||||
@ -578,7 +578,7 @@ GEM
|
||||
opentelemetry-api (~> 1.0)
|
||||
orm_adapter (0.5.0)
|
||||
ox (2.14.18)
|
||||
parallel (1.24.0)
|
||||
parallel (1.25.1)
|
||||
parser (3.3.2.0)
|
||||
ast (~> 2.4.1)
|
||||
racc
|
||||
@ -739,7 +739,7 @@ GEM
|
||||
unicode-display_width (>= 2.4.0, < 3.0)
|
||||
rubocop-ast (1.31.3)
|
||||
parser (>= 3.3.1.0)
|
||||
rubocop-capybara (2.20.0)
|
||||
rubocop-capybara (2.21.0)
|
||||
rubocop (~> 1.41)
|
||||
rubocop-factory_bot (2.25.1)
|
||||
rubocop (~> 1.41)
|
||||
@ -947,7 +947,7 @@ DEPENDENCIES
|
||||
htmlentities (~> 4.3)
|
||||
http (~> 5.2.0)
|
||||
http_accept_language (~> 2.1)
|
||||
httplog (~> 1.6.2)
|
||||
httplog (~> 1.7.0)
|
||||
i18n
|
||||
i18n-tasks (~> 1.0)
|
||||
idn-ruby
|
||||
|
64
README.md
64
README.md
@ -102,42 +102,51 @@ A **Vagrant** configuration is included for development purposes. To use it, com
|
||||
- Run `vagrant ssh -c "cd /vagrant && bin/dev"`
|
||||
- Open `http://mastodon.local` in your browser
|
||||
|
||||
### MacOS
|
||||
### macOS
|
||||
|
||||
To set up **MacOS** for native development, complete the following steps:
|
||||
To set up **macOS** for native development, complete the following steps:
|
||||
|
||||
- Use a Ruby version manager to install the specified version from `.ruby-version`
|
||||
- Run `bundle` to install required gems
|
||||
- Run `brew install postgresql@14 redis imagemagick libidn` to install required dependencies
|
||||
- Navigate to Mastodon's root directory and run `brew install nvm` then `nvm use` to use the version from `.nvmrc`
|
||||
- Run `yarn` to install required packages
|
||||
- Run `corepack enable && corepack prepare`
|
||||
- Run `RAILS_ENV=development bundle exec rails db:setup`
|
||||
- Finally, run `bin/dev` which will launch the local services via `overmind` (if installed) or `foreman`
|
||||
- Install [Homebrew] and run `brew install postgresql@14 redis imagemagick
|
||||
libidn nvm` to install the required project dependencies
|
||||
- Use a Ruby version manager to activate the ruby in `.ruby-version` and run
|
||||
`nvm use` to activate the node version from `.nvmrc`
|
||||
- Run the `bin/setup` script, which will install the required ruby gems and node
|
||||
packages and prepare the database for local development
|
||||
- Finally, run the `bin/dev` script which will launch services via `overmind`
|
||||
(if installed) or `foreman`
|
||||
|
||||
### Docker
|
||||
|
||||
For production hosting and deployment with **Docker**, use the `Dockerfile` and
|
||||
`docker-compose.yml` in the project root directory. To create a local
|
||||
development environment with **Docker**, complete the following steps:
|
||||
`docker-compose.yml` in the project root directory.
|
||||
|
||||
- Install Docker Desktop
|
||||
- Run `docker compose -f .devcontainer/docker-compose.yml up -d`
|
||||
- Run `docker compose -f .devcontainer/docker-compose.yml exec app bin/setup`
|
||||
- Finally, run `docker compose -f .devcontainer/docker-compose.yml exec app bin/dev`
|
||||
For local development, install and launch [Docker], and run:
|
||||
|
||||
If you are using an IDE with [support for the Development Container specification](https://containers.dev/supporting), it will run the above `docker compose` commands automatically. For **Visual Studio Code** this requires the [Dev Container extension](https://containers.dev/supporting#dev-containers).
|
||||
```shell
|
||||
docker compose -f .devcontainer/compose.yaml up -d
|
||||
docker compose -f .devcontainer/compose.yaml exec app bin/setup
|
||||
docker compose -f .devcontainer/compose.yaml exec app bin/dev
|
||||
```
|
||||
|
||||
### Dev Containers
|
||||
|
||||
Within IDEs that support the [Development Containers] specification, start the
|
||||
"Mastodon on local machine" container from the editor. The necessary `docker
|
||||
compose` commands to build and setup the container should run automatically. For
|
||||
**Visual Studio Code** this requires installing the [Dev Container extension].
|
||||
|
||||
### GitHub Codespaces
|
||||
|
||||
To get you coding in just a few minutes, GitHub Codespaces provides a web-based version of Visual Studio Code and a cloud-hosted development environment fully configured with the software needed for this project..
|
||||
[GitHub Codespaces] provides a web-based version of VS Code and a cloud hosted
|
||||
development environment configured with the software needed for this project.
|
||||
|
||||
- Click this button to create a new codespace:<br>
|
||||
[![Open in GitHub Codespaces](https://github.com/codespaces/badge.svg)](https://github.com/codespaces/new?hide_repo_select=true&ref=main&repo=52281283&devcontainer_path=.devcontainer%2Fcodespaces%2Fdevcontainer.json)
|
||||
- Wait for the environment to build. This will take a few minutes.
|
||||
- When the editor is ready, run `bin/dev` in the terminal.
|
||||
- After a few seconds, a popup will appear with a button labeled _Open in Browser_. This will open Mastodon.
|
||||
- On the _Ports_ tab, right click on the “stream” row and select _Port visibility_ → _Public_.
|
||||
[![Open in GitHub Codespaces](https://github.com/codespaces/badge.svg)][codespace]
|
||||
|
||||
- Click the button to create a new codespace, and confirm the options
|
||||
- Wait for the environment to build (takes a few minutes)
|
||||
- When the editor is ready, run `bin/dev` in the terminal
|
||||
- Wait for an _Open in Browser_ prompt. This will open Mastodon
|
||||
- On the _Ports_ tab "stream" setting change _Port visibility_ → _Public_
|
||||
|
||||
## Contributing
|
||||
|
||||
@ -156,3 +165,10 @@ This program is free software: you can redistribute it and/or modify it under th
|
||||
This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Affero General Public License along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
[codespace]: https://codespaces.new/mastodon/mastodon?quickstart=1&devcontainer_path=.devcontainer%2Fcodespaces%2Fdevcontainer.json
|
||||
[Dev Container extension]: https://containers.dev/supporting#dev-containers
|
||||
[Development Containers]: https://containers.dev/supporting
|
||||
[Docker]: https://docs.docker.com
|
||||
[GitHub Codespaces]: https://docs.github.com/en/codespaces
|
||||
[Homebrew]: https://brew.sh
|
||||
|
@ -2,7 +2,7 @@
|
||||
|
||||
If you believe you've identified a security vulnerability in Mastodon (a bug that allows something to happen that shouldn't be possible), you can either:
|
||||
|
||||
- open a [Github security issue on the Mastodon project](https://github.com/mastodon/mastodon/security/advisories/new)
|
||||
- open a [GitHub security issue on the Mastodon project](https://github.com/mastodon/mastodon/security/advisories/new)
|
||||
- reach us at <security@joinmastodon.org>
|
||||
|
||||
You should _not_ report such issues on public GitHub issues or in other public spaces to give us time to publish a fix for the issue without exposing Mastodon's users to increased risk.
|
||||
|
@ -498,7 +498,14 @@
|
||||
"poll_button.add_poll": "Aldoni balotenketon",
|
||||
"poll_button.remove_poll": "Forigi balotenketon",
|
||||
"privacy.change": "Agordi mesaĝan privatecon",
|
||||
"privacy.direct.long": "Ĉiuj menciitaj en la afiŝo",
|
||||
"privacy.direct.short": "Specifaj homoj",
|
||||
"privacy.private.long": "Nur viaj sekvantoj",
|
||||
"privacy.private.short": "Sekvantoj",
|
||||
"privacy.public.long": "Ĉiujn ajn ĉe kaj ekster Mastodon",
|
||||
"privacy.public.short": "Publika",
|
||||
"privacy.unlisted.long": "Malpli algoritmaj fanfaroj",
|
||||
"privacy.unlisted.short": "Diskrete publika",
|
||||
"privacy_policy.last_updated": "Laste ĝisdatigita en {date}",
|
||||
"privacy_policy.title": "Politiko de privateco",
|
||||
"recommended": "Rekomendita",
|
||||
|
@ -156,7 +156,7 @@
|
||||
"compose_form.poll.duration": "Durée du sondage",
|
||||
"compose_form.poll.multiple": "Choix multiple",
|
||||
"compose_form.poll.option_placeholder": "Option {number}",
|
||||
"compose_form.poll.single": "Choisissez-en un",
|
||||
"compose_form.poll.single": "Choix unique",
|
||||
"compose_form.poll.switch_to_multiple": "Changer le sondage pour autoriser plusieurs choix",
|
||||
"compose_form.poll.switch_to_single": "Changer le sondage pour n'autoriser qu'un seul choix",
|
||||
"compose_form.poll.type": "Style",
|
||||
@ -585,9 +585,9 @@
|
||||
"privacy.private.short": "Abonnés",
|
||||
"privacy.public.long": "Tout le monde sur et en dehors de Mastodon",
|
||||
"privacy.public.short": "Public",
|
||||
"privacy.unlisted.additional": "Cette option se comporte exactement comme l'option publique, sauf que le message n'apparaîtra pas dans les flux en direct, les hashtags, l'exploration ou la recherche Mastodon, même si vous avez opté pour l'option publique pour l'ensemble de votre compte.",
|
||||
"privacy.unlisted.additional": "Se comporte exactement comme « public », sauf que le message n'apparaîtra pas dans les flux en direct, les hashtags, explorer ou la recherche Mastodon, même si vous les avez activé au niveau de votre compte.",
|
||||
"privacy.unlisted.long": "Moins de fanfares algorithmiques",
|
||||
"privacy.unlisted.short": "Public calme",
|
||||
"privacy.unlisted.short": "Public discret",
|
||||
"privacy_policy.last_updated": "Dernière mise à jour {date}",
|
||||
"privacy_policy.title": "Politique de confidentialité",
|
||||
"recommended": "Recommandé",
|
||||
|
@ -156,7 +156,7 @@
|
||||
"compose_form.poll.duration": "Durée du sondage",
|
||||
"compose_form.poll.multiple": "Choix multiple",
|
||||
"compose_form.poll.option_placeholder": "Option {number}",
|
||||
"compose_form.poll.single": "Choisissez-en un",
|
||||
"compose_form.poll.single": "Choix unique",
|
||||
"compose_form.poll.switch_to_multiple": "Changer le sondage pour autoriser plusieurs choix",
|
||||
"compose_form.poll.switch_to_single": "Modifier le sondage pour autoriser qu'un seul choix",
|
||||
"compose_form.poll.type": "Style",
|
||||
@ -585,9 +585,9 @@
|
||||
"privacy.private.short": "Abonnés",
|
||||
"privacy.public.long": "Tout le monde sur et en dehors de Mastodon",
|
||||
"privacy.public.short": "Public",
|
||||
"privacy.unlisted.additional": "Cette option se comporte exactement comme l'option publique, sauf que le message n'apparaîtra pas dans les flux en direct, les hashtags, l'exploration ou la recherche Mastodon, même si vous avez opté pour l'option publique pour l'ensemble de votre compte.",
|
||||
"privacy.unlisted.additional": "Se comporte exactement comme « public », sauf que le message n'apparaîtra pas dans les flux en direct, les hashtags, explorer ou la recherche Mastodon, même si vous les avez activé au niveau de votre compte.",
|
||||
"privacy.unlisted.long": "Moins de fanfares algorithmiques",
|
||||
"privacy.unlisted.short": "Public calme",
|
||||
"privacy.unlisted.short": "Public discret",
|
||||
"privacy_policy.last_updated": "Dernière mise à jour {date}",
|
||||
"privacy_policy.title": "Politique de confidentialité",
|
||||
"recommended": "Recommandé",
|
||||
|
@ -19,7 +19,7 @@
|
||||
"account.block_domain": "Blocar dominio {domain}",
|
||||
"account.block_short": "Blocar",
|
||||
"account.blocked": "Blocate",
|
||||
"account.browse_more_on_origin_server": "Percurrer plus sur le profilo original",
|
||||
"account.browse_more_on_origin_server": "Explorar plus sur le profilo original",
|
||||
"account.cancel_follow_request": "Cancellar sequimento",
|
||||
"account.copy": "Copiar ligamine a profilo",
|
||||
"account.direct": "Mentionar privatemente @{name}",
|
||||
@ -111,7 +111,7 @@
|
||||
"bundle_modal_error.message": "Un error ha occurrite durante le cargamento de iste componente.",
|
||||
"bundle_modal_error.retry": "Tentar novemente",
|
||||
"closed_registrations.other_server_instructions": "Perque Mastodon es decentralisate, tu pote crear un conto sur un altere servitor e totevia interager con iste servitor.",
|
||||
"closed_registrations_modal.description": "Crear un conto in {domain} actualmente non es possibile, ma considera que non es necessari haber un conto specificamente sur {domain} pro usar Mastodon.",
|
||||
"closed_registrations_modal.description": "Crear un conto sur {domain} non es actualmente possibile, ma considera que non es necessari haber un conto specificamente sur {domain} pro usar Mastodon.",
|
||||
"closed_registrations_modal.find_another_server": "Cercar un altere servitor",
|
||||
"closed_registrations_modal.preamble": "Mastodon es decentralisate, dunque, non importa ubi tu crea tu conto, tu pote sequer e communicar con omne persona sur iste servitor. Tu pote mesmo hospitar tu proprie servitor!",
|
||||
"closed_registrations_modal.title": "Crear un conto sur Mastodon",
|
||||
|
@ -299,6 +299,11 @@
|
||||
"follow_suggestions.dismiss": "Jangan tampilkan lagi",
|
||||
"follow_suggestions.hints.featured": "Profil ini telah dipilih sendiri oleh tim {domain}.",
|
||||
"follow_suggestions.hints.friends_of_friends": "Profil ini populer di kalangan orang yang anda ikuti.",
|
||||
"follow_suggestions.personalized_suggestion": "Saran yang dipersonalisasi",
|
||||
"follow_suggestions.popular_suggestion": "Saran populer",
|
||||
"follow_suggestions.popular_suggestion_longer": "Populer di {domain}",
|
||||
"follow_suggestions.similar_to_recently_followed_longer": "Serupa dengan profil yang baru Anda ikuti",
|
||||
"follow_suggestions.view_all": "Lihat semua",
|
||||
"followed_tags": "Tagar yang diikuti",
|
||||
"footer.about": "Tentang",
|
||||
"footer.directory": "Direktori profil",
|
||||
@ -324,6 +329,7 @@
|
||||
"home.column_settings.show_reblogs": "Tampilkan boost",
|
||||
"home.column_settings.show_replies": "Tampilkan balasan",
|
||||
"home.hide_announcements": "Sembunyikan pengumuman",
|
||||
"home.pending_critical_update.link": "Lihat pembaruan",
|
||||
"home.show_announcements": "Tampilkan pengumuman",
|
||||
"interaction_modal.description.follow": "Dengan sebuah akun di Mastodon, Anda bisa mengikuti {name} untuk menerima kirimannya di beranda Anda.",
|
||||
"interaction_modal.description.reblog": "Dengan sebuah akun di Mastodon, Anda bisa mem-boost kiriman ini untuk membagikannya ke pengikut Anda sendiri.",
|
||||
@ -375,6 +381,7 @@
|
||||
"lightbox.previous": "Sebelumnya",
|
||||
"limited_account_hint.action": "Tetap tampilkan profil",
|
||||
"limited_account_hint.title": "Profil ini telah disembunyikan oleh moderator {domain}.",
|
||||
"link_preview.author": "Oleh {name}",
|
||||
"lists.account.add": "Tambah ke daftar",
|
||||
"lists.account.remove": "Hapus dari daftar",
|
||||
"lists.delete": "Hapus daftar",
|
||||
@ -389,8 +396,11 @@
|
||||
"lists.search": "Cari di antara orang yang Anda ikuti",
|
||||
"lists.subheading": "Daftar Anda",
|
||||
"load_pending": "{count, plural, other {# item baru}}",
|
||||
"loading_indicator.label": "Memuat…",
|
||||
"media_gallery.toggle_visible": "Tampil/Sembunyikan",
|
||||
"moved_to_account_banner.text": "Akun {disabledAccount} Anda kini dinonaktifkan karena Anda pindah ke {movedToAccount}.",
|
||||
"mute_modal.hide_options": "Sembunyikan opsi",
|
||||
"mute_modal.title": "Bisukan pengguna?",
|
||||
"navigation_bar.about": "Tentang",
|
||||
"navigation_bar.blocks": "Pengguna diblokir",
|
||||
"navigation_bar.bookmarks": "Markah",
|
||||
|
@ -1,7 +1,9 @@
|
||||
{
|
||||
"about.contact": "Ratio:",
|
||||
"about.domain_blocks.no_reason_available": "Ratio abdere est",
|
||||
"about.domain_blocks.silenced.explanation": "Tua profilia atque tuum contentum ab hac serve praecipue non videbis, nisi explōrēs expresse aut subsequeris et optēs.",
|
||||
"account.account_note_header": "Annotatio",
|
||||
"account.add_or_remove_from_list": "Adde aut ēripe ex tabellīs",
|
||||
"account.badges.bot": "Robotum",
|
||||
"account.badges.group": "Congregatio",
|
||||
"account.block": "Impedire @{name}",
|
||||
@ -11,11 +13,21 @@
|
||||
"account.domain_blocked": "Dominium impeditum",
|
||||
"account.edit_profile": "Recolere notionem",
|
||||
"account.featured_tags.last_status_never": "Nulla contributa",
|
||||
"account.featured_tags.title": "Hashtag notātī {name}",
|
||||
"account.followers_counter": "{count, plural, one {{counter} Sectator} other {{counter} Sectatores}}",
|
||||
"account.following_counter": "{count, plural, one {{counter} Sequens} other {{counter} Sequentes}}",
|
||||
"account.moved_to": "{name} significavit eum suam rationem novam nunc esse:",
|
||||
"account.muted": "Confutatus",
|
||||
"account.requested_follow": "{name} postulavit ut te sequeretur",
|
||||
"account.statuses_counter": "{count, plural, one {{counter} Nuntius} other {{counter} Nuntii}}",
|
||||
"account.unblock_short": "Solvere impedimentum",
|
||||
"account_note.placeholder": "Click to add a note",
|
||||
"admin.dashboard.retention.average": "Mediocritas",
|
||||
"admin.impact_report.instance_accounts": "Rationes perfiles hoc deleret",
|
||||
"alert.unexpected.message": "Error inopinatus occurrit.",
|
||||
"announcement.announcement": "Proclamatio",
|
||||
"attachments_list.unprocessed": "(immūtātus)",
|
||||
"block_modal.you_wont_see_mentions": "Nuntios quibus eos commemorant non videbis.",
|
||||
"bundle_column_error.error.title": "Eheu!",
|
||||
"bundle_column_error.retry": "Retemptare",
|
||||
"bundle_column_error.routing.title": "CCCCIIII",
|
||||
@ -37,26 +49,55 @@
|
||||
"compose_form.placeholder": "What is on your mind?",
|
||||
"compose_form.publish_form": "Barrire",
|
||||
"compose_form.spoiler.marked": "Text is hidden behind warning",
|
||||
"compose_form.spoiler.unmarked": "Text is not hidden",
|
||||
"compose_form.spoiler.unmarked": "Adde praeconium contentūs",
|
||||
"confirmations.block.confirm": "Impedire",
|
||||
"confirmations.delete.confirm": "Oblitterare",
|
||||
"confirmations.delete.message": "Are you sure you want to delete this status?",
|
||||
"confirmations.delete_list.confirm": "Oblitterare",
|
||||
"confirmations.discard_edit_media.message": "Habēs mutationēs in descriptionem vel prōspectum medii quae nōn sunt servātae; eas dēmittam?",
|
||||
"confirmations.mute.confirm": "Confutare",
|
||||
"confirmations.reply.confirm": "Respondere",
|
||||
"disabled_account_banner.account_settings": "Praeferentiae ratiōnis",
|
||||
"disabled_account_banner.text": "Ratio tua {disabledAccount} debilitata est.",
|
||||
"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_tags": "These hashtags are gaining traction among people on this and other servers of the decentralized network right now.",
|
||||
"domain_block_modal.you_will_lose_followers": "Omnes sectatores tuī ex hoc servō removēbuntur.",
|
||||
"domain_block_modal.you_wont_see_posts": "Nuntios aut notificātiōnēs ab usoribus in hōc servō nōn vidēbis.",
|
||||
"domain_pill.activitypub_like_language": "ActivityPub est velut lingua quam Mastodon cum aliīs sociālibus rētibus loquitur.",
|
||||
"domain_pill.your_handle": "Tuus nominulus:",
|
||||
"domain_pill.your_server": "Tua domus digitalis, ubi omnia tua nuntia habitant. Hanc non amas? Servēs trānsferāre potes quōcumque tempore et sectātōrēs tuōs simul addūcere.",
|
||||
"domain_pill.your_username": "Tuō singulāre id indicium in hōc servō est. Est possibile invenīre usōrēs cum eōdem nōmine in servīs aliīs.",
|
||||
"embed.instructions": "Embed this status on your website by copying the code below.",
|
||||
"emoji_button.activity": "Actiō",
|
||||
"emoji_button.food": "Cibus et potus",
|
||||
"emoji_button.people": "Homines",
|
||||
"emoji_button.search": "Quaerere...",
|
||||
"empty_column.account_suspended": "Rātiō suspēnsa",
|
||||
"empty_column.account_timeline": "Hic nulla contributa!",
|
||||
"empty_column.account_unavailable": "Notio non impetrabilis",
|
||||
"empty_column.home": "Your home timeline is empty! Follow more people to fill it up. {suggestions}",
|
||||
"empty_column.blocks": "Nondum quemquam usorem obsēcāvisti.",
|
||||
"empty_column.direct": "Nōn habēs adhūc ullo mentionēs prīvātās. Cum ūnam mīseris aut accipis, hīc apparēbit.",
|
||||
"empty_column.followed_tags": "Nōn adhūc aliquem hastāginem secūtus es. Cum id fēceris, hic ostendētur.",
|
||||
"empty_column.home": "Tua linea temporum domesticus vacua est! Sequere plures personas ut eam compleas.",
|
||||
"empty_column.list": "There is nothing in this list yet. When members of this list post new statuses, they will appear here.",
|
||||
"empty_column.lists": "Nōn adhūc habēs ullo tabellās. Cum creās, hīc apparēbunt.",
|
||||
"empty_column.mutes": "Nondum quemquam usorem tacuisti.",
|
||||
"empty_column.notification_requests": "Omnia clara sunt! Nihil hic est. Cum novās notificātiōnēs accipīs, hic secundum tua praecepta apparebunt.",
|
||||
"empty_column.notifications": "Nōn adhūc habēs ullo notificātiōnēs. Cum aliī tē interagunt, hīc videbis.",
|
||||
"explore.trending_statuses": "Contributa",
|
||||
"filtered_notifications_banner.mentions": "{count, plural, one {mentiō} other {mentiōnēs}}",
|
||||
"firehose.all": "Omnis",
|
||||
"footer.about": "De",
|
||||
"generic.saved": "Servavit",
|
||||
"hashtag.column_settings.tag_mode.all": "Haec omnia",
|
||||
"hashtag.column_settings.tag_toggle": "Include additional tags in this column",
|
||||
"hashtag.counter_by_accounts": "{count, plural, one {{counter} particeps} other {{counter} participēs}}",
|
||||
"hashtag.counter_by_uses": "{count, plural, one {{counter} nuntius} other {{counter} nuntii}}",
|
||||
"hashtag.counter_by_uses_today": "{count, plural, one {{counter} nuntius} other {{counter} nuntii}} hodie",
|
||||
"hashtags.and_other": "…et {count, plural, other {# plus}}",
|
||||
"intervals.full.days": "{number, plural, one {# die} other {# dies}}",
|
||||
"intervals.full.hours": "{number, plural, one {# hora} other {# horae}}",
|
||||
"intervals.full.minutes": "{number, plural, one {# minutum} other {# minuta}}",
|
||||
"keyboard_shortcuts.back": "Re navigare",
|
||||
"keyboard_shortcuts.blocked": "Aperire listam usorum obstructorum",
|
||||
"keyboard_shortcuts.boost": "Inlustrare publicatio",
|
||||
@ -90,18 +131,47 @@
|
||||
"keyboard_shortcuts.up": "to move up in the list",
|
||||
"lightbox.close": "Claudere",
|
||||
"lightbox.next": "Secundum",
|
||||
"lists.account.add": "Adde ad tabellās",
|
||||
"lists.new.create": "Addere tabella",
|
||||
"load_pending": "{count, plural, one {# novum item} other {# nova itema}}",
|
||||
"media_gallery.toggle_visible": "{number, plural, one {Cēla imaginem} other {Cēla imagines}}",
|
||||
"moved_to_account_banner.text": "Tua ratione {disabledAccount} interdum reposita est, quod ad {movedToAccount} migrāvisti.",
|
||||
"mute_modal.you_wont_see_mentions": "Non videbis nuntios quī eōs commemorant.",
|
||||
"navigation_bar.about": "De",
|
||||
"navigation_bar.domain_blocks": "Hidden domains",
|
||||
"not_signed_in_indicator.not_signed_in": "You need to sign in to access this resource.",
|
||||
"not_signed_in_indicator.not_signed_in": "Ad hunc locum pervenire oportet ut inīre facias.",
|
||||
"notification.admin.report": "{name} nuntiavit {target}",
|
||||
"notification.admin.sign_up": "{name} subscripsit",
|
||||
"notification.favourite": "{name} nuntium tuum favit",
|
||||
"notification.follow": "{name} te secutus est",
|
||||
"notification.follow_request": "{name} postulavit ut te sequeretur",
|
||||
"notification.mention": "{name} memoravi",
|
||||
"notification.moderation_warning": "Accepistī monitionem moderationis.",
|
||||
"notification.moderation_warning.action_disable": "Ratio tua debilitata est.",
|
||||
"notification.moderation_warning.action_none": "Tua ratiō monitum moderātiōnis accēpit.",
|
||||
"notification.reblog": "{name} boosted your status",
|
||||
"notification.moderation_warning.action_sensitive": "Tua nuntia hinc sensibiliter notabuntur.",
|
||||
"notification.moderation_warning.action_silence": "Ratio tua est limitata.",
|
||||
"notification.moderation_warning.action_suspend": "Ratio tua suspensus est.",
|
||||
"notification.own_poll": "Suffragium tuum terminatum est.",
|
||||
"notification.poll": "Electione in quam suffragium dedisti finita est.",
|
||||
"notification.reblog": "{name} tuum nuntium amplificavit.",
|
||||
"notification.relationships_severance_event.account_suspension": "Admin ab {from} {target} suspendit, quod significat nōn iam posse tē novitātēs ab eīs accipere aut cum eīs interagere.",
|
||||
"notification.relationships_severance_event.domain_block": "Admin ab {from} {target} obsēcāvit, includēns {followersCount} ex tuīs sectātōribus et {followingCount, plural, one {# ratione} other {# rationibus}} quās sequeris.",
|
||||
"notification.relationships_severance_event.user_domain_block": "Bloqueāstī {target}, removēns {followersCount} ex sectātōribus tuīs et {followingCount, plural, one {# rationem} other {# rationēs}} quōs sequeris.",
|
||||
"notification.status": "{name} nuper publicavit",
|
||||
"notification.update": "{name} nuntium correxit",
|
||||
"notification_requests.accept": "Accipe",
|
||||
"notifications.filter.all": "Omnia",
|
||||
"notifications.filter.polls": "Eventus electionis",
|
||||
"notifications.group": "Notificātiōnēs",
|
||||
"onboarding.actions.go_to_explore": "See what's trending",
|
||||
"onboarding.actions.go_to_home": "Go to your home feed",
|
||||
"onboarding.follows.lead": "You curate your own home feed. The more people you follow, the more active and interesting it will be. These profiles may be a good starting point—you can always unfollow them later!",
|
||||
"onboarding.follows.lead": "Tua domus feed est principalis via Mastodon experīrī. Quō plūrēs persōnas sequeris, eō actīvior et interessantior erit. Ad tē incipiendum, ecce quaedam suāsiones:",
|
||||
"onboarding.follows.title": "Popular on Mastodon",
|
||||
"onboarding.start.lead": "Your new Mastodon account is ready to go. Here's how you can make the most of it:",
|
||||
"onboarding.profile.display_name_hint": "Tuum nomen completum aut tuum nomen ludens...",
|
||||
"onboarding.start.lead": "Nunc pars es Mastodonis, singularis, socialis medii platformae decentralis ubi—non algorismus—tuam ipsius experientiam curas. Incipiāmus in nova hac socialis regione:",
|
||||
"onboarding.start.skip": "Want to skip right ahead?",
|
||||
"onboarding.start.title": "Perfecisti eam!",
|
||||
"onboarding.steps.follow_people.body": "You curate your own feed. Lets fill it with interesting people.",
|
||||
"onboarding.steps.follow_people.title": "Follow {count, plural, one {one person} other {# people}}",
|
||||
"onboarding.steps.publish_status.body": "Say hello to the world.",
|
||||
@ -109,31 +179,48 @@
|
||||
"onboarding.steps.setup_profile.title": "Customize your profile",
|
||||
"onboarding.steps.share_profile.body": "Let your friends know how to find you on Mastodon!",
|
||||
"onboarding.steps.share_profile.title": "Share your profile",
|
||||
"onboarding.tips.accounts_from_other_servers": "<strong>Scisne?</strong> Quoniam Mastodon dēcentālis est, nōnnulla profīlia quae invenīs in servīs aliīs quam tuōrum erunt hospitāta. Tamen cum eīs sine impedīmentō interāgere potes! Servus eōrum in alterā parte nōminis eōrum est!",
|
||||
"onboarding.tips.2fa": "<strong>Scisne?</strong> Tūam ratiōnem sēcūrāre potes duōrum elementōrum authentīcātiōnem in ratiōnis tuī praeferentiīs statuendō. Cum ūllā app TOTP ex tuā ēlēctiōne operātur, numerus tēlephōnicus necessārius nōn est!",
|
||||
"onboarding.tips.accounts_from_other_servers": "<strong>Scisne?</strong> Quoniam Mastodon dēcentrālis est, nōnnulla profīlia quae invenīs in servīs aliīs quam tuōrum erunt hospitāta. Tamen cum eīs sine impedīmentō interāgere potes! Servus eōrum in alterā parte nōminis eōrum est!",
|
||||
"onboarding.tips.migration": "<strong>Scisne?</strong> Sī sentīs {domain} tibi in futūrō nōn esse optimam servī ēlēctiōnem, ad alium servum Mastodon sine amittendō sectātōribus tuīs migrāre potes. Etiam tuum servum hospitārī potes!",
|
||||
"onboarding.tips.verification": "<strong>Scisne?</strong> Tūam ratiōnem verificāre potes iungendō nexum ad prōfīlium Mastodon tuum in propriā pāginā interrētiā et addendō pāginam ad prōfīlium tuum. Nullae pecūniae aut documenta necessāria sunt!",
|
||||
"poll.closed": "Clausum",
|
||||
"poll.total_people": "{count, plural, one {# persona} other {# personae}}",
|
||||
"poll.total_votes": "{count, plural, one {# suffragium} other {# suffragia}}",
|
||||
"poll.vote": "Eligere",
|
||||
"poll.voted": "Elegisti hoc responsum",
|
||||
"poll.votes": "{votes, plural, one {# sufragium} other {# sufragia}}",
|
||||
"poll_button.add_poll": "Addere electionem",
|
||||
"poll_button.remove_poll": "Auferre electionem",
|
||||
"privacy.change": "Adjust status privacy",
|
||||
"privacy.public.short": "Coram publico",
|
||||
"regeneration_indicator.sublabel": "Tua domus feed praeparātur!",
|
||||
"relative_time.full.days": "{number, plural, one {# ante die} other {# ante dies}}",
|
||||
"relative_time.full.hours": "{number, plural, one {# ante horam} other {# ante horas}}",
|
||||
"relative_time.full.just_now": "nunc",
|
||||
"relative_time.full.minutes": "{number, plural, one {# ante minutum} other {# ante minuta}}",
|
||||
"relative_time.full.seconds": "{number, plural, one {# ante secundum} other {# ante secunda}}",
|
||||
"relative_time.just_now": "nunc",
|
||||
"relative_time.today": "hodie",
|
||||
"reply_indicator.attachments": "{count, plural, one {# annexus} other {# annexūs}}",
|
||||
"report.block": "Impedimentum",
|
||||
"report.block_explanation": "Non videbis eorum nuntios. Non poterunt vidēre tuōs nuntios aut tē sequī. Intelligere poterunt sē obstrūctōs esse.",
|
||||
"report.categories.other": "Altera",
|
||||
"report.category.title_account": "notio",
|
||||
"report.category.title_status": "contributum",
|
||||
"report.close": "Confectum",
|
||||
"report.mute": "Confutare",
|
||||
"report.mute_explanation": "Non videbis eōrum nuntiōs. Possunt adhuc tē sequī et tuōs nuntiōs vidēre, nec sciēbunt sē tacitōs esse.",
|
||||
"report.next": "Secundum",
|
||||
"report.placeholder": "Type or paste additional comments",
|
||||
"report.placeholder": "Commentāriī adiūnctī",
|
||||
"report.submit": "Mittere",
|
||||
"report.target": "Report {target}",
|
||||
"report_notification.attached_statuses": "{count, plural, one {# post} other {# posts}} attached",
|
||||
"report_notification.attached_statuses": "{count, plural, one {{count} nuntius} other {{count} nuntii}} attachiatus",
|
||||
"report_notification.categories.other": "Altera",
|
||||
"search.placeholder": "Quaerere",
|
||||
"search_results.all": "Omnis",
|
||||
"server_banner.active_users": "Usūrāriī āctīvī",
|
||||
"server_banner.administered_by": "Administratur:",
|
||||
"server_banner.introduction": "{domain} pars est de rete sociali decentralizato a {mastodon} propulsato.",
|
||||
"server_banner.learn_more": "Discere plura",
|
||||
"sign_in_banner.sign_in": "Sign in",
|
||||
"status.admin_status": "Open this status in the moderation interface",
|
||||
@ -143,13 +230,29 @@
|
||||
"status.delete": "Oblitterare",
|
||||
"status.edit": "Recolere",
|
||||
"status.edited_x_times": "Edited {count, plural, one {# time} other {# times}}",
|
||||
"status.favourites": "{count, plural, one {favoritum} other {favorita}}",
|
||||
"status.history.created": "{name} creatum {date}",
|
||||
"status.history.edited": "{name} correxit {date}",
|
||||
"status.open": "Expand this status",
|
||||
"status.title.with_attachments": "{user} posted {attachmentCount, plural, one {an attachment} other {# attachments}}",
|
||||
"status.reblogged_by": "{name} adiuvavit",
|
||||
"status.reblogs": "{count, plural, one {auctus} other {auctūs}}",
|
||||
"status.title.with_attachments": "{user} publicavit {attachmentCount, plural, one {unum annexum} other {{attachmentCount} annexa}}",
|
||||
"tabs_bar.home": "Domi",
|
||||
"time_remaining.days": "{number, plural, one {# die} other {# dies}} restant",
|
||||
"time_remaining.hours": "{number, plural, one {# hora} other {# horae}} restant",
|
||||
"time_remaining.minutes": "{number, plural, one {# minutum} other {# minuta}} restant",
|
||||
"time_remaining.seconds": "{number, plural, one {# secundum} other {# secunda}} restant",
|
||||
"timeline_hint.remote_resource_not_displayed": "{resource} ab aliīs servīs nōn ostenduntur.",
|
||||
"timeline_hint.resources.statuses": "Contributa pristina",
|
||||
"trends.counter_by_accounts": "{count, plural, one {{counter} person} other {{counter} people}} in the past {days, plural, one {day} other {# days}}",
|
||||
"trends.counter_by_accounts": "{count, plural, one {{counter} persōna} other {{counter} persōnae}} in {days, plural, one {diē prīdiē} other {diēbus praeteritīs {days}}}",
|
||||
"ui.beforeunload": "Si Mastodon discesseris, tua epitome peribit.",
|
||||
"units.short.billion": "{count} millia milionum",
|
||||
"units.short.million": "{count} milionum",
|
||||
"units.short.thousand": "{count} millia",
|
||||
"upload_button.label": "Imaginēs, vīdeō aut fīle audītūs adde",
|
||||
"upload_form.audio_description": "Describe for people who are hard of hearing",
|
||||
"upload_form.edit": "Recolere",
|
||||
"upload_modal.description_placeholder": "A velox brunneis vulpes salit super piger canis",
|
||||
"upload_progress.label": "Uploading…",
|
||||
"video.mute": "Confutare soni"
|
||||
}
|
||||
|
@ -1,6 +1,8 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
class ActivityPub::Activity::Flag < ActivityPub::Activity
|
||||
COMMENT_SIZE_LIMIT = 5000
|
||||
|
||||
def perform
|
||||
return if skip_reports?
|
||||
|
||||
@ -38,6 +40,6 @@ class ActivityPub::Activity::Flag < ActivityPub::Activity
|
||||
end
|
||||
|
||||
def report_comment
|
||||
(@json['content'] || '')[0...5000]
|
||||
(@json['content'] || '')[0...COMMENT_SIZE_LIMIT]
|
||||
end
|
||||
end
|
||||
|
@ -18,6 +18,8 @@
|
||||
class Appeal < ApplicationRecord
|
||||
MAX_STRIKE_AGE = 20.days
|
||||
|
||||
TEXT_LENGTH_LIMIT = 2_000
|
||||
|
||||
belongs_to :account
|
||||
belongs_to :strike, class_name: 'AccountWarning', foreign_key: 'account_warning_id', inverse_of: :appeal
|
||||
|
||||
@ -26,7 +28,7 @@ class Appeal < ApplicationRecord
|
||||
belongs_to :rejected_by_account
|
||||
end
|
||||
|
||||
validates :text, presence: true, length: { maximum: 2_000 }
|
||||
validates :text, presence: true, length: { maximum: TEXT_LENGTH_LIMIT }
|
||||
validates :account_warning_id, uniqueness: true
|
||||
|
||||
validate :validate_time_frame, on: :create
|
||||
|
@ -187,7 +187,7 @@ class PostStatusService < BaseService
|
||||
end
|
||||
|
||||
def scheduled_in_the_past?
|
||||
@scheduled_at.present? && @scheduled_at <= Time.now.utc + MIN_SCHEDULE_OFFSET
|
||||
@scheduled_at.present? && @scheduled_at <= Time.now.utc
|
||||
end
|
||||
|
||||
def bump_potential_friendship!
|
||||
|
@ -18,7 +18,7 @@ FileUtils.chdir APP_ROOT do
|
||||
system('bundle check') || system!('bundle install')
|
||||
|
||||
puts "\n== Installing JS dependencies =="
|
||||
system! 'corepack prepare'
|
||||
system! 'corepack enable'
|
||||
system! 'bin/yarn install --immutable'
|
||||
|
||||
puts "\n== Preparing database =="
|
||||
|
@ -60,9 +60,10 @@ Bundler.require(:pam_authentication) if ENV['PAM_ENABLED'] == 'true'
|
||||
module Mastodon
|
||||
class Application < Rails::Application
|
||||
# Initialize configuration defaults for originally generated Rails version.
|
||||
config.load_defaults 7.0
|
||||
config.load_defaults 7.1
|
||||
|
||||
config.active_record.marshalling_format_version = 7.1
|
||||
# Explicitly set the cache format version to align with Rails version
|
||||
config.active_support.cache_format_version = 7.1
|
||||
|
||||
# Please, add to the `ignore` list any other `lib` subdirectories that do
|
||||
# not contain `.rb` files, or that should not be reloaded or eager loaded.
|
||||
|
@ -32,4 +32,9 @@ Rails.application.configure do
|
||||
config.active_record.encryption.deterministic_key = ENV.fetch('ACTIVE_RECORD_ENCRYPTION_DETERMINISTIC_KEY')
|
||||
config.active_record.encryption.key_derivation_salt = ENV.fetch('ACTIVE_RECORD_ENCRYPTION_KEY_DERIVATION_SALT')
|
||||
config.active_record.encryption.primary_key = ENV.fetch('ACTIVE_RECORD_ENCRYPTION_PRIMARY_KEY')
|
||||
config.active_record.encryption.support_sha1_for_non_deterministic_encryption = true
|
||||
|
||||
# TODO: https://github.com/rails/rails/issues/50604#issuecomment-1880990392
|
||||
# Remove after updating to Rails 7.1.4
|
||||
ActiveRecord::Encryption.configure(**config.active_record.encryption)
|
||||
end
|
||||
|
@ -1,214 +0,0 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
# Be sure to restart your server when you modify this file.
|
||||
#
|
||||
# This file eases your Rails 7.1 framework defaults upgrade.
|
||||
#
|
||||
# Uncomment each configuration one by one to switch to the new default.
|
||||
# Once your application is ready to run with all new defaults, you can remove
|
||||
# this file and set the `config.load_defaults` to `7.1`.
|
||||
#
|
||||
# Read the Guide for Upgrading Ruby on Rails for more info on each option.
|
||||
# https://guides.rubyonrails.org/upgrading_ruby_on_rails.html
|
||||
|
||||
# No longer add autoloaded paths into `$LOAD_PATH`. This means that you won't be able
|
||||
# to manually require files that are managed by the autoloader, which you shouldn't do anyway.
|
||||
# This will reduce the size of the load path, making `require` faster if you don't use bootsnap, or reduce the size
|
||||
# of the bootsnap cache if you use it.
|
||||
Rails.application.config.add_autoload_paths_to_load_path = false
|
||||
|
||||
# Remove the default X-Download-Options headers since it is used only by Internet Explorer.
|
||||
# If you need to support Internet Explorer, add back `"X-Download-Options" => "noopen"`.
|
||||
# Rails.application.config.action_dispatch.default_headers = {
|
||||
# "X-Frame-Options" => "SAMEORIGIN",
|
||||
# "X-XSS-Protection" => "0",
|
||||
# "X-Content-Type-Options" => "nosniff",
|
||||
# "X-Permitted-Cross-Domain-Policies" => "none",
|
||||
# "Referrer-Policy" => "strict-origin-when-cross-origin"
|
||||
# }
|
||||
|
||||
# Do not treat an `ActionController::Parameters` instance
|
||||
# as equal to an equivalent `Hash` by default.
|
||||
Rails.application.config.action_controller.allow_deprecated_parameters_hash_equality = false
|
||||
|
||||
# Active Record Encryption now uses SHA-256 as its hash digest algorithm. Important: If you have
|
||||
# data encrypted with previous Rails versions, there are two scenarios to consider:
|
||||
#
|
||||
# 1. If you have +config.active_support.key_generator_hash_digest_class+ configured as SHA1 (the default
|
||||
# before Rails 7.0), you need to configure SHA-1 for Active Record Encryption too:
|
||||
# Rails.application.config.active_record.encryption.hash_digest_class = OpenSSL::Digest::SHA1
|
||||
# 2. If you have +config.active_support.key_generator_hash_digest_class+ configured as SHA256 (the new default
|
||||
# in 7.0), then you need to configure SHA-256 for Active Record Encryption:
|
||||
# Rails.application.config.active_record.encryption.hash_digest_class = OpenSSL::Digest::SHA256
|
||||
#
|
||||
# If you don't currently have data encrypted with Active Record encryption, you can disable this setting to
|
||||
# configure the default behavior starting 7.1+:
|
||||
# Rails.application.config.active_record.encryption.support_sha1_for_non_deterministic_encryption = false
|
||||
|
||||
# No longer run after_commit callbacks on the first of multiple Active Record
|
||||
# instances to save changes to the same database row within a transaction.
|
||||
# Instead, run these callbacks on the instance most likely to have internal
|
||||
# state which matches what was committed to the database, typically the last
|
||||
# instance to save.
|
||||
Rails.application.config.active_record.run_commit_callbacks_on_first_saved_instances_in_transaction = false
|
||||
|
||||
# Configures SQLite with a strict strings mode, which disables double-quoted string literals.
|
||||
#
|
||||
# SQLite has some quirks around double-quoted string literals.
|
||||
# It first tries to consider double-quoted strings as identifier names, but if they don't exist
|
||||
# it then considers them as string literals. Because of this, typos can silently go unnoticed.
|
||||
# For example, it is possible to create an index for a non existing column.
|
||||
# See https://www.sqlite.org/quirks.html#double_quoted_string_literals_are_accepted for more details.
|
||||
Rails.application.config.active_record.sqlite3_adapter_strict_strings_by_default = true
|
||||
|
||||
# Disable deprecated singular associations names
|
||||
Rails.application.config.active_record.allow_deprecated_singular_associations_name = false
|
||||
|
||||
# Enable the Active Job `BigDecimal` argument serializer, which guarantees
|
||||
# roundtripping. Without this serializer, some queue adapters may serialize
|
||||
# `BigDecimal` arguments as simple (non-roundtrippable) strings.
|
||||
#
|
||||
# When deploying an application with multiple replicas, old (pre-Rails 7.1)
|
||||
# replicas will not be able to deserialize `BigDecimal` arguments from this
|
||||
# serializer. Therefore, this setting should only be enabled after all replicas
|
||||
# have been successfully upgraded to Rails 7.1.
|
||||
# Rails.application.config.active_job.use_big_decimal_serializer = true
|
||||
|
||||
# Specify if an `ArgumentError` should be raised if `Rails.cache` `fetch` or
|
||||
# `write` are given an invalid `expires_at` or `expires_in` time.
|
||||
# Options are `true`, and `false`. If `false`, the exception will be reported
|
||||
# as `handled` and logged instead.
|
||||
Rails.application.config.active_support.raise_on_invalid_cache_expiration_time = true
|
||||
|
||||
# Specify whether Query Logs will format tags using the SQLCommenter format
|
||||
# (https://open-telemetry.github.io/opentelemetry-sqlcommenter/), or using the legacy format.
|
||||
# Options are `:legacy` and `:sqlcommenter`.
|
||||
Rails.application.config.active_record.query_log_tags_format = :sqlcommenter
|
||||
|
||||
# Specify the default serializer used by `MessageEncryptor` and `MessageVerifier`
|
||||
# instances.
|
||||
#
|
||||
# The legacy default is `:marshal`, which is a potential vector for
|
||||
# deserialization attacks in cases where a message signing secret has been
|
||||
# leaked.
|
||||
#
|
||||
# In Rails 7.1, the new default is `:json_allow_marshal` which serializes and
|
||||
# deserializes with `ActiveSupport::JSON`, but can fall back to deserializing
|
||||
# with `Marshal` so that legacy messages can still be read.
|
||||
#
|
||||
# In Rails 7.2, the default will become `:json` which serializes and
|
||||
# deserializes with `ActiveSupport::JSON` only.
|
||||
#
|
||||
# Alternatively, you can choose `:message_pack` or `:message_pack_allow_marshal`,
|
||||
# which serialize with `ActiveSupport::MessagePack`. `ActiveSupport::MessagePack`
|
||||
# can roundtrip some Ruby types that are not supported by JSON, and may provide
|
||||
# improved performance, but it requires the `msgpack` gem.
|
||||
#
|
||||
# For more information, see
|
||||
# https://guides.rubyonrails.org/v7.1/configuring.html#config-active-support-message-serializer
|
||||
#
|
||||
# If you are performing a rolling deploy of a Rails 7.1 upgrade, wherein servers
|
||||
# that have not yet been upgraded must be able to read messages from upgraded
|
||||
# servers, first deploy without changing the serializer, then set the serializer
|
||||
# in a subsequent deploy.
|
||||
# Rails.application.config.active_support.message_serializer = :json_allow_marshal
|
||||
|
||||
# Enable a performance optimization that serializes message data and metadata
|
||||
# together. This changes the message format, so messages serialized this way
|
||||
# cannot be read by older versions of Rails. However, messages that use the old
|
||||
# format can still be read, regardless of whether this optimization is enabled.
|
||||
#
|
||||
# To perform a rolling deploy of a Rails 7.1 upgrade, wherein servers that have
|
||||
# not yet been upgraded must be able to read messages from upgraded servers,
|
||||
# leave this optimization off on the first deploy, then enable it on a
|
||||
# subsequent deploy.
|
||||
# Rails.application.config.active_support.use_message_serializer_for_metadata = true
|
||||
|
||||
# Set the maximum size for Rails log files.
|
||||
#
|
||||
# `config.load_defaults 7.1` does not set this value for environments other than
|
||||
# development and test.
|
||||
#
|
||||
Rails.application.config.log_file_size = 100 * 1024 * 1024 if Rails.env.local?
|
||||
|
||||
# Enable raising on assignment to attr_readonly attributes. The previous
|
||||
# behavior would allow assignment but silently not persist changes to the
|
||||
# database.
|
||||
Rails.application.config.active_record.raise_on_assign_to_attr_readonly = true
|
||||
|
||||
# Enable validating only parent-related columns for presence when the parent is mandatory.
|
||||
# The previous behavior was to validate the presence of the parent record, which performed an extra query
|
||||
# to get the parent every time the child record was updated, even when parent has not changed.
|
||||
Rails.application.config.active_record.belongs_to_required_validates_foreign_key = false
|
||||
|
||||
# Enable precompilation of `config.filter_parameters`. Precompilation can
|
||||
# improve filtering performance, depending on the quantity and types of filters.
|
||||
Rails.application.config.precompile_filter_parameters = true
|
||||
|
||||
# Enable before_committed! callbacks on all enrolled records in a transaction.
|
||||
# The previous behavior was to only run the callbacks on the first copy of a record
|
||||
# if there were multiple copies of the same record enrolled in the transaction.
|
||||
Rails.application.config.active_record.before_committed_on_all_records = true
|
||||
|
||||
# Disable automatic column serialization into YAML.
|
||||
# To keep the historic behavior, you can set it to `YAML`, however it is
|
||||
# recommended to explicitly define the serialization method for each column
|
||||
# rather than to rely on a global default.
|
||||
Rails.application.config.active_record.default_column_serializer = nil
|
||||
|
||||
# Run `after_commit` and `after_*_commit` callbacks in the order they are defined in a model.
|
||||
# This matches the behaviour of all other callbacks.
|
||||
# In previous versions of Rails, they ran in the inverse order.
|
||||
Rails.application.config.active_record.run_after_transaction_callbacks_in_order_defined = true
|
||||
|
||||
# Whether a `transaction` block is committed or rolled back when exited via `return`, `break` or `throw`.
|
||||
#
|
||||
# Rails.application.config.active_record.commit_transaction_on_non_local_return = true
|
||||
|
||||
# Controls when to generate a value for <tt>has_secure_token</tt> declarations.
|
||||
#
|
||||
Rails.application.config.active_record.generate_secure_token_on = :initialize
|
||||
|
||||
# ** Please read carefully, this must be configured in config/application.rb **
|
||||
# Change the format of the cache entry.
|
||||
# Changing this default means that all new cache entries added to the cache
|
||||
# will have a different format that is not supported by Rails 7.0
|
||||
# applications.
|
||||
# Only change this value after your application is fully deployed to Rails 7.1
|
||||
# and you have no plans to rollback.
|
||||
# When you're ready to change format, add this to `config/application.rb` (NOT
|
||||
# this file):
|
||||
# config.active_support.cache_format_version = 7.1
|
||||
|
||||
# Configure Action View to use HTML5 standards-compliant sanitizers when they are supported on your
|
||||
# platform.
|
||||
#
|
||||
# `Rails::HTML::Sanitizer.best_supported_vendor` will cause Action View to use HTML5-compliant
|
||||
# sanitizers if they are supported, else fall back to HTML4 sanitizers.
|
||||
#
|
||||
# In previous versions of Rails, Action View always used `Rails::HTML4::Sanitizer` as its vendor.
|
||||
#
|
||||
Rails.application.config.action_view.sanitizer_vendor = Rails::HTML::Sanitizer.best_supported_vendor
|
||||
|
||||
# Configure Action Text to use an HTML5 standards-compliant sanitizer when it is supported on your
|
||||
# platform.
|
||||
#
|
||||
# `Rails::HTML::Sanitizer.best_supported_vendor` will cause Action Text to use HTML5-compliant
|
||||
# sanitizers if they are supported, else fall back to HTML4 sanitizers.
|
||||
#
|
||||
# In previous versions of Rails, Action Text always used `Rails::HTML4::Sanitizer` as its vendor.
|
||||
#
|
||||
# Rails.application.config.action_text.sanitizer_vendor = Rails::HTML::Sanitizer.best_supported_vendor
|
||||
|
||||
# Configure the log level used by the DebugExceptions middleware when logging
|
||||
# uncaught exceptions during requests
|
||||
# Rails.application.config.action_dispatch.debug_exception_log_level = :error
|
||||
|
||||
# Configure the test helpers in Action View, Action Dispatch, and rails-dom-testing to use HTML5
|
||||
# parsers.
|
||||
#
|
||||
# Nokogiri::HTML5 isn't supported on JRuby, so JRuby applications must set this to :html4.
|
||||
#
|
||||
# In previous versions of Rails, these test helpers always used an HTML4 parser.
|
||||
#
|
||||
Rails.application.config.dom_testing_default_html_version = :html5
|
@ -1 +1,8 @@
|
||||
---
|
||||
la:
|
||||
devise:
|
||||
passwords:
|
||||
send_instructions: Sī adresa tua epistularis in nostra basi datōrum exstat, vinculum ad recuperandam clavem adresa tua epistulari adferētur pauca momenta post. Sī autem hanc epistulam nōn recēpistī, rogāmus ut scrūtināriōnem spurcāriī tuī faciās.
|
||||
registrations:
|
||||
destroyed: Vale! Ratio tua succēssu cancellāta est. Spērāmus tē mox iterum vidēre.
|
||||
signed_up_but_inactive: Te cōnscrīpsistī succēdāneē. At nōn potuimus tē introīre quod ratio* tua nōn adhūc est activāta.*
|
||||
|
@ -135,6 +135,7 @@ ja:
|
||||
media: メディアの添付
|
||||
mutes: ミュート
|
||||
notifications: 通知
|
||||
profile: Mastodonのプロフィール
|
||||
push: プッシュ通知
|
||||
reports: 通報
|
||||
search: 検索
|
||||
@ -165,6 +166,7 @@ ja:
|
||||
admin:write:reports: 通報に対するアクションの実行
|
||||
crypto: エンドツーエンド暗号化の使用
|
||||
follow: アカウントのつながりを変更
|
||||
profile: アカウントのプロフィール情報の読み取りのみ
|
||||
push: プッシュ通知の受信
|
||||
read: アカウントのすべてのデータの読み取り
|
||||
read:accounts: アカウント情報の読み取り
|
||||
|
@ -135,6 +135,7 @@ lad:
|
||||
media: Aneksos de multimedia
|
||||
mutes: Silensiasyones
|
||||
notifications: Avizos
|
||||
profile: Tu profil de Mastodon
|
||||
push: Avizos arrepushados
|
||||
reports: Raportos
|
||||
search: Bushkeda
|
||||
@ -165,6 +166,7 @@ lad:
|
||||
admin:write:reports: fazer aksyones de moderasyon en raportos
|
||||
crypto: kulanear shifrasyon de lado a lado
|
||||
follow: modifikar relasyones de kuentos
|
||||
profile: melda solo la informasyon del profil
|
||||
push: risivir tus avizos arrepushados
|
||||
read: meldar todos tus datos de kuento
|
||||
read:accounts: ver enformasyon de kuentos
|
||||
|
@ -135,6 +135,7 @@ lt:
|
||||
media: Medijos priedai
|
||||
mutes: Nutildymai
|
||||
notifications: Pranešimai
|
||||
profile: Tavo Mastodon profilis
|
||||
push: Tiesioginiai pranešimai
|
||||
reports: Ataskaitos
|
||||
search: Paieška
|
||||
@ -165,6 +166,7 @@ lt:
|
||||
admin:write:reports: atlikti ataskaitų prižiūrėjimo veiksmus
|
||||
crypto: naudoti visapusį šifravimą
|
||||
follow: modifikuoti paskyros sąryšius
|
||||
profile: skaityti tik tavo paskyros profilio informaciją
|
||||
push: gauti tiesioginius pranešimus
|
||||
read: skaityti visus paskyros duomenis
|
||||
read:accounts: matyti paskyrų informaciją
|
||||
|
@ -135,6 +135,7 @@ sv:
|
||||
media: Mediabilagor
|
||||
mutes: Tystade användare
|
||||
notifications: Aviseringar
|
||||
profile: Din Mastodon-profil
|
||||
push: Push-aviseringar
|
||||
reports: Rapporter
|
||||
search: Sök
|
||||
|
@ -135,6 +135,7 @@ th:
|
||||
media: ไฟล์แนบสื่อ
|
||||
mutes: การซ่อน
|
||||
notifications: การแจ้งเตือน
|
||||
profile: โปรไฟล์ Mastodon ของคุณ
|
||||
push: การแจ้งเตือนแบบผลัก
|
||||
reports: การรายงาน
|
||||
search: ค้นหา
|
||||
@ -165,6 +166,7 @@ th:
|
||||
admin:write:reports: ทำการกระทำการกลั่นกรองต่อรายงาน
|
||||
crypto: ใช้การเข้ารหัสแบบต้นทางถึงปลายทาง
|
||||
follow: ปรับเปลี่ยนความสัมพันธ์ของบัญชี
|
||||
profile: อ่านเฉพาะข้อมูลโปรไฟล์ของบัญชีของคุณเท่านั้น
|
||||
push: รับการแจ้งเตือนแบบผลักของคุณ
|
||||
read: อ่านข้อมูลบัญชีทั้งหมดของคุณ
|
||||
read:accounts: ดูข้อมูลบัญชี
|
||||
|
@ -135,6 +135,7 @@ vi:
|
||||
media: Tập tin đính kèm
|
||||
mutes: Đã ẩn
|
||||
notifications: Thông báo
|
||||
profile: Hồ sơ Mastodon của bạn
|
||||
push: Thông báo đẩy
|
||||
reports: Báo cáo
|
||||
search: Tìm kiếm
|
||||
@ -165,6 +166,7 @@ vi:
|
||||
admin:write:reports: áp đặt kiểm duyệt với các báo cáo
|
||||
crypto: dùng mã hóa đầu cuối
|
||||
follow: sửa đổi các mối quan hệ tài khoản
|
||||
profile: chỉ đọc thông tin tài khoản cơ bản
|
||||
push: nhận thông báo đẩy
|
||||
read: đọc mọi dữ liệu tài khoản
|
||||
read:accounts: xem thông tin tài khoản
|
||||
|
@ -89,6 +89,7 @@ id:
|
||||
moderation:
|
||||
active: Aktif
|
||||
all: Semua
|
||||
disabled: Nonaktif
|
||||
pending: Tertunda
|
||||
silenced: Terbatas
|
||||
suspended: Disuspen
|
||||
@ -121,6 +122,8 @@ id:
|
||||
removed_header_msg: Berhasil menghapus gambar header %{username}
|
||||
resend_confirmation:
|
||||
already_confirmed: Pengguna ini sudah dikonfirmasi
|
||||
send: Kirim ulang email konfirmasi
|
||||
success: Email konfirmasi berhasil dikirim!
|
||||
reset: Atur ulang
|
||||
reset_password: Reset kata sandi
|
||||
resubscribe: Langganan ulang
|
||||
@ -128,6 +131,7 @@ id:
|
||||
search: Cari
|
||||
search_same_email_domain: Pengguna lain dengan domain email yang sama
|
||||
search_same_ip: Pengguna lain dengan IP yang sama
|
||||
security: Keamanan
|
||||
security_measures:
|
||||
only_password: Hanya kata sandi
|
||||
password_and_2fa: Kata sandi dan 2FA
|
||||
@ -278,6 +282,7 @@ id:
|
||||
update_custom_emoji_html: "%{name} memperbarui emoji %{target}"
|
||||
update_domain_block_html: "%{name} memperbarui blokir domain untuk %{target}"
|
||||
update_ip_block_html: "%{name} mengubah peraturan untuk IP %{target}"
|
||||
update_report_html: "%{name} memperbarui laporan %{target}"
|
||||
update_status_html: "%{name} memperbarui status %{target}"
|
||||
update_user_role_html: "%{name} mengubah peran %{target}"
|
||||
deleted_account: akun yang dihapus
|
||||
@ -302,6 +307,7 @@ id:
|
||||
unpublish: Batal terbitkan
|
||||
unpublished_msg: Pengumuman berhasil ditarik!
|
||||
updated_msg: Pengumuman berhasil diperbarui!
|
||||
critical_update_pending: Pembaruan penting tertunda
|
||||
custom_emojis:
|
||||
assign_category: Beri kategori
|
||||
by_domain: Domain
|
||||
|
@ -1 +1,34 @@
|
||||
---
|
||||
la:
|
||||
about:
|
||||
about_mastodon_html: '"Rete sociale futuri: Nullae praebendae, nulla observatio corporativa, ethica designatio, et decentralizatio! Tua data cum Mastodonte posside!"'
|
||||
contact_missing: Non definitum
|
||||
contact_unavailable: Nōn Applicābilis
|
||||
hosted_on: Mastodon in %{domain} hospitātum
|
||||
title: De
|
||||
accounts:
|
||||
follow: Sequere
|
||||
followers:
|
||||
one: Sectātor
|
||||
other: Sectātōrēs
|
||||
following: Sequendī
|
||||
instance_actor_flash: Hic ratio est actōr virtuālis ad repraesentandam ipsum servatorem et non ullam individuam usorem. Ad scopōs foederātiōnis ūtor nec suspendendus est.
|
||||
last_active: Ultimum Actum
|
||||
link_verified_on: Dominium huius nexūs est comprobatum die %{date}.
|
||||
nothing_here: Nihil est hic!
|
||||
pin_errors:
|
||||
following: Iam debes sequi personam quam vis probare.
|
||||
posts:
|
||||
one: Nuntius
|
||||
other: Nuntii
|
||||
posts_tab_heading: Nuntii
|
||||
admin:
|
||||
account_actions:
|
||||
action: Agere actionem
|
||||
title: Actionem moderationis in %{acct} gerere
|
||||
account_moderation_notes:
|
||||
create: Relinque nota
|
||||
created_msg: Nota moderationis feliciter creata est!
|
||||
destroyed_msg: Nota moderationis feliciter deleta est!
|
||||
accounts:
|
||||
are_you_sure: Esne certus?
|
||||
|
@ -1814,14 +1814,14 @@ nl:
|
||||
subject: Jouw archief staat klaar om te worden gedownload
|
||||
title: Archief ophalen
|
||||
failed_2fa:
|
||||
details: 'Hier zijn details van de inlogpoging:'
|
||||
details: 'Hier zijn de details van de inlogpoging:'
|
||||
explanation: Iemand heeft geprobeerd om in te loggen op jouw account maar heeft een ongeldige tweede verificatiefactor opgegeven.
|
||||
further_actions_html: Als jij dit niet was, raden we je aan om onmiddellijk %{action} aangezien het in gevaar kan zijn.
|
||||
subject: Tweestapsverificatiefout
|
||||
title: Tweestapsverificatie mislukt
|
||||
suspicious_sign_in:
|
||||
change_password: je wachtwoord te wijzigen
|
||||
details: 'Hier zijn de details van inlogpoging:'
|
||||
details: 'Hier zijn de details van het inloggen:'
|
||||
explanation: We hebben vastgesteld dat iemand vanaf een nieuw IP-adres op jouw account is ingelogd.
|
||||
further_actions_html: Wanneer jij dit niet was, adviseren wij om onmiddellijk %{action} en om tweestapsverificatie in te schakelen, om zo je account veilig te houden.
|
||||
subject: Jouw account is vanaf een nieuw IP-adres benaderd
|
||||
|
@ -2,6 +2,9 @@
|
||||
id:
|
||||
simple_form:
|
||||
hints:
|
||||
account:
|
||||
discoverable: Postingan dan profil publik Anda mungkin ditampilkan atau direkomendasikan di berbagai area Mastodon dan profil Anda mungkin disarankan ke pengguna lain.
|
||||
display_name: Nama lengkap Anda atau nama lucu Anda.
|
||||
account_alias:
|
||||
acct: Tentukan namapengguna@domain akun yang ingin Anda pindah
|
||||
account_migration:
|
||||
|
@ -1837,11 +1837,13 @@ th:
|
||||
edit_profile_title: ปรับแต่งโปรไฟล์ของคุณ
|
||||
explanation: นี่คือเคล็ดลับบางส่วนที่จะช่วยให้คุณเริ่มต้นใช้งาน
|
||||
feature_action: เรียนรู้เพิ่มเติม
|
||||
feature_audience: Mastodon มีความพิเศษที่ให้คุณจัดการผู้รับสารของคุณได้โดยไม่มีตัวกลาง นอกจากนี้ การติดตั้ง Mastodon บนโครงสร้างพื้นฐานของคุณจะทำให้คุณสามารถติดตาม (และติดตามโดย) เซิร์ฟเวอร์ Mastodon แห่งไหนก็ได้ที่ทำงานอยู่ โดยไม่มีใครสามารถควบคุมได้นอกจากคุณ
|
||||
feature_audience: Mastodon ให้ความเป็นไปได้ที่เป็นเอกลักษณ์แก่คุณในการจัดการผู้ชมของคุณโดยไม่มีตัวกลาง Mastodon ที่ปรับใช้ในโครงสร้างพื้นฐานของคุณเองอนุญาตให้คุณติดตามและได้รับการติดตามจากเซิร์ฟเวอร์ Mastodon อื่นใดทางออนไลน์และไม่อยู่ภายใต้การควบคุมของใครนอกจากคุณ
|
||||
feature_audience_title: สร้างผู้ชมของคุณด้วยความมั่นใจ
|
||||
feature_control: คุณทราบดีที่สุดถึงสิ่งที่คุณต้องการเห็นในฟีดหน้าแรกของคุณ ไม่มีอัลกอริทึมหรือโฆษณาให้เสียเวลาของคุณ ติดตามใครก็ตามทั่วทั้งเซิร์ฟเวอร์ Mastodon ใด ๆ จากบัญชีเดียวและรับโพสต์ของเขาตามลำดับเวลา และทำให้มุมอินเทอร์เน็ตของคุณเป็นเหมือนคุณมากขึ้นอีกนิด
|
||||
feature_control_title: การควบคุมเส้นเวลาของคุณเอง
|
||||
feature_creativity: Mastodon รองรับโพสต์เสียง วิดีโอ และรูปภาพ, คำอธิบายการช่วยการเข้าถึง, การสำรวจความคิดเห็น, คำเตือนเนื้อหา, ภาพประจำตัวแบบเคลื่อนไหว, อีโมจิที่กำหนดเอง, การควบคุมการครอบตัดภาพขนาดย่อ และอื่น ๆ เพื่อช่วยให้คุณแสดงออกตัวคุณเองทางออนไลน์ ไม่ว่าคุณกำลังจะเผยแพร่ศิลปะของคุณ, เพลงของคุณ หรือพอดแคสต์ของคุณ Mastodon อยู่ที่นั่นเพื่อคุณ
|
||||
feature_creativity_title: ความคิดสร้างสรรค์ที่ไม่มีใครเทียบได้
|
||||
feature_moderation: Mastodon นำการตัดสินใจกลับมาอยู่ในมือของคุณ แต่ละเซิร์ฟเวอร์สร้างกฎและระเบียบข้อบังคับของตนเอง ซึ่งบังคับใช้ในเซิร์ฟเวอร์และไม่ใช่จากบนลงล่างเหมือนสื่อสังคมขององค์กร ทำให้สื่อสังคมยืดหยุ่นมากที่สุดในการตอบสนองต่อความต้องการของกลุ่มคนที่แตกต่างกัน เข้าร่วมเซิร์ฟเวอร์ที่มีกฎที่คุณเห็นด้วย หรือโฮสต์ของคุณเอง
|
||||
feature_moderation_title: การกลั่นกรองในแบบที่ควรจะเป็น
|
||||
follow_action: ติดตาม
|
||||
follow_step: การติดตามผู้คนที่น่าสนใจคือสิ่งที่ Mastodon ให้ความสำคัญ
|
||||
|
@ -1,4 +1,4 @@
|
||||
# This is needed for the Github Action
|
||||
# This is needed for the GitHub Action
|
||||
project_id_env: CROWDIN_PROJECT_ID
|
||||
api_token_env: CROWDIN_PERSONAL_TOKEN
|
||||
|
||||
|
@ -54,7 +54,7 @@ RSpec.describe ActivityPub::Activity::Flag do
|
||||
}.with_indifferent_access, sender)
|
||||
end
|
||||
|
||||
let(:long_comment) { Faker::Lorem.characters(number: 6000) }
|
||||
let(:long_comment) { 'a' * described_class::COMMENT_SIZE_LIMIT * 2 }
|
||||
|
||||
before do
|
||||
subject.perform
|
||||
@ -63,10 +63,12 @@ RSpec.describe ActivityPub::Activity::Flag do
|
||||
it 'creates a report but with a truncated comment' do
|
||||
report = Report.find_by(account: sender, target_account: flagged)
|
||||
|
||||
expect(report).to_not be_nil
|
||||
expect(report.comment.length).to eq 5000
|
||||
expect(report.comment).to eq long_comment[0...5000]
|
||||
expect(report.status_ids).to eq [status.id]
|
||||
expect(report)
|
||||
.to be_present
|
||||
.and have_attributes(status_ids: [status.id])
|
||||
expect(report.comment)
|
||||
.to have_attributes(length: described_class::COMMENT_SIZE_LIMIT)
|
||||
.and eq(long_comment[0...described_class::COMMENT_SIZE_LIMIT])
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -768,20 +768,20 @@ RSpec.describe Account do
|
||||
expect(account).to model_have_error_on_field(:username)
|
||||
end
|
||||
|
||||
it 'is invalid if the username is longer than 30 characters' do
|
||||
account = Fabricate.build(:account, username: Faker::Lorem.characters(number: 31))
|
||||
it 'is invalid if the username is longer than the character limit' do
|
||||
account = Fabricate.build(:account, username: username_over_limit)
|
||||
account.valid?
|
||||
expect(account).to model_have_error_on_field(:username)
|
||||
end
|
||||
|
||||
it 'is invalid if the display name is longer than 30 characters' do
|
||||
account = Fabricate.build(:account, display_name: Faker::Lorem.characters(number: 31))
|
||||
it 'is invalid if the display name is longer than the character limit' do
|
||||
account = Fabricate.build(:account, display_name: username_over_limit)
|
||||
account.valid?
|
||||
expect(account).to model_have_error_on_field(:display_name)
|
||||
end
|
||||
|
||||
it 'is invalid if the note is longer than 500 characters' do
|
||||
account = Fabricate.build(:account, note: Faker::Lorem.characters(number: 501))
|
||||
it 'is invalid if the note is longer than the character limit' do
|
||||
account = Fabricate.build(:account, note: account_note_over_limit)
|
||||
account.valid?
|
||||
expect(account).to model_have_error_on_field(:note)
|
||||
end
|
||||
@ -814,24 +814,32 @@ RSpec.describe Account do
|
||||
expect(account).to model_have_error_on_field(:username)
|
||||
end
|
||||
|
||||
it 'is valid even if the username is longer than 30 characters' do
|
||||
account = Fabricate.build(:account, domain: 'domain', username: Faker::Lorem.characters(number: 31))
|
||||
it 'is valid even if the username is longer than the character limit' do
|
||||
account = Fabricate.build(:account, domain: 'domain', username: username_over_limit)
|
||||
account.valid?
|
||||
expect(account).to_not model_have_error_on_field(:username)
|
||||
end
|
||||
|
||||
it 'is valid even if the display name is longer than 30 characters' do
|
||||
account = Fabricate.build(:account, domain: 'domain', display_name: Faker::Lorem.characters(number: 31))
|
||||
it 'is valid even if the display name is longer than the character limit' do
|
||||
account = Fabricate.build(:account, domain: 'domain', display_name: username_over_limit)
|
||||
account.valid?
|
||||
expect(account).to_not model_have_error_on_field(:display_name)
|
||||
end
|
||||
|
||||
it 'is valid even if the note is longer than 500 characters' do
|
||||
account = Fabricate.build(:account, domain: 'domain', note: Faker::Lorem.characters(number: 501))
|
||||
it 'is valid even if the note is longer than the character limit' do
|
||||
account = Fabricate.build(:account, domain: 'domain', note: account_note_over_limit)
|
||||
account.valid?
|
||||
expect(account).to_not model_have_error_on_field(:note)
|
||||
end
|
||||
end
|
||||
|
||||
def username_over_limit
|
||||
'a' * described_class::USERNAME_LENGTH_LIMIT * 2
|
||||
end
|
||||
|
||||
def account_note_over_limit
|
||||
'a' * described_class::NOTE_LENGTH_LIMIT * 2
|
||||
end
|
||||
end
|
||||
|
||||
describe 'scopes' do
|
||||
|
@ -3,6 +3,19 @@
|
||||
require 'rails_helper'
|
||||
|
||||
describe Appeal do
|
||||
describe 'Validations' do
|
||||
it 'validates text length is under limit' do
|
||||
appeal = Fabricate.build(
|
||||
:appeal,
|
||||
strike: Fabricate(:account_warning),
|
||||
text: 'a' * described_class::TEXT_LENGTH_LIMIT * 2
|
||||
)
|
||||
|
||||
expect(appeal).to_not be_valid
|
||||
expect(appeal).to model_have_error_on_field(:text)
|
||||
end
|
||||
end
|
||||
|
||||
describe 'scopes' do
|
||||
describe 'approved' do
|
||||
let(:approved_appeal) { Fabricate(:appeal, approved_at: 10.days.ago) }
|
||||
|
@ -123,14 +123,14 @@ describe Report do
|
||||
describe 'validations' do
|
||||
let(:remote_account) { Fabricate(:account, domain: 'example.com', protocol: :activitypub, inbox_url: 'http://example.com/inbox') }
|
||||
|
||||
it 'is invalid if comment is longer than 1000 characters only if reporter is local' do
|
||||
report = Fabricate.build(:report, comment: Faker::Lorem.characters(number: 1001))
|
||||
it 'is invalid if comment is longer than character limit and reporter is local' do
|
||||
report = Fabricate.build(:report, comment: comment_over_limit)
|
||||
expect(report.valid?).to be false
|
||||
expect(report).to model_have_error_on_field(:comment)
|
||||
end
|
||||
|
||||
it 'is valid if comment is longer than 1000 characters and reporter is not local' do
|
||||
report = Fabricate.build(:report, account: remote_account, comment: Faker::Lorem.characters(number: 1001))
|
||||
it 'is valid if comment is longer than character limit and reporter is not local' do
|
||||
report = Fabricate.build(:report, account: remote_account, comment: comment_over_limit)
|
||||
expect(report.valid?).to be true
|
||||
end
|
||||
|
||||
@ -146,5 +146,9 @@ describe Report do
|
||||
expect(report.valid?).to be false
|
||||
expect(report).to model_have_error_on_field(:rule_ids)
|
||||
end
|
||||
|
||||
def comment_over_limit
|
||||
'a' * described_class::COMMENT_SIZE_LIMIT * 2
|
||||
end
|
||||
end
|
||||
end
|
||||
|
50
spec/models/scheduled_status_spec.rb
Normal file
50
spec/models/scheduled_status_spec.rb
Normal file
@ -0,0 +1,50 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
require 'rails_helper'
|
||||
|
||||
RSpec.describe ScheduledStatus do
|
||||
let(:account) { Fabricate(:account) }
|
||||
|
||||
describe 'validations' do
|
||||
context 'when scheduled_at is less than minimum offset' do
|
||||
subject { Fabricate.build(:scheduled_status, scheduled_at: 4.minutes.from_now, account: account) }
|
||||
|
||||
it 'is not valid', :aggregate_failures do
|
||||
expect(subject).to_not be_valid
|
||||
expect(subject.errors[:scheduled_at]).to include(I18n.t('scheduled_statuses.too_soon'))
|
||||
end
|
||||
end
|
||||
|
||||
context 'when account has reached total limit' do
|
||||
subject { Fabricate.build(:scheduled_status, account: account) }
|
||||
|
||||
before do
|
||||
allow(account.scheduled_statuses).to receive(:count).and_return(described_class::TOTAL_LIMIT)
|
||||
end
|
||||
|
||||
it 'is not valid', :aggregate_failures do
|
||||
expect(subject).to_not be_valid
|
||||
expect(subject.errors[:base]).to include(I18n.t('scheduled_statuses.over_total_limit', limit: ScheduledStatus::TOTAL_LIMIT))
|
||||
end
|
||||
end
|
||||
|
||||
context 'when account has reached daily limit' do
|
||||
subject { Fabricate.build(:scheduled_status, account: account, scheduled_at: base_time + 10.minutes) }
|
||||
|
||||
let(:base_time) { Time.current.change(hour: 12) }
|
||||
|
||||
before do
|
||||
stub_const('ScheduledStatus::DAILY_LIMIT', 3)
|
||||
|
||||
travel_to base_time do
|
||||
Fabricate.times(ScheduledStatus::DAILY_LIMIT, :scheduled_status, account: account, scheduled_at: base_time + 1.hour)
|
||||
end
|
||||
end
|
||||
|
||||
it 'is not valid', :aggregate_failures do
|
||||
expect(subject).to_not be_valid
|
||||
expect(subject.errors[:base]).to include(I18n.t('scheduled_statuses.over_daily_limit', limit: ScheduledStatus::DAILY_LIMIT))
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
@ -193,6 +193,32 @@ describe '/api/v1/statuses' do
|
||||
expect(response).to have_http_status(404)
|
||||
end
|
||||
end
|
||||
|
||||
context 'when scheduling a status' do
|
||||
let(:params) { { status: 'Hello world', scheduled_at: 10.minutes.from_now } }
|
||||
let(:account) { user.account }
|
||||
|
||||
it 'returns HTTP 200' do
|
||||
subject
|
||||
|
||||
expect(response).to have_http_status(200)
|
||||
end
|
||||
|
||||
it 'creates a scheduled status' do
|
||||
expect { subject }.to change { account.scheduled_statuses.count }.from(0).to(1)
|
||||
end
|
||||
|
||||
context 'when the scheduling time is less than 5 minutes' do
|
||||
let(:params) { { status: 'Hello world', scheduled_at: 4.minutes.from_now } }
|
||||
|
||||
it 'does not create a scheduled status', :aggregate_failures do
|
||||
subject
|
||||
|
||||
expect(response).to have_http_status(422)
|
||||
expect(account.scheduled_statuses).to be_empty
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe 'DELETE /api/v1/statuses/:id' do
|
||||
|
@ -61,6 +61,16 @@ RSpec.describe PostStatusService do
|
||||
status2 = subject.call(account, text: 'test', idempotency: 'meepmeep', scheduled_at: future)
|
||||
expect(status2.id).to eq status1.id
|
||||
end
|
||||
|
||||
context 'when scheduled_at is less than min offset' do
|
||||
let(:invalid_scheduled_time) { 4.minutes.from_now }
|
||||
|
||||
it 'raises invalid record error' do
|
||||
expect do
|
||||
subject.call(account, text: 'Hi future!', scheduled_at: invalid_scheduled_time)
|
||||
end.to raise_error(ActiveRecord::RecordInvalid)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
it 'creates response to the original status of boost' do
|
||||
|
@ -46,7 +46,7 @@ describe 'Filters' do
|
||||
click_on I18n.t('filters.index.delete')
|
||||
end.to change(CustomFilter, :count).by(-1)
|
||||
|
||||
expect(page).to_not have_content(filter_title)
|
||||
expect(page).to have_no_content(filter_title)
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -8,6 +8,7 @@ ARG TARGETPLATFORM=${TARGETPLATFORM}
|
||||
ARG BUILDPLATFORM=${BUILDPLATFORM}
|
||||
|
||||
# Node version to use in base image, change with [--build-arg NODE_MAJOR_VERSION="20"]
|
||||
# renovate: datasource=node-version depName=node
|
||||
ARG NODE_MAJOR_VERSION="20"
|
||||
# Debian image to use for base image, change with [--build-arg DEBIAN_VERSION="bookworm"]
|
||||
ARG DEBIAN_VERSION="bookworm"
|
||||
|
@ -27,7 +27,7 @@
|
||||
"pino": "^9.0.0",
|
||||
"pino-http": "^10.0.0",
|
||||
"prom-client": "^15.0.0",
|
||||
"uuid": "^9.0.0",
|
||||
"uuid": "^10.0.0",
|
||||
"ws": "^8.12.1"
|
||||
},
|
||||
"devDependencies": {
|
||||
|
38
yarn.lock
38
yarn.lock
@ -2945,7 +2945,7 @@ __metadata:
|
||||
prom-client: "npm:^15.0.0"
|
||||
typescript: "npm:^5.0.4"
|
||||
utf-8-validate: "npm:^6.0.3"
|
||||
uuid: "npm:^9.0.0"
|
||||
uuid: "npm:^10.0.0"
|
||||
ws: "npm:^8.12.1"
|
||||
dependenciesMeta:
|
||||
bufferutil:
|
||||
@ -3715,9 +3715,9 @@ __metadata:
|
||||
linkType: hard
|
||||
|
||||
"@types/lodash@npm:^4.14.195":
|
||||
version: 4.17.4
|
||||
resolution: "@types/lodash@npm:4.17.4"
|
||||
checksum: 10c0/0124c64cb9fe7a0f78b6777955abd05ef0d97844d49118652eae45f8fa57bfb7f5a7a9bccc0b5a84c0a6dc09631042e4590cb665acb9d58dfd5e6543c75341ec
|
||||
version: 4.17.5
|
||||
resolution: "@types/lodash@npm:4.17.5"
|
||||
checksum: 10c0/55924803ed853e72261512bd3eaf2c5b16558c3817feb0a3125ef757afe46e54b86f33d1960e40b7606c0ddab91a96f47966bf5e6006b7abfd8994c13b04b19b
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
@ -13086,8 +13086,8 @@ __metadata:
|
||||
linkType: hard
|
||||
|
||||
"pino-pretty@npm:^11.0.0":
|
||||
version: 11.1.0
|
||||
resolution: "pino-pretty@npm:11.1.0"
|
||||
version: 11.2.0
|
||||
resolution: "pino-pretty@npm:11.2.0"
|
||||
dependencies:
|
||||
colorette: "npm:^2.0.7"
|
||||
dateformat: "npm:^4.6.3"
|
||||
@ -13105,7 +13105,7 @@ __metadata:
|
||||
strip-json-comments: "npm:^3.1.1"
|
||||
bin:
|
||||
pino-pretty: bin.js
|
||||
checksum: 10c0/418be6f854b0d62c83c65e75b0969d5311792bfadeefbfe77d8a7f8c5ba26b8bea40f549222b5f500439f440eb4d6c2fa99d712bdd02881ebae7be3a0193b581
|
||||
checksum: 10c0/59421522c0e07877614ed8b51eb45fe79aad9865244b95dfaf5e28c83f9e95631941b5b9e37a277d1751ed90903d7593915e8a8857cc856b4af7e6bf20a5f97d
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
@ -14046,11 +14046,11 @@ __metadata:
|
||||
linkType: hard
|
||||
|
||||
"prettier@npm:^3.0.0":
|
||||
version: 3.3.0
|
||||
resolution: "prettier@npm:3.3.0"
|
||||
version: 3.3.1
|
||||
resolution: "prettier@npm:3.3.1"
|
||||
bin:
|
||||
prettier: bin/prettier.cjs
|
||||
checksum: 10c0/d033c356320aa2e468bf29c931b094ac730d2f4defd5eb2989d8589313dec901d2fc866e3788f3d161e420b142ea4ec3dda535dbe0169ef4d0026397a68ba9cf
|
||||
checksum: 10c0/c25a709c9f0be670dc6bcb190b622347e1dbeb6c3e7df8b0711724cb64d8647c60b839937a4df4df18e9cfb556c2b08ca9d24d9645eb5488a7fc032a2c4d5cb3
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
@ -17513,6 +17513,15 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"uuid@npm:^10.0.0":
|
||||
version: 10.0.0
|
||||
resolution: "uuid@npm:10.0.0"
|
||||
bin:
|
||||
uuid: dist/bin/uuid
|
||||
checksum: 10c0/eab18c27fe4ab9fb9709a5d5f40119b45f2ec8314f8d4cf12ce27e4c6f4ffa4a6321dc7db6c515068fa373c075b49691ba969f0010bf37f44c37ca40cd6bf7fe
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"uuid@npm:^3.3.2":
|
||||
version: 3.4.0
|
||||
resolution: "uuid@npm:3.4.0"
|
||||
@ -17531,15 +17540,6 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"uuid@npm:^9.0.0":
|
||||
version: 9.0.1
|
||||
resolution: "uuid@npm:9.0.1"
|
||||
bin:
|
||||
uuid: dist/bin/uuid
|
||||
checksum: 10c0/1607dd32ac7fc22f2d8f77051e6a64845c9bce5cd3dd8aa0070c074ec73e666a1f63c7b4e0f4bf2bc8b9d59dc85a15e17807446d9d2b17c8485fbc2147b27f9b
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"v8-compile-cache@npm:^2.1.1":
|
||||
version: 2.3.0
|
||||
resolution: "v8-compile-cache@npm:2.3.0"
|
||||
|
Loading…
Reference in New Issue
Block a user