Merge pull request #2701 from ClearlyClaire/glitch-soc/merge-upstream
Merge upstream changes up to b7902225d6
This commit is contained in:
commit
e9cca1cc09
353 changed files with 4050 additions and 2011 deletions
|
@ -70,7 +70,7 @@ services:
|
||||||
hard: -1
|
hard: -1
|
||||||
|
|
||||||
libretranslate:
|
libretranslate:
|
||||||
image: libretranslate/libretranslate:v1.5.6
|
image: libretranslate/libretranslate:v1.5.7
|
||||||
restart: unless-stopped
|
restart: unless-stopped
|
||||||
volumes:
|
volumes:
|
||||||
- lt-data:/home/libretranslate/.local
|
- lt-data:/home/libretranslate/.local
|
||||||
|
|
21
.github/stylelint-matcher.json
vendored
21
.github/stylelint-matcher.json
vendored
|
@ -1,21 +0,0 @@
|
||||||
{
|
|
||||||
"problemMatcher": [
|
|
||||||
{
|
|
||||||
"owner": "stylelint",
|
|
||||||
"pattern": [
|
|
||||||
{
|
|
||||||
"regexp": "^([^\\s].*)$",
|
|
||||||
"file": 1
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"regexp": "^\\s+((\\d+):(\\d+))?\\s+(✖|×)\\s+(.*)\\s{2,}(.*)$",
|
|
||||||
"line": 2,
|
|
||||||
"column": 3,
|
|
||||||
"message": 5,
|
|
||||||
"code": 6,
|
|
||||||
"loop": true
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
2
.github/workflows/crowdin-download.yml
vendored
2
.github/workflows/crowdin-download.yml
vendored
|
@ -53,7 +53,7 @@ jobs:
|
||||||
|
|
||||||
# Create or update the pull request
|
# Create or update the pull request
|
||||||
- name: Create Pull Request
|
- name: Create Pull Request
|
||||||
uses: peter-evans/create-pull-request@v6.0.4
|
uses: peter-evans/create-pull-request@v6.0.5
|
||||||
with:
|
with:
|
||||||
commit-message: 'New Crowdin translations'
|
commit-message: 'New Crowdin translations'
|
||||||
title: 'New Crowdin Translations (automated)'
|
title: 'New Crowdin Translations (automated)'
|
||||||
|
|
6
.github/workflows/lint-css.yml
vendored
6
.github/workflows/lint-css.yml
vendored
|
@ -38,9 +38,5 @@ jobs:
|
||||||
- name: Set up Javascript environment
|
- name: Set up Javascript environment
|
||||||
uses: ./.github/actions/setup-javascript
|
uses: ./.github/actions/setup-javascript
|
||||||
|
|
||||||
- uses: xt0rted/stylelint-problem-matcher@v1
|
|
||||||
|
|
||||||
- run: echo "::add-matcher::.github/stylelint-matcher.json"
|
|
||||||
|
|
||||||
- name: Stylelint
|
- name: Stylelint
|
||||||
run: yarn lint:css
|
run: yarn lint:css -f github
|
||||||
|
|
6
.github/workflows/test-ruby.yml
vendored
6
.github/workflows/test-ruby.yml
vendored
|
@ -115,8 +115,8 @@ jobs:
|
||||||
matrix:
|
matrix:
|
||||||
ruby-version:
|
ruby-version:
|
||||||
- '3.1'
|
- '3.1'
|
||||||
|
- '3.2'
|
||||||
- '.ruby-version'
|
- '.ruby-version'
|
||||||
- '3.3'
|
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v4
|
- uses: actions/checkout@v4
|
||||||
|
|
||||||
|
@ -190,8 +190,8 @@ jobs:
|
||||||
matrix:
|
matrix:
|
||||||
ruby-version:
|
ruby-version:
|
||||||
- '3.1'
|
- '3.1'
|
||||||
|
- '3.2'
|
||||||
- '.ruby-version'
|
- '.ruby-version'
|
||||||
- '3.3'
|
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v4
|
- uses: actions/checkout@v4
|
||||||
|
@ -289,8 +289,8 @@ jobs:
|
||||||
matrix:
|
matrix:
|
||||||
ruby-version:
|
ruby-version:
|
||||||
- '3.1'
|
- '3.1'
|
||||||
|
- '3.2'
|
||||||
- '.ruby-version'
|
- '.ruby-version'
|
||||||
- '3.3'
|
|
||||||
search-image:
|
search-image:
|
||||||
- docker.elastic.co/elasticsearch/elasticsearch:7.17.13
|
- docker.elastic.co/elasticsearch/elasticsearch:7.17.13
|
||||||
include:
|
include:
|
||||||
|
|
3
.gitignore
vendored
3
.gitignore
vendored
|
@ -68,3 +68,6 @@ yarn-debug.log
|
||||||
|
|
||||||
# Ignore Docker option files
|
# Ignore Docker option files
|
||||||
docker-compose.override.yml
|
docker-compose.override.yml
|
||||||
|
|
||||||
|
# Ignore dotenv .local files
|
||||||
|
.env*.local
|
||||||
|
|
|
@ -182,6 +182,11 @@ Style/FormatStringToken:
|
||||||
AllowedMethods:
|
AllowedMethods:
|
||||||
- redirect_with_vary
|
- redirect_with_vary
|
||||||
|
|
||||||
|
# Reason: Prevailing style choice
|
||||||
|
# https://docs.rubocop.org/rubocop/cops_style.html#stylehashaslastarrayitem
|
||||||
|
Style/HashAsLastArrayItem:
|
||||||
|
Enabled: false
|
||||||
|
|
||||||
# Reason: Enforce modern Ruby style
|
# Reason: Enforce modern Ruby style
|
||||||
# https://docs.rubocop.org/rubocop/cops_style.html#stylehashsyntax
|
# https://docs.rubocop.org/rubocop/cops_style.html#stylehashsyntax
|
||||||
Style/HashSyntax:
|
Style/HashSyntax:
|
||||||
|
|
|
@ -42,14 +42,6 @@ RSpec/MultipleMemoizedHelpers:
|
||||||
RSpec/NestedGroups:
|
RSpec/NestedGroups:
|
||||||
Max: 6
|
Max: 6
|
||||||
|
|
||||||
# Configuration parameters: Include.
|
|
||||||
# Include: app/models/**/*.rb
|
|
||||||
Rails/HasAndBelongsToMany:
|
|
||||||
Exclude:
|
|
||||||
- 'app/models/concerns/account/associations.rb'
|
|
||||||
- 'app/models/status.rb'
|
|
||||||
- 'app/models/tag.rb'
|
|
||||||
|
|
||||||
Rails/OutputSafety:
|
Rails/OutputSafety:
|
||||||
Exclude:
|
Exclude:
|
||||||
- 'config/initializers/simple_form.rb'
|
- 'config/initializers/simple_form.rb'
|
||||||
|
@ -128,19 +120,6 @@ Style/GuardClause:
|
||||||
- 'lib/mastodon/cli/media.rb'
|
- 'lib/mastodon/cli/media.rb'
|
||||||
- 'lib/tasks/repo.rake'
|
- 'lib/tasks/repo.rake'
|
||||||
|
|
||||||
# This cop supports safe autocorrection (--autocorrect).
|
|
||||||
# Configuration parameters: EnforcedStyle.
|
|
||||||
# SupportedStyles: braces, no_braces
|
|
||||||
Style/HashAsLastArrayItem:
|
|
||||||
Exclude:
|
|
||||||
- 'app/controllers/admin/statuses_controller.rb'
|
|
||||||
- 'app/controllers/api/v1/statuses_controller.rb'
|
|
||||||
- 'app/models/concerns/account/counters.rb'
|
|
||||||
- 'app/models/concerns/status/threading_concern.rb'
|
|
||||||
- 'app/models/status.rb'
|
|
||||||
- 'app/services/batched_remove_status_service.rb'
|
|
||||||
- 'app/services/notify_service.rb'
|
|
||||||
|
|
||||||
# This cop supports unsafe autocorrection (--autocorrect-all).
|
# This cop supports unsafe autocorrection (--autocorrect-all).
|
||||||
Style/HashTransformValues:
|
Style/HashTransformValues:
|
||||||
Exclude:
|
Exclude:
|
||||||
|
@ -218,14 +197,6 @@ Style/SafeNavigation:
|
||||||
Exclude:
|
Exclude:
|
||||||
- 'app/models/concerns/account/finder_concern.rb'
|
- 'app/models/concerns/account/finder_concern.rb'
|
||||||
|
|
||||||
# This cop supports safe autocorrection (--autocorrect).
|
|
||||||
# Configuration parameters: EnforcedStyle.
|
|
||||||
# SupportedStyles: only_raise, only_fail, semantic
|
|
||||||
Style/SignalException:
|
|
||||||
Exclude:
|
|
||||||
- 'lib/devise/strategies/two_factor_ldap_authenticatable.rb'
|
|
||||||
- 'lib/devise/strategies/two_factor_pam_authenticatable.rb'
|
|
||||||
|
|
||||||
# This cop supports unsafe autocorrection (--autocorrect-all).
|
# This cop supports unsafe autocorrection (--autocorrect-all).
|
||||||
# Configuration parameters: Mode.
|
# Configuration parameters: Mode.
|
||||||
Style/StringConcatenation:
|
Style/StringConcatenation:
|
||||||
|
|
|
@ -1 +1 @@
|
||||||
3.2.3
|
3.3.1
|
||||||
|
|
10
Dockerfile
10
Dockerfile
|
@ -7,15 +7,15 @@
|
||||||
ARG TARGETPLATFORM=${TARGETPLATFORM}
|
ARG TARGETPLATFORM=${TARGETPLATFORM}
|
||||||
ARG BUILDPLATFORM=${BUILDPLATFORM}
|
ARG BUILDPLATFORM=${BUILDPLATFORM}
|
||||||
|
|
||||||
# Ruby image to use for base image, change with [--build-arg RUBY_VERSION="3.2.3"]
|
# Ruby image to use for base image, change with [--build-arg RUBY_VERSION="3.3.1"]
|
||||||
ARG RUBY_VERSION="3.2.3"
|
ARG RUBY_VERSION="3.3.1"
|
||||||
# # Node version to use in base image, change with [--build-arg NODE_MAJOR_VERSION="20"]
|
# # Node version to use in base image, change with [--build-arg NODE_MAJOR_VERSION="20"]
|
||||||
ARG NODE_MAJOR_VERSION="20"
|
ARG NODE_MAJOR_VERSION="20"
|
||||||
# Debian image to use for base image, change with [--build-arg DEBIAN_VERSION="bookworm"]
|
# Debian image to use for base image, change with [--build-arg DEBIAN_VERSION="bookworm"]
|
||||||
ARG DEBIAN_VERSION="bookworm"
|
ARG DEBIAN_VERSION="bookworm"
|
||||||
# Node image to use for base image based on combined variables (ex: 20-bookworm-slim)
|
# Node image to use for base image based on combined variables (ex: 20-bookworm-slim)
|
||||||
FROM docker.io/node:${NODE_MAJOR_VERSION}-${DEBIAN_VERSION}-slim as node
|
FROM docker.io/node:${NODE_MAJOR_VERSION}-${DEBIAN_VERSION}-slim as node
|
||||||
# Ruby image to use for base image based on combined variables (ex: 3.2.3-slim-bookworm)
|
# Ruby image to use for base image based on combined variables (ex: 3.3.1-slim-bookworm)
|
||||||
FROM docker.io/ruby:${RUBY_VERSION}-slim-${DEBIAN_VERSION} as ruby
|
FROM docker.io/ruby:${RUBY_VERSION}-slim-${DEBIAN_VERSION} as ruby
|
||||||
|
|
||||||
# Resulting version string is vX.X.X-MASTODON_VERSION_PRERELEASE+MASTODON_VERSION_METADATA
|
# Resulting version string is vX.X.X-MASTODON_VERSION_PRERELEASE+MASTODON_VERSION_METADATA
|
||||||
|
@ -29,7 +29,7 @@ ARG MASTODON_VERSION_METADATA=""
|
||||||
# See: https://docs.joinmastodon.org/admin/config/#rails_serve_static_files
|
# See: https://docs.joinmastodon.org/admin/config/#rails_serve_static_files
|
||||||
ARG RAILS_SERVE_STATIC_FILES="true"
|
ARG RAILS_SERVE_STATIC_FILES="true"
|
||||||
# Allow to use YJIT compiler
|
# Allow to use YJIT compiler
|
||||||
# See: https://github.com/ruby/ruby/blob/v3_2_3/doc/yjit/yjit.md
|
# See: https://github.com/ruby/ruby/blob/v3_2_4/doc/yjit/yjit.md
|
||||||
ARG RUBY_YJIT_ENABLE="1"
|
ARG RUBY_YJIT_ENABLE="1"
|
||||||
# Timezone used by the Docker container and runtime, change with [--build-arg TZ=Europe/Berlin]
|
# Timezone used by the Docker container and runtime, change with [--build-arg TZ=Europe/Berlin]
|
||||||
ARG TZ="Etc/UTC"
|
ARG TZ="Etc/UTC"
|
||||||
|
@ -262,4 +262,4 @@ USER mastodon
|
||||||
# Expose default Puma ports
|
# Expose default Puma ports
|
||||||
EXPOSE 3000
|
EXPOSE 3000
|
||||||
# Set container tini as default entry point
|
# Set container tini as default entry point
|
||||||
ENTRYPOINT ["/usr/bin/tini", "--"]
|
ENTRYPOINT ["/usr/bin/tini", "--"]
|
||||||
|
|
2
Gemfile
2
Gemfile
|
@ -31,7 +31,7 @@ gem 'browser'
|
||||||
gem 'charlock_holmes', '~> 0.7.7'
|
gem 'charlock_holmes', '~> 0.7.7'
|
||||||
gem 'chewy', '~> 7.3'
|
gem 'chewy', '~> 7.3'
|
||||||
gem 'devise', '~> 4.9'
|
gem 'devise', '~> 4.9'
|
||||||
gem 'devise-two-factor', '~> 4.1'
|
gem 'devise-two-factor'
|
||||||
|
|
||||||
group :pam_authentication, optional: true do
|
group :pam_authentication, optional: true do
|
||||||
gem 'devise_pam_authenticatable2', '~> 9.2'
|
gem 'devise_pam_authenticatable2', '~> 9.2'
|
||||||
|
|
44
Gemfile.lock
44
Gemfile.lock
|
@ -97,22 +97,20 @@ GEM
|
||||||
activerecord (>= 3.2, < 8.0)
|
activerecord (>= 3.2, < 8.0)
|
||||||
rake (>= 10.4, < 14.0)
|
rake (>= 10.4, < 14.0)
|
||||||
ast (2.4.2)
|
ast (2.4.2)
|
||||||
attr_encrypted (4.0.0)
|
|
||||||
encryptor (~> 3.0.0)
|
|
||||||
attr_required (1.0.2)
|
attr_required (1.0.2)
|
||||||
awrence (1.2.1)
|
awrence (1.2.1)
|
||||||
aws-eventstream (1.3.0)
|
aws-eventstream (1.3.0)
|
||||||
aws-partitions (1.916.0)
|
aws-partitions (1.922.0)
|
||||||
aws-sdk-core (3.192.1)
|
aws-sdk-core (3.194.0)
|
||||||
aws-eventstream (~> 1, >= 1.3.0)
|
aws-eventstream (~> 1, >= 1.3.0)
|
||||||
aws-partitions (~> 1, >= 1.651.0)
|
aws-partitions (~> 1, >= 1.651.0)
|
||||||
aws-sigv4 (~> 1.8)
|
aws-sigv4 (~> 1.8)
|
||||||
jmespath (~> 1, >= 1.6.1)
|
jmespath (~> 1, >= 1.6.1)
|
||||||
aws-sdk-kms (1.79.0)
|
aws-sdk-kms (1.80.0)
|
||||||
aws-sdk-core (~> 3, >= 3.191.0)
|
aws-sdk-core (~> 3, >= 3.193.0)
|
||||||
aws-sigv4 (~> 1.1)
|
aws-sigv4 (~> 1.1)
|
||||||
aws-sdk-s3 (1.147.0)
|
aws-sdk-s3 (1.149.0)
|
||||||
aws-sdk-core (~> 3, >= 3.192.0)
|
aws-sdk-core (~> 3, >= 3.194.0)
|
||||||
aws-sdk-kms (~> 1)
|
aws-sdk-kms (~> 1)
|
||||||
aws-sigv4 (~> 1.8)
|
aws-sigv4 (~> 1.8)
|
||||||
aws-sigv4 (1.8.0)
|
aws-sigv4 (1.8.0)
|
||||||
|
@ -204,9 +202,8 @@ GEM
|
||||||
railties (>= 4.1.0)
|
railties (>= 4.1.0)
|
||||||
responders
|
responders
|
||||||
warden (~> 1.2.3)
|
warden (~> 1.2.3)
|
||||||
devise-two-factor (4.1.1)
|
devise-two-factor (5.0.0)
|
||||||
activesupport (~> 7.0)
|
activesupport (~> 7.0)
|
||||||
attr_encrypted (>= 1.3, < 5, != 2)
|
|
||||||
devise (~> 4.0)
|
devise (~> 4.0)
|
||||||
railties (~> 7.0)
|
railties (~> 7.0)
|
||||||
rotp (~> 6.0)
|
rotp (~> 6.0)
|
||||||
|
@ -220,7 +217,7 @@ GEM
|
||||||
domain_name (0.6.20240107)
|
domain_name (0.6.20240107)
|
||||||
doorkeeper (5.6.9)
|
doorkeeper (5.6.9)
|
||||||
railties (>= 5)
|
railties (>= 5)
|
||||||
dotenv (3.1.0)
|
dotenv (3.1.1)
|
||||||
drb (2.2.1)
|
drb (2.2.1)
|
||||||
ed25519 (1.3.0)
|
ed25519 (1.3.0)
|
||||||
elasticsearch (7.13.3)
|
elasticsearch (7.13.3)
|
||||||
|
@ -236,7 +233,6 @@ GEM
|
||||||
htmlentities (~> 4.3.3)
|
htmlentities (~> 4.3.3)
|
||||||
launchy (~> 2.1)
|
launchy (~> 2.1)
|
||||||
mail (~> 2.7)
|
mail (~> 2.7)
|
||||||
encryptor (3.0.0)
|
|
||||||
erubi (1.12.0)
|
erubi (1.12.0)
|
||||||
et-orbi (1.2.11)
|
et-orbi (1.2.11)
|
||||||
tzinfo
|
tzinfo
|
||||||
|
@ -304,7 +300,7 @@ GEM
|
||||||
activesupport (>= 5.1)
|
activesupport (>= 5.1)
|
||||||
haml (>= 4.0.6)
|
haml (>= 4.0.6)
|
||||||
railties (>= 5.1)
|
railties (>= 5.1)
|
||||||
haml_lint (0.57.0)
|
haml_lint (0.58.0)
|
||||||
haml (>= 5.0)
|
haml (>= 5.0)
|
||||||
parallel (~> 1.10)
|
parallel (~> 1.10)
|
||||||
rainbow
|
rainbow
|
||||||
|
@ -350,8 +346,8 @@ GEM
|
||||||
activesupport (>= 3.0)
|
activesupport (>= 3.0)
|
||||||
nokogiri (>= 1.6)
|
nokogiri (>= 1.6)
|
||||||
io-console (0.7.2)
|
io-console (0.7.2)
|
||||||
irb (1.12.0)
|
irb (1.13.0)
|
||||||
rdoc
|
rdoc (>= 4.0.0)
|
||||||
reline (>= 0.4.2)
|
reline (>= 0.4.2)
|
||||||
jmespath (1.6.2)
|
jmespath (1.6.2)
|
||||||
json (2.7.2)
|
json (2.7.2)
|
||||||
|
@ -498,7 +494,7 @@ GEM
|
||||||
orm_adapter (0.5.0)
|
orm_adapter (0.5.0)
|
||||||
ox (2.14.18)
|
ox (2.14.18)
|
||||||
parallel (1.24.0)
|
parallel (1.24.0)
|
||||||
parser (3.3.0.5)
|
parser (3.3.1.0)
|
||||||
ast (~> 2.4.1)
|
ast (~> 2.4.1)
|
||||||
racc
|
racc
|
||||||
parslet (2.0.0)
|
parslet (2.0.0)
|
||||||
|
@ -605,7 +601,7 @@ GEM
|
||||||
redlock (1.3.2)
|
redlock (1.3.2)
|
||||||
redis (>= 3.0.0, < 6.0)
|
redis (>= 3.0.0, < 6.0)
|
||||||
regexp_parser (2.9.0)
|
regexp_parser (2.9.0)
|
||||||
reline (0.5.2)
|
reline (0.5.4)
|
||||||
io-console (~> 0.5)
|
io-console (~> 0.5)
|
||||||
request_store (1.6.0)
|
request_store (1.6.0)
|
||||||
rack (>= 1.4)
|
rack (>= 1.4)
|
||||||
|
@ -644,7 +640,7 @@ GEM
|
||||||
rspec-mocks (~> 3.0)
|
rspec-mocks (~> 3.0)
|
||||||
sidekiq (>= 5, < 8)
|
sidekiq (>= 5, < 8)
|
||||||
rspec-support (3.13.1)
|
rspec-support (3.13.1)
|
||||||
rubocop (1.63.3)
|
rubocop (1.63.4)
|
||||||
json (~> 2.3)
|
json (~> 2.3)
|
||||||
language_server-protocol (>= 3.17.0)
|
language_server-protocol (>= 3.17.0)
|
||||||
parallel (~> 1.10)
|
parallel (~> 1.10)
|
||||||
|
@ -655,8 +651,8 @@ GEM
|
||||||
rubocop-ast (>= 1.31.1, < 2.0)
|
rubocop-ast (>= 1.31.1, < 2.0)
|
||||||
ruby-progressbar (~> 1.7)
|
ruby-progressbar (~> 1.7)
|
||||||
unicode-display_width (>= 2.4.0, < 3.0)
|
unicode-display_width (>= 2.4.0, < 3.0)
|
||||||
rubocop-ast (1.31.2)
|
rubocop-ast (1.31.3)
|
||||||
parser (>= 3.3.0.4)
|
parser (>= 3.3.1.0)
|
||||||
rubocop-capybara (2.20.0)
|
rubocop-capybara (2.20.0)
|
||||||
rubocop (~> 1.41)
|
rubocop (~> 1.41)
|
||||||
rubocop-factory_bot (2.25.1)
|
rubocop-factory_bot (2.25.1)
|
||||||
|
@ -669,7 +665,7 @@ GEM
|
||||||
rack (>= 1.1)
|
rack (>= 1.1)
|
||||||
rubocop (>= 1.33.0, < 2.0)
|
rubocop (>= 1.33.0, < 2.0)
|
||||||
rubocop-ast (>= 1.31.1, < 2.0)
|
rubocop-ast (>= 1.31.1, < 2.0)
|
||||||
rubocop-rspec (2.29.1)
|
rubocop-rspec (2.29.2)
|
||||||
rubocop (~> 1.40)
|
rubocop (~> 1.40)
|
||||||
rubocop-capybara (~> 2.17)
|
rubocop-capybara (~> 2.17)
|
||||||
rubocop-factory_bot (~> 2.22)
|
rubocop-factory_bot (~> 2.22)
|
||||||
|
@ -693,7 +689,7 @@ GEM
|
||||||
scenic (1.8.0)
|
scenic (1.8.0)
|
||||||
activerecord (>= 4.0.0)
|
activerecord (>= 4.0.0)
|
||||||
railties (>= 4.0.0)
|
railties (>= 4.0.0)
|
||||||
selenium-webdriver (4.19.0)
|
selenium-webdriver (4.20.1)
|
||||||
base64 (~> 0.2)
|
base64 (~> 0.2)
|
||||||
rexml (~> 3.2, >= 3.2.5)
|
rexml (~> 3.2, >= 3.2.5)
|
||||||
rubyzip (>= 1.2.2, < 3.0)
|
rubyzip (>= 1.2.2, < 3.0)
|
||||||
|
@ -842,7 +838,7 @@ DEPENDENCIES
|
||||||
database_cleaner-active_record
|
database_cleaner-active_record
|
||||||
debug (~> 1.8)
|
debug (~> 1.8)
|
||||||
devise (~> 4.9)
|
devise (~> 4.9)
|
||||||
devise-two-factor (~> 4.1)
|
devise-two-factor
|
||||||
devise_pam_authenticatable2 (~> 9.2)
|
devise_pam_authenticatable2 (~> 9.2)
|
||||||
discard (~> 1.2)
|
discard (~> 1.2)
|
||||||
doorkeeper (~> 5.6)
|
doorkeeper (~> 5.6)
|
||||||
|
@ -952,7 +948,7 @@ DEPENDENCIES
|
||||||
xorcist (~> 1.1)
|
xorcist (~> 1.1)
|
||||||
|
|
||||||
RUBY VERSION
|
RUBY VERSION
|
||||||
ruby 3.2.3p157
|
ruby 3.3.1p55
|
||||||
|
|
||||||
BUNDLED WITH
|
BUNDLED WITH
|
||||||
2.5.9
|
2.5.9
|
||||||
|
|
|
@ -25,6 +25,8 @@ class Admin::DomainAllowsController < Admin::BaseController
|
||||||
def destroy
|
def destroy
|
||||||
authorize @domain_allow, :destroy?
|
authorize @domain_allow, :destroy?
|
||||||
UnallowDomainService.new.call(@domain_allow)
|
UnallowDomainService.new.call(@domain_allow)
|
||||||
|
log_action :destroy, @domain_allow
|
||||||
|
|
||||||
redirect_to admin_instances_path, notice: I18n.t('admin.domain_allows.destroyed_msg')
|
redirect_to admin_instances_path, notice: I18n.t('admin.domain_allows.destroyed_msg')
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -29,10 +29,11 @@ class Api::V1::Admin::DomainBlocksController < Api::BaseController
|
||||||
def create
|
def create
|
||||||
authorize :domain_block, :create?
|
authorize :domain_block, :create?
|
||||||
|
|
||||||
|
@domain_block = DomainBlock.new(resource_params)
|
||||||
existing_domain_block = resource_params[:domain].present? ? DomainBlock.rule_for(resource_params[:domain]) : nil
|
existing_domain_block = resource_params[:domain].present? ? DomainBlock.rule_for(resource_params[:domain]) : nil
|
||||||
return render json: existing_domain_block, serializer: REST::Admin::ExistingDomainBlockErrorSerializer, status: 422 if existing_domain_block.present?
|
return render json: existing_domain_block, serializer: REST::Admin::ExistingDomainBlockErrorSerializer, status: 422 if conflicts_with_existing_block?(@domain_block, existing_domain_block)
|
||||||
|
|
||||||
@domain_block = DomainBlock.create!(resource_params)
|
@domain_block.save!
|
||||||
DomainBlockWorker.perform_async(@domain_block.id)
|
DomainBlockWorker.perform_async(@domain_block.id)
|
||||||
log_action :create, @domain_block
|
log_action :create, @domain_block
|
||||||
render json: @domain_block, serializer: REST::Admin::DomainBlockSerializer
|
render json: @domain_block, serializer: REST::Admin::DomainBlockSerializer
|
||||||
|
@ -55,6 +56,10 @@ class Api::V1::Admin::DomainBlocksController < Api::BaseController
|
||||||
|
|
||||||
private
|
private
|
||||||
|
|
||||||
|
def conflicts_with_existing_block?(domain_block, existing_domain_block)
|
||||||
|
existing_domain_block.present? && (existing_domain_block.domain == TagManager.instance.normalize_domain(domain_block.domain) || !domain_block.stricter_than?(existing_domain_block))
|
||||||
|
end
|
||||||
|
|
||||||
def set_domain_blocks
|
def set_domain_blocks
|
||||||
@domain_blocks = filtered_domain_blocks.order(id: :desc).to_a_paginated_by_id(limit_param(LIMIT), params_slice(:max_id, :since_id, :min_id))
|
@domain_blocks = filtered_domain_blocks.order(id: :desc).to_a_paginated_by_id(limit_param(LIMIT), params_slice(:max_id, :since_id, :min_id))
|
||||||
end
|
end
|
||||||
|
|
|
@ -113,6 +113,14 @@ module ApplicationHelper
|
||||||
content_tag(:i, nil, attributes.merge(class: class_names.join(' ')))
|
content_tag(:i, nil, attributes.merge(class: class_names.join(' ')))
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def material_symbol(icon, attributes = {})
|
||||||
|
inline_svg_tag(
|
||||||
|
"400-24px/#{icon}.svg",
|
||||||
|
class: %w(icon).concat(attributes[:class].to_s.split),
|
||||||
|
role: :img
|
||||||
|
)
|
||||||
|
end
|
||||||
|
|
||||||
def check_icon
|
def check_icon
|
||||||
inline_svg_tag 'check.svg'
|
inline_svg_tag 'check.svg'
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
import './public-path';
|
import './public-path';
|
||||||
import main from "mastodon/main";
|
import main from 'mastodon/main';
|
||||||
|
|
||||||
import { start } from '../mastodon/common';
|
import { start } from '../mastodon/common';
|
||||||
import { loadLocale } from '../mastodon/locales';
|
import { loadLocale } from '../mastodon/locales';
|
||||||
|
@ -10,6 +10,6 @@ start();
|
||||||
loadPolyfills()
|
loadPolyfills()
|
||||||
.then(loadLocale)
|
.then(loadLocale)
|
||||||
.then(main)
|
.then(main)
|
||||||
.catch(e => {
|
.catch((e: unknown) => {
|
||||||
console.error(e);
|
console.error(e);
|
||||||
});
|
});
|
|
@ -2,7 +2,9 @@ import './public-path';
|
||||||
import ready from '../mastodon/ready';
|
import ready from '../mastodon/ready';
|
||||||
|
|
||||||
ready(() => {
|
ready(() => {
|
||||||
const image = document.querySelector('img');
|
const image = document.querySelector<HTMLImageElement>('img');
|
||||||
|
|
||||||
|
if (!image) return;
|
||||||
|
|
||||||
image.addEventListener('mouseenter', () => {
|
image.addEventListener('mouseenter', () => {
|
||||||
image.src = '/oops.gif';
|
image.src = '/oops.gif';
|
||||||
|
@ -11,4 +13,6 @@ ready(() => {
|
||||||
image.addEventListener('mouseleave', () => {
|
image.addEventListener('mouseleave', () => {
|
||||||
image.src = '/oops.png';
|
image.src = '/oops.png';
|
||||||
});
|
});
|
||||||
|
}).catch((e: unknown) => {
|
||||||
|
console.error(e);
|
||||||
});
|
});
|
|
@ -2,7 +2,7 @@
|
||||||
// to share the same assets regardless of instance configuration.
|
// to share the same assets regardless of instance configuration.
|
||||||
// See https://webpack.js.org/guides/public-path/#on-the-fly
|
// See https://webpack.js.org/guides/public-path/#on-the-fly
|
||||||
|
|
||||||
function removeOuterSlashes(string) {
|
function removeOuterSlashes(string: string) {
|
||||||
return string.replace(/^\/*/, '').replace(/\/*$/, '');
|
return string.replace(/^\/*/, '').replace(/\/*$/, '');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -15,7 +15,9 @@ function formatPublicPath(host = '', path = '') {
|
||||||
return `${formattedHost}/${formattedPath}/`;
|
return `${formattedHost}/${formattedPath}/`;
|
||||||
}
|
}
|
||||||
|
|
||||||
const cdnHost = document.querySelector('meta[name=cdn-host]');
|
const cdnHost = document.querySelector<HTMLMetaElement>('meta[name=cdn-host]');
|
||||||
|
|
||||||
// eslint-disable-next-line no-undef
|
__webpack_public_path__ = formatPublicPath(
|
||||||
__webpack_public_path__ = formatPublicPath(cdnHost ? cdnHost.content : '', process.env.PUBLIC_OUTPUT_PATH);
|
cdnHost ? cdnHost.content : '',
|
||||||
|
process.env.PUBLIC_OUTPUT_PATH,
|
||||||
|
);
|
|
@ -2,7 +2,7 @@ import './public-path';
|
||||||
import { createRoot } from 'react-dom/client';
|
import { createRoot } from 'react-dom/client';
|
||||||
|
|
||||||
import { start } from '../mastodon/common';
|
import { start } from '../mastodon/common';
|
||||||
import ComposeContainer from '../mastodon/containers/compose_container';
|
import ComposeContainer from '../mastodon/containers/compose_container';
|
||||||
import { loadPolyfills } from '../mastodon/polyfills';
|
import { loadPolyfills } from '../mastodon/polyfills';
|
||||||
import ready from '../mastodon/ready';
|
import ready from '../mastodon/ready';
|
||||||
|
|
||||||
|
@ -16,7 +16,7 @@ function loaded() {
|
||||||
|
|
||||||
if (!attr) return;
|
if (!attr) return;
|
||||||
|
|
||||||
const props = JSON.parse(attr);
|
const props = JSON.parse(attr) as object;
|
||||||
const root = createRoot(mountNode);
|
const root = createRoot(mountNode);
|
||||||
|
|
||||||
root.render(<ComposeContainer {...props} />);
|
root.render(<ComposeContainer {...props} />);
|
||||||
|
@ -24,9 +24,13 @@ function loaded() {
|
||||||
}
|
}
|
||||||
|
|
||||||
function main() {
|
function main() {
|
||||||
ready(loaded);
|
ready(loaded).catch((error: unknown) => {
|
||||||
|
console.error(error);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
loadPolyfills().then(main).catch(error => {
|
loadPolyfills()
|
||||||
console.error(error);
|
.then(main)
|
||||||
});
|
.catch((error: unknown) => {
|
||||||
|
console.error(error);
|
||||||
|
});
|
48
app/javascript/entrypoints/sign_up.ts
Normal file
48
app/javascript/entrypoints/sign_up.ts
Normal file
|
@ -0,0 +1,48 @@
|
||||||
|
import './public-path';
|
||||||
|
import axios from 'axios';
|
||||||
|
|
||||||
|
import ready from '../mastodon/ready';
|
||||||
|
|
||||||
|
async function checkConfirmation() {
|
||||||
|
const response = await axios.get('/api/v1/emails/check_confirmation');
|
||||||
|
|
||||||
|
if (response.data) {
|
||||||
|
window.location.href = '/start';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ready(() => {
|
||||||
|
setInterval(() => {
|
||||||
|
void checkConfirmation();
|
||||||
|
}, 5000);
|
||||||
|
|
||||||
|
document
|
||||||
|
.querySelectorAll<HTMLButtonElement>('button.timer-button')
|
||||||
|
.forEach((button) => {
|
||||||
|
let counter = 30;
|
||||||
|
|
||||||
|
const container = document.createElement('span');
|
||||||
|
|
||||||
|
const updateCounter = () => {
|
||||||
|
container.innerText = ` (${counter})`;
|
||||||
|
};
|
||||||
|
|
||||||
|
updateCounter();
|
||||||
|
|
||||||
|
const countdown = setInterval(() => {
|
||||||
|
counter--;
|
||||||
|
|
||||||
|
if (counter === 0) {
|
||||||
|
button.disabled = false;
|
||||||
|
button.removeChild(container);
|
||||||
|
clearInterval(countdown);
|
||||||
|
} else {
|
||||||
|
updateCounter();
|
||||||
|
}
|
||||||
|
}, 1000);
|
||||||
|
|
||||||
|
button.appendChild(container);
|
||||||
|
});
|
||||||
|
}).catch((e: unknown) => {
|
||||||
|
throw e;
|
||||||
|
});
|
197
app/javascript/entrypoints/two_factor_authentication.ts
Normal file
197
app/javascript/entrypoints/two_factor_authentication.ts
Normal file
|
@ -0,0 +1,197 @@
|
||||||
|
import * as WebAuthnJSON from '@github/webauthn-json';
|
||||||
|
import axios, { AxiosError } from 'axios';
|
||||||
|
|
||||||
|
import ready from '../mastodon/ready';
|
||||||
|
|
||||||
|
import 'regenerator-runtime/runtime';
|
||||||
|
|
||||||
|
type PublicKeyCredentialCreationOptionsJSON =
|
||||||
|
WebAuthnJSON.CredentialCreationOptionsJSON['publicKey'];
|
||||||
|
|
||||||
|
function exceptionHasAxiosError(
|
||||||
|
error: unknown,
|
||||||
|
): error is AxiosError<{ error: unknown }> {
|
||||||
|
return (
|
||||||
|
error instanceof AxiosError &&
|
||||||
|
typeof error.response?.data === 'object' &&
|
||||||
|
'error' in error.response.data
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
function logAxiosResponseError(error: unknown) {
|
||||||
|
if (exceptionHasAxiosError(error)) console.error(error);
|
||||||
|
}
|
||||||
|
|
||||||
|
function getCSRFToken() {
|
||||||
|
return document
|
||||||
|
.querySelector<HTMLMetaElement>('meta[name="csrf-token"]')
|
||||||
|
?.getAttribute('content');
|
||||||
|
}
|
||||||
|
|
||||||
|
function hideFlashMessages() {
|
||||||
|
document.querySelectorAll('.flash-message').forEach((flashMessage) => {
|
||||||
|
flashMessage.classList.add('hidden');
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
async function callback(
|
||||||
|
url: string,
|
||||||
|
body:
|
||||||
|
| {
|
||||||
|
credential: WebAuthnJSON.PublicKeyCredentialWithAttestationJSON;
|
||||||
|
nickname: string;
|
||||||
|
}
|
||||||
|
| {
|
||||||
|
user: { credential: WebAuthnJSON.PublicKeyCredentialWithAssertionJSON };
|
||||||
|
},
|
||||||
|
) {
|
||||||
|
try {
|
||||||
|
const response = await axios.post<{ redirect_path: string }>(
|
||||||
|
url,
|
||||||
|
JSON.stringify(body),
|
||||||
|
{
|
||||||
|
headers: {
|
||||||
|
'Content-Type': 'application/json',
|
||||||
|
Accept: 'application/json',
|
||||||
|
'X-CSRF-Token': getCSRFToken(),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
|
window.location.replace(response.data.redirect_path);
|
||||||
|
} catch (error) {
|
||||||
|
if (error instanceof AxiosError && error.response?.status === 422) {
|
||||||
|
const errorMessage = document.getElementById(
|
||||||
|
'security-key-error-message',
|
||||||
|
);
|
||||||
|
errorMessage?.classList.remove('hidden');
|
||||||
|
|
||||||
|
logAxiosResponseError(error);
|
||||||
|
} else {
|
||||||
|
console.error(error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async function handleWebauthnCredentialRegistration(nickname: string) {
|
||||||
|
try {
|
||||||
|
const response = await axios.get<PublicKeyCredentialCreationOptionsJSON>(
|
||||||
|
'/settings/security_keys/options',
|
||||||
|
);
|
||||||
|
|
||||||
|
const credentialOptions = response.data;
|
||||||
|
|
||||||
|
try {
|
||||||
|
const credential = await WebAuthnJSON.create({
|
||||||
|
publicKey: credentialOptions,
|
||||||
|
});
|
||||||
|
|
||||||
|
const params = {
|
||||||
|
credential: credential,
|
||||||
|
nickname: nickname,
|
||||||
|
};
|
||||||
|
|
||||||
|
await callback('/settings/security_keys', params);
|
||||||
|
} catch (error) {
|
||||||
|
const errorMessage = document.getElementById(
|
||||||
|
'security-key-error-message',
|
||||||
|
);
|
||||||
|
errorMessage?.classList.remove('hidden');
|
||||||
|
console.error(error);
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
logAxiosResponseError(error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async function handleWebauthnCredentialAuthentication() {
|
||||||
|
try {
|
||||||
|
const response = await axios.get<PublicKeyCredentialCreationOptionsJSON>(
|
||||||
|
'sessions/security_key_options',
|
||||||
|
);
|
||||||
|
|
||||||
|
const credentialOptions = response.data;
|
||||||
|
|
||||||
|
try {
|
||||||
|
const credential = await WebAuthnJSON.get({
|
||||||
|
publicKey: credentialOptions,
|
||||||
|
});
|
||||||
|
|
||||||
|
const params = { user: { credential: credential } };
|
||||||
|
void callback('sign_in', params);
|
||||||
|
} catch (error) {
|
||||||
|
const errorMessage = document.getElementById(
|
||||||
|
'security-key-error-message',
|
||||||
|
);
|
||||||
|
errorMessage?.classList.remove('hidden');
|
||||||
|
console.error(error);
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
logAxiosResponseError(error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ready(() => {
|
||||||
|
if (!WebAuthnJSON.supported()) {
|
||||||
|
const unsupported_browser_message = document.getElementById(
|
||||||
|
'unsupported-browser-message',
|
||||||
|
);
|
||||||
|
if (unsupported_browser_message) {
|
||||||
|
unsupported_browser_message.classList.remove('hidden');
|
||||||
|
const button = document.querySelector<HTMLButtonElement>(
|
||||||
|
'button.btn.js-webauthn',
|
||||||
|
);
|
||||||
|
if (button) button.disabled = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const webAuthnCredentialRegistrationForm =
|
||||||
|
document.querySelector<HTMLFormElement>('form#new_webauthn_credential');
|
||||||
|
if (webAuthnCredentialRegistrationForm) {
|
||||||
|
webAuthnCredentialRegistrationForm.addEventListener('submit', (event) => {
|
||||||
|
event.preventDefault();
|
||||||
|
|
||||||
|
if (!(event.target instanceof HTMLFormElement)) return;
|
||||||
|
|
||||||
|
const nickname = event.target.querySelector<HTMLInputElement>(
|
||||||
|
'input[name="new_webauthn_credential[nickname]"]',
|
||||||
|
);
|
||||||
|
|
||||||
|
if (nickname?.value) {
|
||||||
|
void handleWebauthnCredentialRegistration(nickname.value);
|
||||||
|
} else {
|
||||||
|
nickname?.focus();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
const webAuthnCredentialAuthenticationForm =
|
||||||
|
document.getElementById('webauthn-form');
|
||||||
|
if (webAuthnCredentialAuthenticationForm) {
|
||||||
|
webAuthnCredentialAuthenticationForm.addEventListener('submit', (event) => {
|
||||||
|
event.preventDefault();
|
||||||
|
void handleWebauthnCredentialAuthentication();
|
||||||
|
});
|
||||||
|
|
||||||
|
const otpAuthenticationForm = document.getElementById(
|
||||||
|
'otp-authentication-form',
|
||||||
|
);
|
||||||
|
|
||||||
|
const linkToOtp = document.getElementById('link-to-otp');
|
||||||
|
|
||||||
|
linkToOtp?.addEventListener('click', () => {
|
||||||
|
webAuthnCredentialAuthenticationForm.classList.add('hidden');
|
||||||
|
otpAuthenticationForm?.classList.remove('hidden');
|
||||||
|
hideFlashMessages();
|
||||||
|
});
|
||||||
|
|
||||||
|
const linkToWebAuthn = document.getElementById('link-to-webauthn');
|
||||||
|
linkToWebAuthn?.addEventListener('click', () => {
|
||||||
|
otpAuthenticationForm?.classList.add('hidden');
|
||||||
|
webAuthnCredentialAuthenticationForm.classList.remove('hidden');
|
||||||
|
hideFlashMessages();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}).catch((e: unknown) => {
|
||||||
|
throw e;
|
||||||
|
});
|
|
@ -1,9 +1,7 @@
|
||||||
import { List as ImmutableList } from 'immutable';
|
|
||||||
|
|
||||||
import { debounce } from 'lodash';
|
import { debounce } from 'lodash';
|
||||||
|
|
||||||
import type { MarkerJSON } from 'flavours/glitch/api_types/markers';
|
import type { MarkerJSON } from 'flavours/glitch/api_types/markers';
|
||||||
import type { RootState } from 'flavours/glitch/store';
|
import type { AppDispatch, RootState } from 'flavours/glitch/store';
|
||||||
import { createAppAsyncThunk } from 'flavours/glitch/store/typed_functions';
|
import { createAppAsyncThunk } from 'flavours/glitch/store/typed_functions';
|
||||||
|
|
||||||
import api, { authorizationTokenFromState } from '../api';
|
import api, { authorizationTokenFromState } from '../api';
|
||||||
|
@ -71,34 +69,17 @@ interface MarkerParam {
|
||||||
last_read_id?: string;
|
last_read_id?: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
function getLastHomeId(state: RootState): string | undefined {
|
|
||||||
/* eslint-disable @typescript-eslint/no-unsafe-return, @typescript-eslint/no-unsafe-call, @typescript-eslint/no-unsafe-member-access */
|
|
||||||
return (
|
|
||||||
state
|
|
||||||
// @ts-expect-error state.timelines is not yet typed
|
|
||||||
.getIn(['timelines', 'home', 'items'], ImmutableList())
|
|
||||||
// @ts-expect-error state.timelines is not yet typed
|
|
||||||
.find((item) => item !== null)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
function getLastNotificationId(state: RootState): string | undefined {
|
function getLastNotificationId(state: RootState): string | undefined {
|
||||||
// @ts-expect-error state.notifications is not yet typed
|
// @ts-expect-error state.notifications is not yet typed
|
||||||
|
// eslint-disable-next-line @typescript-eslint/no-unsafe-return, @typescript-eslint/no-unsafe-call
|
||||||
return state.getIn(['notifications', 'lastReadId']);
|
return state.getIn(['notifications', 'lastReadId']);
|
||||||
}
|
}
|
||||||
|
|
||||||
const buildPostMarkersParams = (state: RootState) => {
|
const buildPostMarkersParams = (state: RootState) => {
|
||||||
const params = {} as { home?: MarkerParam; notifications?: MarkerParam };
|
const params = {} as { home?: MarkerParam; notifications?: MarkerParam };
|
||||||
|
|
||||||
const lastHomeId = getLastHomeId(state);
|
|
||||||
const lastNotificationId = getLastNotificationId(state);
|
const lastNotificationId = getLastNotificationId(state);
|
||||||
|
|
||||||
if (lastHomeId && compareId(lastHomeId, state.markers.home) > 0) {
|
|
||||||
params.home = {
|
|
||||||
last_read_id: lastHomeId,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
if (
|
if (
|
||||||
lastNotificationId &&
|
lastNotificationId &&
|
||||||
lastNotificationId !== '0' &&
|
lastNotificationId !== '0' &&
|
||||||
|
@ -132,8 +113,8 @@ export const submitMarkersAction = createAppAsyncThunk<{
|
||||||
});
|
});
|
||||||
|
|
||||||
const debouncedSubmitMarkers = debounce(
|
const debouncedSubmitMarkers = debounce(
|
||||||
(dispatch) => {
|
(dispatch: AppDispatch) => {
|
||||||
dispatch(submitMarkersAction());
|
void dispatch(submitMarkersAction());
|
||||||
},
|
},
|
||||||
300000,
|
300000,
|
||||||
{
|
{
|
||||||
|
|
|
@ -1,16 +1,18 @@
|
||||||
import PropTypes from 'prop-types';
|
import PropTypes from 'prop-types';
|
||||||
|
import { useCallback } from 'react';
|
||||||
|
|
||||||
import { defineMessages, injectIntl, FormattedMessage } from 'react-intl';
|
import { defineMessages, useIntl, FormattedMessage } from 'react-intl';
|
||||||
|
|
||||||
import classNames from 'classnames';
|
import classNames from 'classnames';
|
||||||
|
|
||||||
import ImmutablePropTypes from 'react-immutable-proptypes';
|
import ImmutablePropTypes from 'react-immutable-proptypes';
|
||||||
import ImmutablePureComponent from 'react-immutable-pure-component';
|
|
||||||
|
|
||||||
|
import MoreHorizIcon from '@/material-icons/400-24px/more_horiz.svg?react';
|
||||||
import { EmptyAccount } from 'flavours/glitch/components/empty_account';
|
import { EmptyAccount } from 'flavours/glitch/components/empty_account';
|
||||||
import { ShortNumber } from 'flavours/glitch/components/short_number';
|
import { ShortNumber } from 'flavours/glitch/components/short_number';
|
||||||
import { VerifiedBadge } from 'flavours/glitch/components/verified_badge';
|
import { VerifiedBadge } from 'flavours/glitch/components/verified_badge';
|
||||||
|
|
||||||
|
import DropdownMenuContainer from '../containers/dropdown_menu_container';
|
||||||
import { me } from '../initial_state';
|
import { me } from '../initial_state';
|
||||||
|
|
||||||
import { Avatar } from './avatar';
|
import { Avatar } from './avatar';
|
||||||
|
@ -30,153 +32,153 @@ const messages = defineMessages({
|
||||||
unmute_notifications: { id: 'account.unmute_notifications_short', defaultMessage: 'Unmute notifications' },
|
unmute_notifications: { id: 'account.unmute_notifications_short', defaultMessage: 'Unmute notifications' },
|
||||||
mute: { id: 'account.mute_short', defaultMessage: 'Mute' },
|
mute: { id: 'account.mute_short', defaultMessage: 'Mute' },
|
||||||
block: { id: 'account.block_short', defaultMessage: 'Block' },
|
block: { id: 'account.block_short', defaultMessage: 'Block' },
|
||||||
|
more: { id: 'status.more', defaultMessage: 'More' },
|
||||||
});
|
});
|
||||||
|
|
||||||
class Account extends ImmutablePureComponent {
|
const Account = ({ size = 46, account, onFollow, onBlock, onMute, onMuteNotifications, hidden, minimal, defaultAction, withBio }) => {
|
||||||
|
const intl = useIntl();
|
||||||
|
|
||||||
static propTypes = {
|
const handleFollow = useCallback(() => {
|
||||||
size: PropTypes.number,
|
onFollow(account);
|
||||||
account: ImmutablePropTypes.record,
|
}, [onFollow, account]);
|
||||||
onFollow: PropTypes.func,
|
|
||||||
onBlock: PropTypes.func,
|
|
||||||
onMute: PropTypes.func,
|
|
||||||
onMuteNotifications: PropTypes.func,
|
|
||||||
intl: PropTypes.object.isRequired,
|
|
||||||
hidden: PropTypes.bool,
|
|
||||||
minimal: PropTypes.bool,
|
|
||||||
defaultAction: PropTypes.string,
|
|
||||||
withBio: PropTypes.bool,
|
|
||||||
};
|
|
||||||
|
|
||||||
static defaultProps = {
|
const handleBlock = useCallback(() => {
|
||||||
size: 46,
|
onBlock(account);
|
||||||
};
|
}, [onBlock, account]);
|
||||||
|
|
||||||
handleFollow = () => {
|
const handleMute = useCallback(() => {
|
||||||
this.props.onFollow(this.props.account);
|
onMute(account);
|
||||||
};
|
}, [onMute, account]);
|
||||||
|
|
||||||
handleBlock = () => {
|
const handleMuteNotifications = useCallback(() => {
|
||||||
this.props.onBlock(this.props.account);
|
onMuteNotifications(account, true);
|
||||||
};
|
}, [onMuteNotifications, account]);
|
||||||
|
|
||||||
handleMute = () => {
|
const handleUnmuteNotifications = useCallback(() => {
|
||||||
this.props.onMute(this.props.account);
|
onMuteNotifications(account, false);
|
||||||
};
|
}, [onMuteNotifications, account]);
|
||||||
|
|
||||||
handleMuteNotifications = () => {
|
if (!account) {
|
||||||
this.props.onMuteNotifications(this.props.account, true);
|
return <EmptyAccount size={size} minimal={minimal} />;
|
||||||
};
|
}
|
||||||
|
|
||||||
handleUnmuteNotifications = () => {
|
|
||||||
this.props.onMuteNotifications(this.props.account, false);
|
|
||||||
};
|
|
||||||
|
|
||||||
render () {
|
|
||||||
const { account, intl, hidden, withBio, defaultAction, size, minimal } = this.props;
|
|
||||||
|
|
||||||
if (!account) {
|
|
||||||
return <EmptyAccount size={size} minimal={minimal} />;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (hidden) {
|
|
||||||
return (
|
|
||||||
<>
|
|
||||||
{account.get('display_name')}
|
|
||||||
{account.get('username')}
|
|
||||||
</>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
let buttons;
|
|
||||||
|
|
||||||
if (account.get('id') !== me && account.get('relationship', null) !== null) {
|
|
||||||
const following = account.getIn(['relationship', 'following']);
|
|
||||||
const requested = account.getIn(['relationship', 'requested']);
|
|
||||||
const blocking = account.getIn(['relationship', 'blocking']);
|
|
||||||
const muting = account.getIn(['relationship', 'muting']);
|
|
||||||
|
|
||||||
if (requested) {
|
|
||||||
buttons = <Button text={intl.formatMessage(messages.cancel_follow_request)} onClick={this.handleFollow} />;
|
|
||||||
} else if (blocking) {
|
|
||||||
buttons = <Button text={intl.formatMessage(messages.unblock)} onClick={this.handleBlock} />;
|
|
||||||
} else if (muting) {
|
|
||||||
let hidingNotificationsButton;
|
|
||||||
|
|
||||||
if (account.getIn(['relationship', 'muting_notifications'])) {
|
|
||||||
hidingNotificationsButton = <Button text={intl.formatMessage(messages.unmute_notifications)} onClick={this.handleUnmuteNotifications} />;
|
|
||||||
} else {
|
|
||||||
hidingNotificationsButton = <Button text={intl.formatMessage(messages.mute_notifications)} onClick={this.handleMuteNotifications} />;
|
|
||||||
}
|
|
||||||
|
|
||||||
buttons = (
|
|
||||||
<>
|
|
||||||
<Button text={intl.formatMessage(messages.unmute)} onClick={this.handleMute} />
|
|
||||||
{hidingNotificationsButton}
|
|
||||||
</>
|
|
||||||
);
|
|
||||||
} else if (defaultAction === 'mute') {
|
|
||||||
buttons = <Button title={intl.formatMessage(messages.mute)} onClick={this.handleMute} />;
|
|
||||||
} else if (defaultAction === 'block') {
|
|
||||||
buttons = <Button text={intl.formatMessage(messages.block)} onClick={this.handleBlock} />;
|
|
||||||
} else if (!account.get('suspended') && !account.get('moved') || following) {
|
|
||||||
buttons = <Button text={intl.formatMessage(following ? messages.unfollow : messages.follow)} onClick={this.handleFollow} />;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
let muteTimeRemaining;
|
|
||||||
|
|
||||||
if (account.get('mute_expires_at')) {
|
|
||||||
muteTimeRemaining = <>· <RelativeTimestamp timestamp={account.get('mute_expires_at')} futureDate /></>;
|
|
||||||
}
|
|
||||||
|
|
||||||
let verification;
|
|
||||||
|
|
||||||
const firstVerifiedField = account.get('fields').find(item => !!item.get('verified_at'));
|
|
||||||
|
|
||||||
if (firstVerifiedField) {
|
|
||||||
verification = <VerifiedBadge link={firstVerifiedField.get('value')} />;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
if (hidden) {
|
||||||
return (
|
return (
|
||||||
<div className={classNames('account', { 'account--minimal': minimal })}>
|
<>
|
||||||
<div className='account__wrapper'>
|
{account.get('display_name')}
|
||||||
<Permalink key={account.get('id')} className='account__display-name' title={account.get('acct')} href={account.get('url')} to={`/@${account.get('acct')}`}>
|
{account.get('username')}
|
||||||
<div className='account__avatar-wrapper'>
|
</>
|
||||||
<Avatar account={account} size={size} />
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div className='account__contents'>
|
|
||||||
<DisplayName account={account} />
|
|
||||||
{!minimal && (
|
|
||||||
<div className='account__details'>
|
|
||||||
{account.get('followers_count') !== -1 && (
|
|
||||||
<ShortNumber value={account.get('followers_count')} renderer={FollowersCounter} />
|
|
||||||
)} {verification} {muteTimeRemaining}
|
|
||||||
</div>
|
|
||||||
)}
|
|
||||||
</div>
|
|
||||||
</Permalink>
|
|
||||||
|
|
||||||
{!minimal && (
|
|
||||||
<div className='account__relationship'>
|
|
||||||
{buttons}
|
|
||||||
</div>
|
|
||||||
)}
|
|
||||||
</div>
|
|
||||||
|
|
||||||
{withBio && (account.get('note').length > 0 ? (
|
|
||||||
<div
|
|
||||||
className='account__note translate'
|
|
||||||
dangerouslySetInnerHTML={{ __html: account.get('note_emojified') }}
|
|
||||||
/>
|
|
||||||
) : (
|
|
||||||
<div className='account__note account__note--missing'><FormattedMessage id='account.no_bio' defaultMessage='No description provided.' /></div>
|
|
||||||
))}
|
|
||||||
</div>
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
let buttons;
|
||||||
|
|
||||||
export default injectIntl(Account);
|
if (account.get('id') !== me && account.get('relationship', null) !== null) {
|
||||||
|
const following = account.getIn(['relationship', 'following']);
|
||||||
|
const requested = account.getIn(['relationship', 'requested']);
|
||||||
|
const blocking = account.getIn(['relationship', 'blocking']);
|
||||||
|
const muting = account.getIn(['relationship', 'muting']);
|
||||||
|
|
||||||
|
if (requested) {
|
||||||
|
buttons = <Button text={intl.formatMessage(messages.cancel_follow_request)} onClick={handleFollow} />;
|
||||||
|
} else if (blocking) {
|
||||||
|
buttons = <Button text={intl.formatMessage(messages.unblock)} onClick={handleBlock} />;
|
||||||
|
} else if (muting) {
|
||||||
|
let menu;
|
||||||
|
|
||||||
|
if (account.getIn(['relationship', 'muting_notifications'])) {
|
||||||
|
menu = [{ text: intl.formatMessage(messages.unmute_notifications), action: handleUnmuteNotifications }];
|
||||||
|
} else {
|
||||||
|
menu = [{ text: intl.formatMessage(messages.mute_notifications), action: handleMuteNotifications }];
|
||||||
|
}
|
||||||
|
|
||||||
|
buttons = (
|
||||||
|
<>
|
||||||
|
<DropdownMenuContainer
|
||||||
|
items={menu}
|
||||||
|
icon='ellipsis-h'
|
||||||
|
iconComponent={MoreHorizIcon}
|
||||||
|
direction='right'
|
||||||
|
title={intl.formatMessage(messages.more)}
|
||||||
|
/>
|
||||||
|
|
||||||
|
<Button text={intl.formatMessage(messages.unmute)} onClick={handleMute} />
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
} else if (defaultAction === 'mute') {
|
||||||
|
buttons = <Button title={intl.formatMessage(messages.mute)} onClick={handleMute} />;
|
||||||
|
} else if (defaultAction === 'block') {
|
||||||
|
buttons = <Button text={intl.formatMessage(messages.block)} onClick={handleBlock} />;
|
||||||
|
} else if (!account.get('suspended') && !account.get('moved') || following) {
|
||||||
|
buttons = <Button text={intl.formatMessage(following ? messages.unfollow : messages.follow)} onClick={handleFollow} />;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let muteTimeRemaining;
|
||||||
|
|
||||||
|
if (account.get('mute_expires_at')) {
|
||||||
|
muteTimeRemaining = <>· <RelativeTimestamp timestamp={account.get('mute_expires_at')} futureDate /></>;
|
||||||
|
}
|
||||||
|
|
||||||
|
let verification;
|
||||||
|
|
||||||
|
const firstVerifiedField = account.get('fields').find(item => !!item.get('verified_at'));
|
||||||
|
|
||||||
|
if (firstVerifiedField) {
|
||||||
|
verification = <VerifiedBadge link={firstVerifiedField.get('value')} />;
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className={classNames('account', { 'account--minimal': minimal })}>
|
||||||
|
<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')}`}>
|
||||||
|
<div className='account__avatar-wrapper'>
|
||||||
|
<Avatar account={account} size={size} />
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className='account__contents'>
|
||||||
|
<DisplayName account={account} />
|
||||||
|
{!minimal && (
|
||||||
|
<div className='account__details'>
|
||||||
|
{account.get('followers_count') !== -1 && (
|
||||||
|
<ShortNumber value={account.get('followers_count')} renderer={FollowersCounter} />
|
||||||
|
)} {verification} {muteTimeRemaining}
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
</Permalink>
|
||||||
|
|
||||||
|
{!minimal && (
|
||||||
|
<div className='account__relationship'>
|
||||||
|
{buttons}
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{withBio && (account.get('note').length > 0 ? (
|
||||||
|
<div
|
||||||
|
className='account__note translate'
|
||||||
|
dangerouslySetInnerHTML={{ __html: account.get('note_emojified') }}
|
||||||
|
/>
|
||||||
|
) : (
|
||||||
|
<div className='account__note account__note--missing'><FormattedMessage id='account.no_bio' defaultMessage='No description provided.' /></div>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
Account.propTypes = {
|
||||||
|
size: PropTypes.number,
|
||||||
|
account: ImmutablePropTypes.record,
|
||||||
|
onFollow: PropTypes.func,
|
||||||
|
onBlock: PropTypes.func,
|
||||||
|
onMute: PropTypes.func,
|
||||||
|
onMuteNotifications: PropTypes.func,
|
||||||
|
intl: PropTypes.object.isRequired,
|
||||||
|
hidden: PropTypes.bool,
|
||||||
|
minimal: PropTypes.bool,
|
||||||
|
defaultAction: PropTypes.string,
|
||||||
|
withBio: PropTypes.bool,
|
||||||
|
};
|
||||||
|
|
||||||
|
export default Account;
|
||||||
|
|
|
@ -7,7 +7,7 @@ import PersonIcon from '@/material-icons/400-24px/person.svg?react';
|
||||||
import SmartToyIcon from '@/material-icons/400-24px/smart_toy.svg?react';
|
import SmartToyIcon from '@/material-icons/400-24px/smart_toy.svg?react';
|
||||||
|
|
||||||
|
|
||||||
export const Badge = ({ icon, label, domain, roleId }) => (
|
export const Badge = ({ icon = <PersonIcon />, label, domain, roleId }) => (
|
||||||
<div className='account-role' data-account-role-id={roleId}>
|
<div className='account-role' data-account-role-id={roleId}>
|
||||||
{icon}
|
{icon}
|
||||||
{label}
|
{label}
|
||||||
|
@ -22,10 +22,6 @@ Badge.propTypes = {
|
||||||
roleId: PropTypes.string
|
roleId: PropTypes.string
|
||||||
};
|
};
|
||||||
|
|
||||||
Badge.defaultProps = {
|
|
||||||
icon: <PersonIcon />,
|
|
||||||
};
|
|
||||||
|
|
||||||
export const GroupBadge = () => (
|
export const GroupBadge = () => (
|
||||||
<Badge icon={<GroupsIcon />} label={<FormattedMessage id='account.badges.group' defaultMessage='Group' />} />
|
<Badge icon={<GroupsIcon />} label={<FormattedMessage id='account.badges.group' defaultMessage='Group' />} />
|
||||||
);
|
);
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import 'packs/public-path';
|
import '@/entrypoints/public-path';
|
||||||
import { createRoot } from 'react-dom/client';
|
import { createRoot } from 'react-dom/client';
|
||||||
|
|
||||||
import Rails from '@rails/ujs';
|
import Rails from '@rails/ujs';
|
|
@ -1,8 +1,8 @@
|
||||||
import 'packs/public-path';
|
import '@/entrypoints/public-path';
|
||||||
|
|
||||||
import { start } from 'flavours/glitch/common';
|
import { start } from 'flavours/glitch/common';
|
||||||
import { loadLocale } from 'flavours/glitch/locales';
|
import { loadLocale } from 'flavours/glitch/locales';
|
||||||
import main from "flavours/glitch/main";
|
import main from 'flavours/glitch/main';
|
||||||
import { loadPolyfills } from 'flavours/glitch/polyfills';
|
import { loadPolyfills } from 'flavours/glitch/polyfills';
|
||||||
|
|
||||||
start();
|
start();
|
||||||
|
@ -10,6 +10,6 @@ start();
|
||||||
loadPolyfills()
|
loadPolyfills()
|
||||||
.then(loadLocale)
|
.then(loadLocale)
|
||||||
.then(main)
|
.then(main)
|
||||||
.catch(e => {
|
.catch((e: unknown) => {
|
||||||
console.error(e);
|
console.error(e);
|
||||||
});
|
});
|
|
@ -1,7 +1,7 @@
|
||||||
/* This file is a hack to have something more reliable than the upstream `common` tag
|
/* This file is a hack to have something more reliable than the upstream `common` tag
|
||||||
that is implicitly generated as the common chunk through webpack's `splitChunks` config */
|
that is implicitly generated as the common chunk through webpack's `splitChunks` config */
|
||||||
|
|
||||||
import 'packs/public-path';
|
import '@/entrypoints/public-path';
|
||||||
import 'font-awesome/css/font-awesome.css';
|
import 'font-awesome/css/font-awesome.css';
|
||||||
|
|
||||||
// This is a hack to ensures that webpack compiles our images.
|
// This is a hack to ensures that webpack compiles our images.
|
|
@ -1,8 +1,10 @@
|
||||||
import 'packs/public-path';
|
import '@/entrypoints/public-path';
|
||||||
import ready from 'flavours/glitch/ready';
|
import ready from 'flavours/glitch/ready';
|
||||||
|
|
||||||
ready(() => {
|
ready(() => {
|
||||||
const image = document.querySelector('img');
|
const image = document.querySelector<HTMLImageElement>('img');
|
||||||
|
|
||||||
|
if (!image) return;
|
||||||
|
|
||||||
image.addEventListener('mouseenter', () => {
|
image.addEventListener('mouseenter', () => {
|
||||||
image.src = '/oops.gif';
|
image.src = '/oops.gif';
|
||||||
|
@ -11,4 +13,6 @@ ready(() => {
|
||||||
image.addEventListener('mouseleave', () => {
|
image.addEventListener('mouseleave', () => {
|
||||||
image.src = '/oops.png';
|
image.src = '/oops.png';
|
||||||
});
|
});
|
||||||
|
}).catch((e: unknown) => {
|
||||||
|
console.error(e);
|
||||||
});
|
});
|
|
@ -1,6 +1,6 @@
|
||||||
import { createRoot } from 'react-dom/client';
|
import { createRoot } from 'react-dom/client';
|
||||||
|
|
||||||
import 'packs/public-path';
|
import '@/entrypoints/public-path';
|
||||||
|
|
||||||
import { IntlMessageFormat } from 'intl-messageformat';
|
import { IntlMessageFormat } from 'intl-messageformat';
|
||||||
import type { MessageDescriptor, PrimitiveType } from 'react-intl';
|
import type { MessageDescriptor, PrimitiveType } from 'react-intl';
|
|
@ -8,7 +8,7 @@ and performs no other task.
|
||||||
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import 'packs/public-path';
|
import '@/entrypoints/public-path';
|
||||||
|
|
||||||
import axios from 'axios';
|
import axios from 'axios';
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import 'packs/public-path';
|
import '@/entrypoints/public-path';
|
||||||
import { createRoot } from 'react-dom/client';
|
import { createRoot } from 'react-dom/client';
|
||||||
|
|
||||||
import { start } from 'flavours/glitch/common';
|
import { start } from 'flavours/glitch/common';
|
||||||
|
@ -16,7 +16,7 @@ function loaded() {
|
||||||
|
|
||||||
if (!attr) return;
|
if (!attr) return;
|
||||||
|
|
||||||
const props = JSON.parse(attr);
|
const props = JSON.parse(attr) as object;
|
||||||
const root = createRoot(mountNode);
|
const root = createRoot(mountNode);
|
||||||
|
|
||||||
root.render(<ComposeContainer {...props} />);
|
root.render(<ComposeContainer {...props} />);
|
||||||
|
@ -24,9 +24,13 @@ function loaded() {
|
||||||
}
|
}
|
||||||
|
|
||||||
function main() {
|
function main() {
|
||||||
ready(loaded);
|
ready(loaded).catch((error: unknown) => {
|
||||||
|
console.error(error);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
loadPolyfills().then(main).catch(error => {
|
loadPolyfills()
|
||||||
console.error(error);
|
.then(main)
|
||||||
});
|
.catch((error: unknown) => {
|
||||||
|
console.error(error);
|
||||||
|
});
|
48
app/javascript/flavours/glitch/entrypoints/sign_up.ts
Normal file
48
app/javascript/flavours/glitch/entrypoints/sign_up.ts
Normal file
|
@ -0,0 +1,48 @@
|
||||||
|
import '@/entrypoints/public-path';
|
||||||
|
import axios from 'axios';
|
||||||
|
|
||||||
|
import ready from 'flavours/glitch/ready';
|
||||||
|
|
||||||
|
async function checkConfirmation() {
|
||||||
|
const response = await axios.get('/api/v1/emails/check_confirmation');
|
||||||
|
|
||||||
|
if (response.data) {
|
||||||
|
window.location.href = '/start';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ready(() => {
|
||||||
|
setInterval(() => {
|
||||||
|
void checkConfirmation();
|
||||||
|
}, 5000);
|
||||||
|
|
||||||
|
document
|
||||||
|
.querySelectorAll<HTMLButtonElement>('button.timer-button')
|
||||||
|
.forEach((button) => {
|
||||||
|
let counter = 30;
|
||||||
|
|
||||||
|
const container = document.createElement('span');
|
||||||
|
|
||||||
|
const updateCounter = () => {
|
||||||
|
container.innerText = ` (${counter})`;
|
||||||
|
};
|
||||||
|
|
||||||
|
updateCounter();
|
||||||
|
|
||||||
|
const countdown = setInterval(() => {
|
||||||
|
counter--;
|
||||||
|
|
||||||
|
if (counter === 0) {
|
||||||
|
button.disabled = false;
|
||||||
|
button.removeChild(container);
|
||||||
|
clearInterval(countdown);
|
||||||
|
} else {
|
||||||
|
updateCounter();
|
||||||
|
}
|
||||||
|
}, 1000);
|
||||||
|
|
||||||
|
button.appendChild(container);
|
||||||
|
});
|
||||||
|
}).catch((e: unknown) => {
|
||||||
|
throw e;
|
||||||
|
});
|
|
@ -0,0 +1,197 @@
|
||||||
|
import * as WebAuthnJSON from '@github/webauthn-json';
|
||||||
|
import axios, { AxiosError } from 'axios';
|
||||||
|
|
||||||
|
import ready from 'flavours/glitch/ready';
|
||||||
|
|
||||||
|
import 'regenerator-runtime/runtime';
|
||||||
|
|
||||||
|
type PublicKeyCredentialCreationOptionsJSON =
|
||||||
|
WebAuthnJSON.CredentialCreationOptionsJSON['publicKey'];
|
||||||
|
|
||||||
|
function exceptionHasAxiosError(
|
||||||
|
error: unknown,
|
||||||
|
): error is AxiosError<{ error: unknown }> {
|
||||||
|
return (
|
||||||
|
error instanceof AxiosError &&
|
||||||
|
typeof error.response?.data === 'object' &&
|
||||||
|
'error' in error.response.data
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
function logAxiosResponseError(error: unknown) {
|
||||||
|
if (exceptionHasAxiosError(error)) console.error(error);
|
||||||
|
}
|
||||||
|
|
||||||
|
function getCSRFToken() {
|
||||||
|
return document
|
||||||
|
.querySelector<HTMLMetaElement>('meta[name="csrf-token"]')
|
||||||
|
?.getAttribute('content');
|
||||||
|
}
|
||||||
|
|
||||||
|
function hideFlashMessages() {
|
||||||
|
document.querySelectorAll('.flash-message').forEach((flashMessage) => {
|
||||||
|
flashMessage.classList.add('hidden');
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
async function callback(
|
||||||
|
url: string,
|
||||||
|
body:
|
||||||
|
| {
|
||||||
|
credential: WebAuthnJSON.PublicKeyCredentialWithAttestationJSON;
|
||||||
|
nickname: string;
|
||||||
|
}
|
||||||
|
| {
|
||||||
|
user: { credential: WebAuthnJSON.PublicKeyCredentialWithAssertionJSON };
|
||||||
|
},
|
||||||
|
) {
|
||||||
|
try {
|
||||||
|
const response = await axios.post<{ redirect_path: string }>(
|
||||||
|
url,
|
||||||
|
JSON.stringify(body),
|
||||||
|
{
|
||||||
|
headers: {
|
||||||
|
'Content-Type': 'application/json',
|
||||||
|
Accept: 'application/json',
|
||||||
|
'X-CSRF-Token': getCSRFToken(),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
|
window.location.replace(response.data.redirect_path);
|
||||||
|
} catch (error) {
|
||||||
|
if (error instanceof AxiosError && error.response?.status === 422) {
|
||||||
|
const errorMessage = document.getElementById(
|
||||||
|
'security-key-error-message',
|
||||||
|
);
|
||||||
|
errorMessage?.classList.remove('hidden');
|
||||||
|
|
||||||
|
logAxiosResponseError(error);
|
||||||
|
} else {
|
||||||
|
console.error(error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async function handleWebauthnCredentialRegistration(nickname: string) {
|
||||||
|
try {
|
||||||
|
const response = await axios.get<PublicKeyCredentialCreationOptionsJSON>(
|
||||||
|
'/settings/security_keys/options',
|
||||||
|
);
|
||||||
|
|
||||||
|
const credentialOptions = response.data;
|
||||||
|
|
||||||
|
try {
|
||||||
|
const credential = await WebAuthnJSON.create({
|
||||||
|
publicKey: credentialOptions,
|
||||||
|
});
|
||||||
|
|
||||||
|
const params = {
|
||||||
|
credential: credential,
|
||||||
|
nickname: nickname,
|
||||||
|
};
|
||||||
|
|
||||||
|
await callback('/settings/security_keys', params);
|
||||||
|
} catch (error) {
|
||||||
|
const errorMessage = document.getElementById(
|
||||||
|
'security-key-error-message',
|
||||||
|
);
|
||||||
|
errorMessage?.classList.remove('hidden');
|
||||||
|
console.error(error);
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
logAxiosResponseError(error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async function handleWebauthnCredentialAuthentication() {
|
||||||
|
try {
|
||||||
|
const response = await axios.get<PublicKeyCredentialCreationOptionsJSON>(
|
||||||
|
'sessions/security_key_options',
|
||||||
|
);
|
||||||
|
|
||||||
|
const credentialOptions = response.data;
|
||||||
|
|
||||||
|
try {
|
||||||
|
const credential = await WebAuthnJSON.get({
|
||||||
|
publicKey: credentialOptions,
|
||||||
|
});
|
||||||
|
|
||||||
|
const params = { user: { credential: credential } };
|
||||||
|
void callback('sign_in', params);
|
||||||
|
} catch (error) {
|
||||||
|
const errorMessage = document.getElementById(
|
||||||
|
'security-key-error-message',
|
||||||
|
);
|
||||||
|
errorMessage?.classList.remove('hidden');
|
||||||
|
console.error(error);
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
logAxiosResponseError(error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ready(() => {
|
||||||
|
if (!WebAuthnJSON.supported()) {
|
||||||
|
const unsupported_browser_message = document.getElementById(
|
||||||
|
'unsupported-browser-message',
|
||||||
|
);
|
||||||
|
if (unsupported_browser_message) {
|
||||||
|
unsupported_browser_message.classList.remove('hidden');
|
||||||
|
const button = document.querySelector<HTMLButtonElement>(
|
||||||
|
'button.btn.js-webauthn',
|
||||||
|
);
|
||||||
|
if (button) button.disabled = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const webAuthnCredentialRegistrationForm =
|
||||||
|
document.querySelector<HTMLFormElement>('form#new_webauthn_credential');
|
||||||
|
if (webAuthnCredentialRegistrationForm) {
|
||||||
|
webAuthnCredentialRegistrationForm.addEventListener('submit', (event) => {
|
||||||
|
event.preventDefault();
|
||||||
|
|
||||||
|
if (!(event.target instanceof HTMLFormElement)) return;
|
||||||
|
|
||||||
|
const nickname = event.target.querySelector<HTMLInputElement>(
|
||||||
|
'input[name="new_webauthn_credential[nickname]"]',
|
||||||
|
);
|
||||||
|
|
||||||
|
if (nickname?.value) {
|
||||||
|
void handleWebauthnCredentialRegistration(nickname.value);
|
||||||
|
} else {
|
||||||
|
nickname?.focus();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
const webAuthnCredentialAuthenticationForm =
|
||||||
|
document.getElementById('webauthn-form');
|
||||||
|
if (webAuthnCredentialAuthenticationForm) {
|
||||||
|
webAuthnCredentialAuthenticationForm.addEventListener('submit', (event) => {
|
||||||
|
event.preventDefault();
|
||||||
|
void handleWebauthnCredentialAuthentication();
|
||||||
|
});
|
||||||
|
|
||||||
|
const otpAuthenticationForm = document.getElementById(
|
||||||
|
'otp-authentication-form',
|
||||||
|
);
|
||||||
|
|
||||||
|
const linkToOtp = document.getElementById('link-to-otp');
|
||||||
|
|
||||||
|
linkToOtp?.addEventListener('click', () => {
|
||||||
|
webAuthnCredentialAuthenticationForm.classList.add('hidden');
|
||||||
|
otpAuthenticationForm?.classList.remove('hidden');
|
||||||
|
hideFlashMessages();
|
||||||
|
});
|
||||||
|
|
||||||
|
const linkToWebAuthn = document.getElementById('link-to-webauthn');
|
||||||
|
linkToWebAuthn?.addEventListener('click', () => {
|
||||||
|
otpAuthenticationForm?.classList.add('hidden');
|
||||||
|
webAuthnCredentialAuthenticationForm.classList.remove('hidden');
|
||||||
|
hideFlashMessages();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}).catch((e: unknown) => {
|
||||||
|
throw e;
|
||||||
|
});
|
|
@ -1,16 +1,16 @@
|
||||||
import PropTypes from 'prop-types';
|
import { useCallback } from 'react';
|
||||||
|
|
||||||
import { FormattedMessage } from 'react-intl';
|
import { FormattedMessage } from 'react-intl';
|
||||||
|
|
||||||
import ImmutablePropTypes from 'react-immutable-proptypes';
|
|
||||||
import ImmutablePureComponent from 'react-immutable-pure-component';
|
|
||||||
|
|
||||||
import FindInPageIcon from '@/material-icons/400-24px/find_in_page.svg?react';
|
import FindInPageIcon from '@/material-icons/400-24px/find_in_page.svg?react';
|
||||||
import PeopleIcon from '@/material-icons/400-24px/group.svg?react';
|
import PeopleIcon from '@/material-icons/400-24px/group.svg?react';
|
||||||
import TagIcon from '@/material-icons/400-24px/tag.svg?react';
|
import TagIcon from '@/material-icons/400-24px/tag.svg?react';
|
||||||
|
import { expandSearch } from 'flavours/glitch/actions/search';
|
||||||
import { Icon } from 'flavours/glitch/components/icon';
|
import { Icon } from 'flavours/glitch/components/icon';
|
||||||
import { LoadMore } from 'flavours/glitch/components/load_more';
|
import { LoadMore } from 'flavours/glitch/components/load_more';
|
||||||
|
import { LoadingIndicator } from 'flavours/glitch/components/loading_indicator';
|
||||||
import { SearchSection } from 'flavours/glitch/features/explore/components/search_section';
|
import { SearchSection } from 'flavours/glitch/features/explore/components/search_section';
|
||||||
|
import { useAppDispatch, useAppSelector } from 'flavours/glitch/store';
|
||||||
|
|
||||||
import { ImmutableHashtag as Hashtag } from '../../../components/hashtag';
|
import { ImmutableHashtag as Hashtag } from '../../../components/hashtag';
|
||||||
import AccountContainer from '../../../containers/account_container';
|
import AccountContainer from '../../../containers/account_container';
|
||||||
|
@ -26,62 +26,68 @@ const withoutLastResult = list => {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
class SearchResults extends ImmutablePureComponent {
|
export const SearchResults = () => {
|
||||||
|
const results = useAppSelector((state) => state.getIn(['search', 'results']));
|
||||||
|
const isLoading = useAppSelector((state) => state.getIn(['search', 'isLoading']));
|
||||||
|
|
||||||
static propTypes = {
|
const dispatch = useAppDispatch();
|
||||||
results: ImmutablePropTypes.map.isRequired,
|
|
||||||
expandSearch: PropTypes.func.isRequired,
|
|
||||||
searchTerm: PropTypes.string,
|
|
||||||
};
|
|
||||||
|
|
||||||
handleLoadMoreAccounts = () => this.props.expandSearch('accounts');
|
const handleLoadMoreAccounts = useCallback(() => {
|
||||||
|
dispatch(expandSearch('accounts'));
|
||||||
|
}, [dispatch]);
|
||||||
|
|
||||||
handleLoadMoreStatuses = () => this.props.expandSearch('statuses');
|
const handleLoadMoreStatuses = useCallback(() => {
|
||||||
|
dispatch(expandSearch('statuses'));
|
||||||
|
}, [dispatch]);
|
||||||
|
|
||||||
handleLoadMoreHashtags = () => this.props.expandSearch('hashtags');
|
const handleLoadMoreHashtags = useCallback(() => {
|
||||||
|
dispatch(expandSearch('hashtags'));
|
||||||
|
}, [dispatch]);
|
||||||
|
|
||||||
render () {
|
let accounts, statuses, hashtags;
|
||||||
const { results } = this.props;
|
|
||||||
|
|
||||||
let accounts, statuses, hashtags;
|
if (results.get('accounts') && results.get('accounts').size > 0) {
|
||||||
|
accounts = (
|
||||||
if (results.get('accounts') && results.get('accounts').size > 0) {
|
<SearchSection title={<><Icon id='users' icon={PeopleIcon} /><FormattedMessage id='search_results.accounts' defaultMessage='Profiles' /></>}>
|
||||||
accounts = (
|
{withoutLastResult(results.get('accounts')).map(accountId => <AccountContainer key={accountId} id={accountId} />)}
|
||||||
<SearchSection title={<><Icon id='users' icon={PeopleIcon} /><FormattedMessage id='search_results.accounts' defaultMessage='Profiles' /></>}>
|
{(results.get('accounts').size > INITIAL_PAGE_LIMIT && results.get('accounts').size % INITIAL_PAGE_LIMIT === 1) && <LoadMore visible onClick={handleLoadMoreAccounts} />}
|
||||||
{withoutLastResult(results.get('accounts')).map(accountId => <AccountContainer key={accountId} id={accountId} />)}
|
</SearchSection>
|
||||||
{(results.get('accounts').size > INITIAL_PAGE_LIMIT && results.get('accounts').size % INITIAL_PAGE_LIMIT === 1) && <LoadMore visible onClick={this.handleLoadMoreAccounts} />}
|
|
||||||
</SearchSection>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (results.get('hashtags') && results.get('hashtags').size > 0) {
|
|
||||||
hashtags = (
|
|
||||||
<SearchSection title={<><Icon id='hashtag' icon={TagIcon} /><FormattedMessage id='search_results.hashtags' defaultMessage='Hashtags' /></>}>
|
|
||||||
{withoutLastResult(results.get('hashtags')).map(hashtag => <Hashtag key={hashtag.get('name')} hashtag={hashtag} />)}
|
|
||||||
{(results.get('hashtags').size > INITIAL_PAGE_LIMIT && results.get('hashtags').size % INITIAL_PAGE_LIMIT === 1) && <LoadMore visible onClick={this.handleLoadMoreHashtags} />}
|
|
||||||
</SearchSection>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (results.get('statuses') && results.get('statuses').size > 0) {
|
|
||||||
statuses = (
|
|
||||||
<SearchSection title={<><Icon id='quote-right' icon={FindInPageIcon} /><FormattedMessage id='search_results.statuses' defaultMessage='Posts' /></>}>
|
|
||||||
{withoutLastResult(results.get('statuses')).map(statusId => <StatusContainer key={statusId} id={statusId} />)}
|
|
||||||
{(results.get('statuses').size > INITIAL_PAGE_LIMIT && results.get('statuses').size % INITIAL_PAGE_LIMIT === 1) && <LoadMore visible onClick={this.handleLoadMoreStatuses} />}
|
|
||||||
</SearchSection>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
return (
|
|
||||||
<div className='search-results'>
|
|
||||||
{accounts}
|
|
||||||
{hashtags}
|
|
||||||
{statuses}
|
|
||||||
</div>
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
if (results.get('hashtags') && results.get('hashtags').size > 0) {
|
||||||
|
hashtags = (
|
||||||
|
<SearchSection title={<><Icon id='hashtag' icon={TagIcon} /><FormattedMessage id='search_results.hashtags' defaultMessage='Hashtags' /></>}>
|
||||||
|
{withoutLastResult(results.get('hashtags')).map(hashtag => <Hashtag key={hashtag.get('name')} hashtag={hashtag} />)}
|
||||||
|
{(results.get('hashtags').size > INITIAL_PAGE_LIMIT && results.get('hashtags').size % INITIAL_PAGE_LIMIT === 1) && <LoadMore visible onClick={handleLoadMoreHashtags} />}
|
||||||
|
</SearchSection>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
export default SearchResults;
|
if (results.get('statuses') && results.get('statuses').size > 0) {
|
||||||
|
statuses = (
|
||||||
|
<SearchSection title={<><Icon id='quote-right' icon={FindInPageIcon} /><FormattedMessage id='search_results.statuses' defaultMessage='Posts' /></>}>
|
||||||
|
{withoutLastResult(results.get('statuses')).map(statusId => <StatusContainer key={statusId} id={statusId} />)}
|
||||||
|
{(results.get('statuses').size > INITIAL_PAGE_LIMIT && results.get('statuses').size % INITIAL_PAGE_LIMIT === 1) && <LoadMore visible onClick={handleLoadMoreStatuses} />}
|
||||||
|
</SearchSection>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className='search-results'>
|
||||||
|
{!accounts && !hashtags && !statuses && (
|
||||||
|
isLoading ? (
|
||||||
|
<LoadingIndicator />
|
||||||
|
) : (
|
||||||
|
<div className='empty-column-indicator'>
|
||||||
|
<FormattedMessage id='search_results.nothing_found' defaultMessage='Could not find anything for these search terms' />
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
)}
|
||||||
|
{accounts}
|
||||||
|
{hashtags}
|
||||||
|
{statuses}
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
|
||||||
|
};
|
||||||
|
|
|
@ -1,20 +0,0 @@
|
||||||
import { connect } from 'react-redux';
|
|
||||||
|
|
||||||
import { expandSearch } from 'flavours/glitch/actions/search';
|
|
||||||
import { fetchSuggestions, dismissSuggestion } from 'flavours/glitch/actions/suggestions';
|
|
||||||
|
|
||||||
import SearchResults from '../components/search_results';
|
|
||||||
|
|
||||||
const mapStateToProps = state => ({
|
|
||||||
results: state.getIn(['search', 'results']),
|
|
||||||
suggestions: state.getIn(['suggestions', 'items']),
|
|
||||||
searchTerm: state.getIn(['search', 'searchTerm']),
|
|
||||||
});
|
|
||||||
|
|
||||||
const mapDispatchToProps = dispatch => ({
|
|
||||||
fetchSuggestions: () => dispatch(fetchSuggestions()),
|
|
||||||
expandSearch: type => dispatch(expandSearch(type)),
|
|
||||||
dismissSuggestion: account => dispatch(dismissSuggestion(account.get('id'))),
|
|
||||||
});
|
|
||||||
|
|
||||||
export default connect(mapStateToProps, mapDispatchToProps)(SearchResults);
|
|
|
@ -32,9 +32,9 @@ import { mascot } from '../../initial_state';
|
||||||
import { isMobile } from '../../is_mobile';
|
import { isMobile } from '../../is_mobile';
|
||||||
import Motion from '../ui/util/optional_motion';
|
import Motion from '../ui/util/optional_motion';
|
||||||
|
|
||||||
|
import { SearchResults } from './components/search_results';
|
||||||
import ComposeFormContainer from './containers/compose_form_container';
|
import ComposeFormContainer from './containers/compose_form_container';
|
||||||
import SearchContainer from './containers/search_container';
|
import SearchContainer from './containers/search_container';
|
||||||
import SearchResultsContainer from './containers/search_results_container';
|
|
||||||
|
|
||||||
const messages = defineMessages({
|
const messages = defineMessages({
|
||||||
start: { id: 'getting_started.heading', defaultMessage: 'Getting started' },
|
start: { id: 'getting_started.heading', defaultMessage: 'Getting started' },
|
||||||
|
@ -183,7 +183,7 @@ class Compose extends PureComponent {
|
||||||
<Motion defaultStyle={{ x: -100 }} style={{ x: spring(showSearch ? 0 : -100, { stiffness: 210, damping: 20 }) }}>
|
<Motion defaultStyle={{ x: -100 }} style={{ x: spring(showSearch ? 0 : -100, { stiffness: 210, damping: 20 }) }}>
|
||||||
{({ x }) => (
|
{({ x }) => (
|
||||||
<div className='drawer__inner darker' style={{ transform: `translateX(${x}%)`, visibility: x === -100 ? 'hidden' : 'visible' }}>
|
<div className='drawer__inner darker' style={{ transform: `translateX(${x}%)`, visibility: x === -100 ? 'hidden' : 'visible' }}>
|
||||||
<SearchResultsContainer />
|
<SearchResults />
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
</Motion>
|
</Motion>
|
||||||
|
|
|
@ -0,0 +1,88 @@
|
||||||
|
import PropTypes from 'prop-types';
|
||||||
|
import { useCallback } from 'react';
|
||||||
|
|
||||||
|
import { FormattedMessage, useIntl, defineMessages } from 'react-intl';
|
||||||
|
|
||||||
|
import { Link } from 'react-router-dom';
|
||||||
|
|
||||||
|
import { useDispatch, useSelector } from 'react-redux';
|
||||||
|
|
||||||
|
import CloseIcon from '@/material-icons/400-24px/close.svg?react';
|
||||||
|
import { followAccount, unfollowAccount } from 'flavours/glitch/actions/accounts';
|
||||||
|
import { dismissSuggestion } from 'flavours/glitch/actions/suggestions';
|
||||||
|
import { Avatar } from 'flavours/glitch/components/avatar';
|
||||||
|
import { Button } from 'flavours/glitch/components/button';
|
||||||
|
import { DisplayName } from 'flavours/glitch/components/display_name';
|
||||||
|
import { IconButton } from 'flavours/glitch/components/icon_button';
|
||||||
|
import { domain } from 'flavours/glitch/initial_state';
|
||||||
|
|
||||||
|
const messages = defineMessages({
|
||||||
|
follow: { id: 'account.follow', defaultMessage: 'Follow' },
|
||||||
|
unfollow: { id: 'account.unfollow', defaultMessage: 'Unfollow' },
|
||||||
|
dismiss: { id: 'follow_suggestions.dismiss', defaultMessage: "Don't show again" },
|
||||||
|
});
|
||||||
|
|
||||||
|
export const Card = ({ id, source }) => {
|
||||||
|
const intl = useIntl();
|
||||||
|
const account = useSelector(state => state.getIn(['accounts', id]));
|
||||||
|
const relationship = useSelector(state => state.getIn(['relationships', id]));
|
||||||
|
const dispatch = useDispatch();
|
||||||
|
const following = relationship?.get('following') ?? relationship?.get('requested');
|
||||||
|
|
||||||
|
const handleFollow = useCallback(() => {
|
||||||
|
if (following) {
|
||||||
|
dispatch(unfollowAccount(id));
|
||||||
|
} else {
|
||||||
|
dispatch(followAccount(id));
|
||||||
|
}
|
||||||
|
}, [id, following, dispatch]);
|
||||||
|
|
||||||
|
const handleDismiss = useCallback(() => {
|
||||||
|
dispatch(dismissSuggestion(id));
|
||||||
|
}, [id, dispatch]);
|
||||||
|
|
||||||
|
let label;
|
||||||
|
|
||||||
|
switch (source) {
|
||||||
|
case 'friends_of_friends':
|
||||||
|
label = <FormattedMessage id='follow_suggestions.friends_of_friends_longer' defaultMessage='Popular among people you follow' />;
|
||||||
|
break;
|
||||||
|
case 'similar_to_recently_followed':
|
||||||
|
label = <FormattedMessage id='follow_suggestions.similar_to_recently_followed_longer' defaultMessage='Similar to profiles you recently followed' />;
|
||||||
|
break;
|
||||||
|
case 'featured':
|
||||||
|
label = <FormattedMessage id='follow_suggestions.featured_longer' defaultMessage='Hand-picked by the {domain} team' values={{ domain }} />;
|
||||||
|
break;
|
||||||
|
case 'most_followed':
|
||||||
|
label = <FormattedMessage id='follow_suggestions.popular_suggestion_longer' defaultMessage='Popular on {domain}' values={{ domain }} />;
|
||||||
|
break;
|
||||||
|
case 'most_interactions':
|
||||||
|
label = <FormattedMessage id='follow_suggestions.popular_suggestion_longer' defaultMessage='Popular on {domain}' values={{ domain }} />;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className='explore__suggestions__card'>
|
||||||
|
<div className='explore__suggestions__card__source'>
|
||||||
|
{label}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className='explore__suggestions__card__body'>
|
||||||
|
<Link to={`/@${account.get('acct')}`}><Avatar account={account} size={48} /></Link>
|
||||||
|
|
||||||
|
<div className='explore__suggestions__card__body__main'>
|
||||||
|
<div className='explore__suggestions__card__body__main__name-button'>
|
||||||
|
<Link className='explore__suggestions__card__body__main__name-button__name' to={`/@${account.get('acct')}`}><DisplayName account={account} /></Link>
|
||||||
|
<IconButton iconComponent={CloseIcon} onClick={handleDismiss} title={intl.formatMessage(messages.dismiss)} />
|
||||||
|
<Button text={intl.formatMessage(following ? messages.unfollow : messages.follow)} secondary={following} onClick={handleFollow} />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
Card.propTypes = {
|
||||||
|
id: PropTypes.string.isRequired,
|
||||||
|
source: PropTypes.oneOf(['friends_of_friends', 'similar_to_recently_followed', 'featured', 'most_followed', 'most_interactions']),
|
||||||
|
};
|
|
@ -10,9 +10,10 @@ import { connect } from 'react-redux';
|
||||||
|
|
||||||
import { fetchSuggestions, dismissSuggestion } from 'flavours/glitch/actions/suggestions';
|
import { fetchSuggestions, dismissSuggestion } from 'flavours/glitch/actions/suggestions';
|
||||||
import { LoadingIndicator } from 'flavours/glitch/components/loading_indicator';
|
import { LoadingIndicator } from 'flavours/glitch/components/loading_indicator';
|
||||||
import AccountCard from 'flavours/glitch/features/directory/components/account_card';
|
|
||||||
import { WithRouterPropTypes } from 'flavours/glitch/utils/react_router';
|
import { WithRouterPropTypes } from 'flavours/glitch/utils/react_router';
|
||||||
|
|
||||||
|
import { Card } from './components/card';
|
||||||
|
|
||||||
const mapStateToProps = state => ({
|
const mapStateToProps = state => ({
|
||||||
suggestions: state.getIn(['suggestions', 'items']),
|
suggestions: state.getIn(['suggestions', 'items']),
|
||||||
isLoading: state.getIn(['suggestions', 'isLoading']),
|
isLoading: state.getIn(['suggestions', 'isLoading']),
|
||||||
|
@ -59,7 +60,11 @@ class Suggestions extends PureComponent {
|
||||||
return (
|
return (
|
||||||
<div className='explore__suggestions scrollable' data-nosnippet>
|
<div className='explore__suggestions scrollable' data-nosnippet>
|
||||||
{isLoading ? <LoadingIndicator /> : suggestions.map(suggestion => (
|
{isLoading ? <LoadingIndicator /> : suggestions.map(suggestion => (
|
||||||
<AccountCard key={suggestion.get('account')} id={suggestion.get('account')} onDismiss={suggestion.get('source') === 'past_interactions' ? this.handleDismiss : null} />
|
<Card
|
||||||
|
key={suggestion.get('account')}
|
||||||
|
id={suggestion.get('account')}
|
||||||
|
source={suggestion.getIn(['sources', 0])}
|
||||||
|
/>
|
||||||
))}
|
))}
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
|
|
@ -0,0 +1,78 @@
|
||||||
|
import { defineMessages, FormattedMessage, useIntl } from 'react-intl';
|
||||||
|
|
||||||
|
import GavelIcon from '@/material-icons/400-24px/gavel.svg?react';
|
||||||
|
import { Icon } from 'flavours/glitch/components/icon';
|
||||||
|
|
||||||
|
// This needs to be kept in sync with app/models/account_warning.rb
|
||||||
|
const messages = defineMessages({
|
||||||
|
none: {
|
||||||
|
id: 'notification.moderation_warning.action_none',
|
||||||
|
defaultMessage: 'Your account has received a moderation warning.',
|
||||||
|
},
|
||||||
|
disable: {
|
||||||
|
id: 'notification.moderation_warning.action_disable',
|
||||||
|
defaultMessage: 'Your account has been disabled.',
|
||||||
|
},
|
||||||
|
mark_statuses_as_sensitive: {
|
||||||
|
id: 'notification.moderation_warning.action_mark_statuses_as_sensitive',
|
||||||
|
defaultMessage: 'Some of your posts have been marked as sensitive.',
|
||||||
|
},
|
||||||
|
delete_statuses: {
|
||||||
|
id: 'notification.moderation_warning.action_delete_statuses',
|
||||||
|
defaultMessage: 'Some of your posts have been removed.',
|
||||||
|
},
|
||||||
|
sensitive: {
|
||||||
|
id: 'notification.moderation_warning.action_sensitive',
|
||||||
|
defaultMessage: 'Your posts will be marked as sensitive from now on.',
|
||||||
|
},
|
||||||
|
silence: {
|
||||||
|
id: 'notification.moderation_warning.action_silence',
|
||||||
|
defaultMessage: 'Your account has been limited.',
|
||||||
|
},
|
||||||
|
suspend: {
|
||||||
|
id: 'notification.moderation_warning.action_suspend',
|
||||||
|
defaultMessage: 'Your account has been suspended.',
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
interface Props {
|
||||||
|
action:
|
||||||
|
| 'none'
|
||||||
|
| 'disable'
|
||||||
|
| 'mark_statuses_as_sensitive'
|
||||||
|
| 'delete_statuses'
|
||||||
|
| 'sensitive'
|
||||||
|
| 'silence'
|
||||||
|
| 'suspend';
|
||||||
|
id: string;
|
||||||
|
hidden: boolean;
|
||||||
|
}
|
||||||
|
|
||||||
|
export const ModerationWarning: React.FC<Props> = ({ action, id, hidden }) => {
|
||||||
|
const intl = useIntl();
|
||||||
|
|
||||||
|
if (hidden) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<a
|
||||||
|
href={`/disputes/strikes/${id}`}
|
||||||
|
target='_blank'
|
||||||
|
rel='noopener noreferrer'
|
||||||
|
className='notification__moderation-warning'
|
||||||
|
>
|
||||||
|
<Icon id='warning' icon={GavelIcon} />
|
||||||
|
|
||||||
|
<div className='notification__moderation-warning__content'>
|
||||||
|
<p>{intl.formatMessage(messages[action])}</p>
|
||||||
|
<span className='link-button'>
|
||||||
|
<FormattedMessage
|
||||||
|
id='notification.moderation-warning.learn_more'
|
||||||
|
defaultMessage='Learn more'
|
||||||
|
/>
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
</a>
|
||||||
|
);
|
||||||
|
};
|
|
@ -22,6 +22,7 @@ import { WithRouterPropTypes } from 'flavours/glitch/utils/react_router';
|
||||||
import FollowRequestContainer from '../containers/follow_request_container';
|
import FollowRequestContainer from '../containers/follow_request_container';
|
||||||
import NotificationOverlayContainer from '../containers/overlay_container';
|
import NotificationOverlayContainer from '../containers/overlay_container';
|
||||||
|
|
||||||
|
import { ModerationWarning } from './moderation_warning';
|
||||||
import { RelationshipsSeveranceEvent } from './relationships_severance_event';
|
import { RelationshipsSeveranceEvent } from './relationships_severance_event';
|
||||||
import Report from './report';
|
import Report from './report';
|
||||||
|
|
||||||
|
@ -30,6 +31,7 @@ const messages = defineMessages({
|
||||||
adminSignUp: { id: 'notification.admin.sign_up', defaultMessage: '{name} signed up' },
|
adminSignUp: { id: 'notification.admin.sign_up', defaultMessage: '{name} signed up' },
|
||||||
adminReport: { id: 'notification.admin.report', defaultMessage: '{name} reported {target}' },
|
adminReport: { id: 'notification.admin.report', defaultMessage: '{name} reported {target}' },
|
||||||
relationshipsSevered: { id: 'notification.relationships_severance_event', defaultMessage: 'Lost connections with {name}' },
|
relationshipsSevered: { id: 'notification.relationships_severance_event', defaultMessage: 'Lost connections with {name}' },
|
||||||
|
moderationWarning: { id: 'notification.moderation_warning', defaultMessage: 'Your have received a moderation warning' },
|
||||||
});
|
});
|
||||||
|
|
||||||
const notificationForScreenReader = (intl, message, timestamp) => {
|
const notificationForScreenReader = (intl, message, timestamp) => {
|
||||||
|
@ -328,6 +330,27 @@ class Notification extends ImmutablePureComponent {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
renderModerationWarning (notification) {
|
||||||
|
const { intl, unread, hidden } = this.props;
|
||||||
|
const warning = notification.get('moderation_warning');
|
||||||
|
|
||||||
|
if (!warning) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<HotKeys handlers={this.getHandlers()}>
|
||||||
|
<div className={classNames('notification notification-moderation-warning focusable', { unread })} tabIndex={0} aria-label={notificationForScreenReader(intl, intl.formatMessage(messages.moderationWarning), notification.get('created_at'))}>
|
||||||
|
<ModerationWarning
|
||||||
|
action={warning.get('action')}
|
||||||
|
id={warning.get('id')}
|
||||||
|
hidden={hidden}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</HotKeys>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
renderAdminSignUp (notification, account, link) {
|
renderAdminSignUp (notification, account, link) {
|
||||||
const { intl, unread } = this.props;
|
const { intl, unread } = this.props;
|
||||||
|
|
||||||
|
@ -423,6 +446,8 @@ class Notification extends ImmutablePureComponent {
|
||||||
return this.renderPoll(notification);
|
return this.renderPoll(notification);
|
||||||
case 'severed_relationships':
|
case 'severed_relationships':
|
||||||
return this.renderRelationshipsSevered(notification);
|
return this.renderRelationshipsSevered(notification);
|
||||||
|
case 'moderation_warning':
|
||||||
|
return this.renderModerationWarning(notification);
|
||||||
case 'admin.sign_up':
|
case 'admin.sign_up':
|
||||||
return this.renderAdminSignUp(notification, account, link);
|
return this.renderAdminSignUp(notification, account, link);
|
||||||
case 'admin.report':
|
case 'admin.report':
|
||||||
|
|
|
@ -1,42 +0,0 @@
|
||||||
import 'packs/public-path';
|
|
||||||
import axios from 'axios';
|
|
||||||
|
|
||||||
import ready from 'flavours/glitch/ready';
|
|
||||||
|
|
||||||
ready(() => {
|
|
||||||
setInterval(() => {
|
|
||||||
axios.get('/api/v1/emails/check_confirmation').then((response) => {
|
|
||||||
if (response.data) {
|
|
||||||
window.location = '/start';
|
|
||||||
}
|
|
||||||
}).catch(error => {
|
|
||||||
console.error(error);
|
|
||||||
});
|
|
||||||
}, 5000);
|
|
||||||
|
|
||||||
document.querySelectorAll('.timer-button').forEach(button => {
|
|
||||||
let counter = 30;
|
|
||||||
|
|
||||||
const container = document.createElement('span');
|
|
||||||
|
|
||||||
const updateCounter = () => {
|
|
||||||
container.innerText = ` (${counter})`;
|
|
||||||
};
|
|
||||||
|
|
||||||
updateCounter();
|
|
||||||
|
|
||||||
const countdown = setInterval(() => {
|
|
||||||
counter--;
|
|
||||||
|
|
||||||
if (counter === 0) {
|
|
||||||
button.disabled = false;
|
|
||||||
button.removeChild(container);
|
|
||||||
clearInterval(countdown);
|
|
||||||
} else {
|
|
||||||
updateCounter();
|
|
||||||
}
|
|
||||||
}, 1000);
|
|
||||||
|
|
||||||
button.appendChild(container);
|
|
||||||
});
|
|
||||||
});
|
|
|
@ -1,119 +0,0 @@
|
||||||
import * as WebAuthnJSON from '@github/webauthn-json';
|
|
||||||
import axios from 'axios';
|
|
||||||
|
|
||||||
import ready from 'flavours/glitch/ready';
|
|
||||||
import 'regenerator-runtime/runtime';
|
|
||||||
|
|
||||||
function getCSRFToken() {
|
|
||||||
var CSRFSelector = document.querySelector('meta[name="csrf-token"]');
|
|
||||||
if (CSRFSelector) {
|
|
||||||
return CSRFSelector.getAttribute('content');
|
|
||||||
} else {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function hideFlashMessages() {
|
|
||||||
Array.from(document.getElementsByClassName('flash-message')).forEach(function(flashMessage) {
|
|
||||||
flashMessage.classList.add('hidden');
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
function callback(url, body) {
|
|
||||||
axios.post(url, JSON.stringify(body), {
|
|
||||||
headers: {
|
|
||||||
'Content-Type': 'application/json',
|
|
||||||
'Accept': 'application/json',
|
|
||||||
'X-CSRF-Token': getCSRFToken(),
|
|
||||||
},
|
|
||||||
credentials: 'same-origin',
|
|
||||||
}).then(function(response) {
|
|
||||||
window.location.replace(response.data.redirect_path);
|
|
||||||
}).catch(function(error) {
|
|
||||||
if (error.response.status === 422) {
|
|
||||||
const errorMessage = document.getElementById('security-key-error-message');
|
|
||||||
errorMessage.classList.remove('hidden');
|
|
||||||
console.error(error.response.data.error);
|
|
||||||
} else {
|
|
||||||
console.error(error);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
ready(() => {
|
|
||||||
if (!WebAuthnJSON.supported()) {
|
|
||||||
const unsupported_browser_message = document.getElementById('unsupported-browser-message');
|
|
||||||
if (unsupported_browser_message) {
|
|
||||||
unsupported_browser_message.classList.remove('hidden');
|
|
||||||
document.querySelector('.btn.js-webauthn').disabled = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
const webAuthnCredentialRegistrationForm = document.getElementById('new_webauthn_credential');
|
|
||||||
if (webAuthnCredentialRegistrationForm) {
|
|
||||||
webAuthnCredentialRegistrationForm.addEventListener('submit', (event) => {
|
|
||||||
event.preventDefault();
|
|
||||||
|
|
||||||
var nickname = event.target.querySelector('input[name="new_webauthn_credential[nickname]"]');
|
|
||||||
if (nickname.value) {
|
|
||||||
axios.get('/settings/security_keys/options')
|
|
||||||
.then((response) => {
|
|
||||||
const credentialOptions = response.data;
|
|
||||||
|
|
||||||
WebAuthnJSON.create({ 'publicKey': credentialOptions }).then((credential) => {
|
|
||||||
var params = { 'credential': credential, 'nickname': nickname.value };
|
|
||||||
callback('/settings/security_keys', params);
|
|
||||||
}).catch((error) => {
|
|
||||||
const errorMessage = document.getElementById('security-key-error-message');
|
|
||||||
errorMessage.classList.remove('hidden');
|
|
||||||
console.error(error);
|
|
||||||
});
|
|
||||||
}).catch((error) => {
|
|
||||||
console.error(error.response.data.error);
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
nickname.focus();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
const webAuthnCredentialAuthenticationForm = document.getElementById('webauthn-form');
|
|
||||||
if (webAuthnCredentialAuthenticationForm) {
|
|
||||||
webAuthnCredentialAuthenticationForm.addEventListener('submit', (event) => {
|
|
||||||
event.preventDefault();
|
|
||||||
|
|
||||||
axios.get('sessions/security_key_options')
|
|
||||||
.then((response) => {
|
|
||||||
const credentialOptions = response.data;
|
|
||||||
|
|
||||||
WebAuthnJSON.get({ 'publicKey': credentialOptions }).then((credential) => {
|
|
||||||
var params = { 'user': { 'credential': credential } };
|
|
||||||
callback('sign_in', params);
|
|
||||||
}).catch((error) => {
|
|
||||||
const errorMessage = document.getElementById('security-key-error-message');
|
|
||||||
errorMessage.classList.remove('hidden');
|
|
||||||
console.error(error);
|
|
||||||
});
|
|
||||||
}).catch((error) => {
|
|
||||||
console.error(error.response.data.error);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
const otpAuthenticationForm = document.getElementById('otp-authentication-form');
|
|
||||||
|
|
||||||
const linkToOtp = document.getElementById('link-to-otp');
|
|
||||||
linkToOtp.addEventListener('click', () => {
|
|
||||||
webAuthnCredentialAuthenticationForm.classList.add('hidden');
|
|
||||||
otpAuthenticationForm.classList.remove('hidden');
|
|
||||||
hideFlashMessages();
|
|
||||||
});
|
|
||||||
|
|
||||||
const linkToWebAuthn = document.getElementById('link-to-webauthn');
|
|
||||||
linkToWebAuthn.addEventListener('click', () => {
|
|
||||||
otpAuthenticationForm.classList.add('hidden');
|
|
||||||
webAuthnCredentialAuthenticationForm.classList.remove('hidden');
|
|
||||||
hideFlashMessages();
|
|
||||||
});
|
|
||||||
}
|
|
||||||
});
|
|
|
@ -62,6 +62,7 @@ export const notificationToMap = (notification, markForDelete = false) => Immuta
|
||||||
status: notification.status ? notification.status.id : null,
|
status: notification.status ? notification.status.id : null,
|
||||||
report: notification.report ? fromJS(notification.report) : null,
|
report: notification.report ? fromJS(notification.report) : null,
|
||||||
event: notification.event ? fromJS(notification.event) : null,
|
event: notification.event ? fromJS(notification.event) : null,
|
||||||
|
moderation_warning: notification.moderation_warning ? fromJS(notification.moderation_warning) : null,
|
||||||
});
|
});
|
||||||
|
|
||||||
const normalizeNotification = (state, notification, usePendingItems) => {
|
const normalizeNotification = (state, notification, usePendingItems) => {
|
||||||
|
|
|
@ -50,6 +50,7 @@ export default function search(state = initialState, action) {
|
||||||
return state.set('hidden', true);
|
return state.set('hidden', true);
|
||||||
case SEARCH_FETCH_REQUEST:
|
case SEARCH_FETCH_REQUEST:
|
||||||
return state.withMutations(map => {
|
return state.withMutations(map => {
|
||||||
|
map.set('results', ImmutableMap());
|
||||||
map.set('isLoading', true);
|
map.set('isLoading', true);
|
||||||
map.set('submitted', true);
|
map.set('submitted', true);
|
||||||
map.set('type', action.searchType);
|
map.set('type', action.searchType);
|
||||||
|
|
|
@ -2228,7 +2228,22 @@ a .account__avatar {
|
||||||
white-space: nowrap;
|
white-space: nowrap;
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
gap: 4px;
|
gap: 8px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.account__relationship,
|
||||||
|
.explore__suggestions__card {
|
||||||
|
.icon-button {
|
||||||
|
border: 1px solid var(--background-border-color);
|
||||||
|
border-radius: 4px;
|
||||||
|
box-sizing: content-box;
|
||||||
|
padding: 5px;
|
||||||
|
|
||||||
|
.icon {
|
||||||
|
width: 24px;
|
||||||
|
height: 24px;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.account-authorize {
|
.account-authorize {
|
||||||
|
@ -2379,7 +2394,8 @@ a.account__display-name {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.notification__relationships-severance-event {
|
.notification__relationships-severance-event,
|
||||||
|
.notification__moderation-warning {
|
||||||
display: flex;
|
display: flex;
|
||||||
gap: 16px;
|
gap: 16px;
|
||||||
color: $secondary-text-color;
|
color: $secondary-text-color;
|
||||||
|
@ -3166,6 +3182,75 @@ $ui-header-logo-wordmark-width: 99px;
|
||||||
display: none;
|
display: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.explore__suggestions__card {
|
||||||
|
padding: 12px 16px;
|
||||||
|
gap: 8px;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
border-bottom: 1px solid var(--background-border-color);
|
||||||
|
|
||||||
|
&:last-child {
|
||||||
|
border-bottom: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
&__source {
|
||||||
|
padding-inline-start: 60px;
|
||||||
|
font-size: 13px;
|
||||||
|
line-height: 16px;
|
||||||
|
color: $dark-text-color;
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
overflow: hidden;
|
||||||
|
white-space: nowrap;
|
||||||
|
}
|
||||||
|
|
||||||
|
&__body {
|
||||||
|
display: flex;
|
||||||
|
gap: 12px;
|
||||||
|
align-items: center;
|
||||||
|
|
||||||
|
&__main {
|
||||||
|
flex: 1 1 auto;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
gap: 8px;
|
||||||
|
min-width: 0;
|
||||||
|
|
||||||
|
&__name-button {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 8px;
|
||||||
|
|
||||||
|
&__name {
|
||||||
|
display: block;
|
||||||
|
color: inherit;
|
||||||
|
text-decoration: none;
|
||||||
|
flex: 1 1 auto;
|
||||||
|
min-width: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.button {
|
||||||
|
min-width: 80px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.display-name {
|
||||||
|
font-size: 15px;
|
||||||
|
line-height: 20px;
|
||||||
|
color: $secondary-text-color;
|
||||||
|
|
||||||
|
strong {
|
||||||
|
font-weight: 700;
|
||||||
|
}
|
||||||
|
|
||||||
|
&__account {
|
||||||
|
color: $darker-text-color;
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@media screen and (max-width: $no-gap-breakpoint - 1px) {
|
@media screen and (max-width: $no-gap-breakpoint - 1px) {
|
||||||
.columns-area__panels__pane--compositional {
|
.columns-area__panels__pane--compositional {
|
||||||
display: none;
|
display: none;
|
||||||
|
@ -6029,7 +6114,7 @@ a.status-card {
|
||||||
user-select: text;
|
user-select: text;
|
||||||
display: flex;
|
display: flex;
|
||||||
|
|
||||||
@media screen and (max-width: $no-gap-breakpoint) {
|
@media screen and (width <= 630px) {
|
||||||
margin-top: auto;
|
margin-top: auto;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -7862,10 +7947,11 @@ img.modal-warning {
|
||||||
content: '';
|
content: '';
|
||||||
position: absolute;
|
position: absolute;
|
||||||
bottom: -1px;
|
bottom: -1px;
|
||||||
left: 0;
|
left: 50%;
|
||||||
width: 100%;
|
transform: translateX(-50%);
|
||||||
|
width: 40px;
|
||||||
height: 3px;
|
height: 3px;
|
||||||
border-radius: 4px;
|
border-radius: 4px 4px 0 0;
|
||||||
background: $highlight-text-color;
|
background: $highlight-text-color;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -10647,6 +10733,7 @@ noscript {
|
||||||
font-weight: 500;
|
font-weight: 500;
|
||||||
font-size: 11px;
|
font-size: 11px;
|
||||||
line-height: 16px;
|
line-height: 16px;
|
||||||
|
word-break: keep-all;
|
||||||
|
|
||||||
&__badge {
|
&__badge {
|
||||||
background: $ui-button-background-color;
|
background: $ui-button-background-color;
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
# (REQUIRED) The directory which contains the entry point files.
|
# (REQUIRED) The directory which contains the entry point files.
|
||||||
pack_directory: app/javascript/flavours/glitch/packs
|
pack_directory: app/javascript/flavours/glitch/entrypoints
|
||||||
|
|
||||||
# (OPTIONAL) Define files to be preloaded when a logged-in user is
|
# (OPTIONAL) Define files to be preloaded when a logged-in user is
|
||||||
# visiting the main web app.
|
# visiting the main web app.
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
# (REQUIRED) The directory which contains the pack files.
|
# (REQUIRED) The directory which contains the pack files.
|
||||||
pack_directory: app/javascript/packs
|
pack_directory: app/javascript/entrypoints
|
||||||
|
|
||||||
# (OPTIONAL) Define files to be preloaded when a logged-in user is
|
# (OPTIONAL) Define files to be preloaded when a logged-in user is
|
||||||
# visiting the main web app.
|
# visiting the main web app.
|
||||||
|
|
|
@ -1,9 +1,7 @@
|
||||||
import { List as ImmutableList } from 'immutable';
|
|
||||||
|
|
||||||
import { debounce } from 'lodash';
|
import { debounce } from 'lodash';
|
||||||
|
|
||||||
import type { MarkerJSON } from 'mastodon/api_types/markers';
|
import type { MarkerJSON } from 'mastodon/api_types/markers';
|
||||||
import type { RootState } from 'mastodon/store';
|
import type { AppDispatch, RootState } from 'mastodon/store';
|
||||||
import { createAppAsyncThunk } from 'mastodon/store/typed_functions';
|
import { createAppAsyncThunk } from 'mastodon/store/typed_functions';
|
||||||
|
|
||||||
import api, { authorizationTokenFromState } from '../api';
|
import api, { authorizationTokenFromState } from '../api';
|
||||||
|
@ -71,34 +69,17 @@ interface MarkerParam {
|
||||||
last_read_id?: string;
|
last_read_id?: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
function getLastHomeId(state: RootState): string | undefined {
|
|
||||||
/* eslint-disable @typescript-eslint/no-unsafe-return, @typescript-eslint/no-unsafe-call, @typescript-eslint/no-unsafe-member-access */
|
|
||||||
return (
|
|
||||||
state
|
|
||||||
// @ts-expect-error state.timelines is not yet typed
|
|
||||||
.getIn(['timelines', 'home', 'items'], ImmutableList())
|
|
||||||
// @ts-expect-error state.timelines is not yet typed
|
|
||||||
.find((item) => item !== null)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
function getLastNotificationId(state: RootState): string | undefined {
|
function getLastNotificationId(state: RootState): string | undefined {
|
||||||
// @ts-expect-error state.notifications is not yet typed
|
// @ts-expect-error state.notifications is not yet typed
|
||||||
|
// eslint-disable-next-line @typescript-eslint/no-unsafe-return, @typescript-eslint/no-unsafe-call
|
||||||
return state.getIn(['notifications', 'lastReadId']);
|
return state.getIn(['notifications', 'lastReadId']);
|
||||||
}
|
}
|
||||||
|
|
||||||
const buildPostMarkersParams = (state: RootState) => {
|
const buildPostMarkersParams = (state: RootState) => {
|
||||||
const params = {} as { home?: MarkerParam; notifications?: MarkerParam };
|
const params = {} as { home?: MarkerParam; notifications?: MarkerParam };
|
||||||
|
|
||||||
const lastHomeId = getLastHomeId(state);
|
|
||||||
const lastNotificationId = getLastNotificationId(state);
|
const lastNotificationId = getLastNotificationId(state);
|
||||||
|
|
||||||
if (lastHomeId && compareId(lastHomeId, state.markers.home) > 0) {
|
|
||||||
params.home = {
|
|
||||||
last_read_id: lastHomeId,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
if (
|
if (
|
||||||
lastNotificationId &&
|
lastNotificationId &&
|
||||||
compareId(lastNotificationId, state.markers.notifications) > 0
|
compareId(lastNotificationId, state.markers.notifications) > 0
|
||||||
|
@ -131,8 +112,8 @@ export const submitMarkersAction = createAppAsyncThunk<{
|
||||||
});
|
});
|
||||||
|
|
||||||
const debouncedSubmitMarkers = debounce(
|
const debouncedSubmitMarkers = debounce(
|
||||||
(dispatch) => {
|
(dispatch: AppDispatch) => {
|
||||||
dispatch(submitMarkersAction());
|
void dispatch(submitMarkersAction());
|
||||||
},
|
},
|
||||||
300000,
|
300000,
|
||||||
{
|
{
|
||||||
|
|
|
@ -1,17 +1,19 @@
|
||||||
import PropTypes from 'prop-types';
|
import PropTypes from 'prop-types';
|
||||||
|
import { useCallback } from 'react';
|
||||||
|
|
||||||
import { defineMessages, injectIntl, FormattedMessage } from 'react-intl';
|
import { defineMessages, useIntl, FormattedMessage } from 'react-intl';
|
||||||
|
|
||||||
import classNames from 'classnames';
|
import classNames from 'classnames';
|
||||||
import { Link } from 'react-router-dom';
|
import { Link } from 'react-router-dom';
|
||||||
|
|
||||||
import ImmutablePropTypes from 'react-immutable-proptypes';
|
import ImmutablePropTypes from 'react-immutable-proptypes';
|
||||||
import ImmutablePureComponent from 'react-immutable-pure-component';
|
|
||||||
|
|
||||||
|
import MoreHorizIcon from '@/material-icons/400-24px/more_horiz.svg?react';
|
||||||
import { EmptyAccount } from 'mastodon/components/empty_account';
|
import { EmptyAccount } from 'mastodon/components/empty_account';
|
||||||
import { ShortNumber } from 'mastodon/components/short_number';
|
import { ShortNumber } from 'mastodon/components/short_number';
|
||||||
import { VerifiedBadge } from 'mastodon/components/verified_badge';
|
import { VerifiedBadge } from 'mastodon/components/verified_badge';
|
||||||
|
|
||||||
|
import DropdownMenuContainer from '../containers/dropdown_menu_container';
|
||||||
import { me } from '../initial_state';
|
import { me } from '../initial_state';
|
||||||
|
|
||||||
import { Avatar } from './avatar';
|
import { Avatar } from './avatar';
|
||||||
|
@ -30,151 +32,151 @@ const messages = defineMessages({
|
||||||
unmute_notifications: { id: 'account.unmute_notifications_short', defaultMessage: 'Unmute notifications' },
|
unmute_notifications: { id: 'account.unmute_notifications_short', defaultMessage: 'Unmute notifications' },
|
||||||
mute: { id: 'account.mute_short', defaultMessage: 'Mute' },
|
mute: { id: 'account.mute_short', defaultMessage: 'Mute' },
|
||||||
block: { id: 'account.block_short', defaultMessage: 'Block' },
|
block: { id: 'account.block_short', defaultMessage: 'Block' },
|
||||||
|
more: { id: 'status.more', defaultMessage: 'More' },
|
||||||
});
|
});
|
||||||
|
|
||||||
class Account extends ImmutablePureComponent {
|
const Account = ({ size = 46, account, onFollow, onBlock, onMute, onMuteNotifications, hidden, minimal, defaultAction, withBio }) => {
|
||||||
|
const intl = useIntl();
|
||||||
|
|
||||||
static propTypes = {
|
const handleFollow = useCallback(() => {
|
||||||
size: PropTypes.number,
|
onFollow(account);
|
||||||
account: ImmutablePropTypes.record,
|
}, [onFollow, account]);
|
||||||
onFollow: PropTypes.func,
|
|
||||||
onBlock: PropTypes.func,
|
|
||||||
onMute: PropTypes.func,
|
|
||||||
onMuteNotifications: PropTypes.func,
|
|
||||||
intl: PropTypes.object.isRequired,
|
|
||||||
hidden: PropTypes.bool,
|
|
||||||
minimal: PropTypes.bool,
|
|
||||||
defaultAction: PropTypes.string,
|
|
||||||
withBio: PropTypes.bool,
|
|
||||||
};
|
|
||||||
|
|
||||||
static defaultProps = {
|
const handleBlock = useCallback(() => {
|
||||||
size: 46,
|
onBlock(account);
|
||||||
};
|
}, [onBlock, account]);
|
||||||
|
|
||||||
handleFollow = () => {
|
const handleMute = useCallback(() => {
|
||||||
this.props.onFollow(this.props.account);
|
onMute(account);
|
||||||
};
|
}, [onMute, account]);
|
||||||
|
|
||||||
handleBlock = () => {
|
const handleMuteNotifications = useCallback(() => {
|
||||||
this.props.onBlock(this.props.account);
|
onMuteNotifications(account, true);
|
||||||
};
|
}, [onMuteNotifications, account]);
|
||||||
|
|
||||||
handleMute = () => {
|
const handleUnmuteNotifications = useCallback(() => {
|
||||||
this.props.onMute(this.props.account);
|
onMuteNotifications(account, false);
|
||||||
};
|
}, [onMuteNotifications, account]);
|
||||||
|
|
||||||
handleMuteNotifications = () => {
|
if (!account) {
|
||||||
this.props.onMuteNotifications(this.props.account, true);
|
return <EmptyAccount size={size} minimal={minimal} />;
|
||||||
};
|
}
|
||||||
|
|
||||||
handleUnmuteNotifications = () => {
|
|
||||||
this.props.onMuteNotifications(this.props.account, false);
|
|
||||||
};
|
|
||||||
|
|
||||||
render () {
|
|
||||||
const { account, intl, hidden, withBio, defaultAction, size, minimal } = this.props;
|
|
||||||
|
|
||||||
if (!account) {
|
|
||||||
return <EmptyAccount size={size} minimal={minimal} />;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (hidden) {
|
|
||||||
return (
|
|
||||||
<>
|
|
||||||
{account.get('display_name')}
|
|
||||||
{account.get('username')}
|
|
||||||
</>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
let buttons;
|
|
||||||
|
|
||||||
if (account.get('id') !== me && account.get('relationship', null) !== null) {
|
|
||||||
const following = account.getIn(['relationship', 'following']);
|
|
||||||
const requested = account.getIn(['relationship', 'requested']);
|
|
||||||
const blocking = account.getIn(['relationship', 'blocking']);
|
|
||||||
const muting = account.getIn(['relationship', 'muting']);
|
|
||||||
|
|
||||||
if (requested) {
|
|
||||||
buttons = <Button text={intl.formatMessage(messages.cancel_follow_request)} onClick={this.handleFollow} />;
|
|
||||||
} else if (blocking) {
|
|
||||||
buttons = <Button text={intl.formatMessage(messages.unblock)} onClick={this.handleBlock} />;
|
|
||||||
} else if (muting) {
|
|
||||||
let hidingNotificationsButton;
|
|
||||||
|
|
||||||
if (account.getIn(['relationship', 'muting_notifications'])) {
|
|
||||||
hidingNotificationsButton = <Button text={intl.formatMessage(messages.unmute_notifications)} onClick={this.handleUnmuteNotifications} />;
|
|
||||||
} else {
|
|
||||||
hidingNotificationsButton = <Button text={intl.formatMessage(messages.mute_notifications)} onClick={this.handleMuteNotifications} />;
|
|
||||||
}
|
|
||||||
|
|
||||||
buttons = (
|
|
||||||
<>
|
|
||||||
<Button text={intl.formatMessage(messages.unmute)} onClick={this.handleMute} />
|
|
||||||
{hidingNotificationsButton}
|
|
||||||
</>
|
|
||||||
);
|
|
||||||
} else if (defaultAction === 'mute') {
|
|
||||||
buttons = <Button title={intl.formatMessage(messages.mute)} onClick={this.handleMute} />;
|
|
||||||
} else if (defaultAction === 'block') {
|
|
||||||
buttons = <Button text={intl.formatMessage(messages.block)} onClick={this.handleBlock} />;
|
|
||||||
} else if (!account.get('suspended') && !account.get('moved') || following) {
|
|
||||||
buttons = <Button text={intl.formatMessage(following ? messages.unfollow : messages.follow)} onClick={this.handleFollow} />;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
let muteTimeRemaining;
|
|
||||||
|
|
||||||
if (account.get('mute_expires_at')) {
|
|
||||||
muteTimeRemaining = <>· <RelativeTimestamp timestamp={account.get('mute_expires_at')} futureDate /></>;
|
|
||||||
}
|
|
||||||
|
|
||||||
let verification;
|
|
||||||
|
|
||||||
const firstVerifiedField = account.get('fields').find(item => !!item.get('verified_at'));
|
|
||||||
|
|
||||||
if (firstVerifiedField) {
|
|
||||||
verification = <VerifiedBadge link={firstVerifiedField.get('value')} />;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
if (hidden) {
|
||||||
return (
|
return (
|
||||||
<div className={classNames('account', { 'account--minimal': minimal })}>
|
<>
|
||||||
<div className='account__wrapper'>
|
{account.get('display_name')}
|
||||||
<Link key={account.get('id')} className='account__display-name' title={account.get('acct')} to={`/@${account.get('acct')}`}>
|
{account.get('username')}
|
||||||
<div className='account__avatar-wrapper'>
|
</>
|
||||||
<Avatar account={account} size={size} />
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div className='account__contents'>
|
|
||||||
<DisplayName account={account} />
|
|
||||||
{!minimal && (
|
|
||||||
<div className='account__details'>
|
|
||||||
<ShortNumber value={account.get('followers_count')} renderer={FollowersCounter} /> {verification} {muteTimeRemaining}
|
|
||||||
</div>
|
|
||||||
)}
|
|
||||||
</div>
|
|
||||||
</Link>
|
|
||||||
|
|
||||||
{!minimal && (
|
|
||||||
<div className='account__relationship'>
|
|
||||||
{buttons}
|
|
||||||
</div>
|
|
||||||
)}
|
|
||||||
</div>
|
|
||||||
|
|
||||||
{withBio && (account.get('note').length > 0 ? (
|
|
||||||
<div
|
|
||||||
className='account__note translate'
|
|
||||||
dangerouslySetInnerHTML={{ __html: account.get('note_emojified') }}
|
|
||||||
/>
|
|
||||||
) : (
|
|
||||||
<div className='account__note account__note--missing'><FormattedMessage id='account.no_bio' defaultMessage='No description provided.' /></div>
|
|
||||||
))}
|
|
||||||
</div>
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
let buttons;
|
||||||
|
|
||||||
export default injectIntl(Account);
|
if (account.get('id') !== me && account.get('relationship', null) !== null) {
|
||||||
|
const following = account.getIn(['relationship', 'following']);
|
||||||
|
const requested = account.getIn(['relationship', 'requested']);
|
||||||
|
const blocking = account.getIn(['relationship', 'blocking']);
|
||||||
|
const muting = account.getIn(['relationship', 'muting']);
|
||||||
|
|
||||||
|
if (requested) {
|
||||||
|
buttons = <Button text={intl.formatMessage(messages.cancel_follow_request)} onClick={handleFollow} />;
|
||||||
|
} else if (blocking) {
|
||||||
|
buttons = <Button text={intl.formatMessage(messages.unblock)} onClick={handleBlock} />;
|
||||||
|
} else if (muting) {
|
||||||
|
let menu;
|
||||||
|
|
||||||
|
if (account.getIn(['relationship', 'muting_notifications'])) {
|
||||||
|
menu = [{ text: intl.formatMessage(messages.unmute_notifications), action: handleUnmuteNotifications }];
|
||||||
|
} else {
|
||||||
|
menu = [{ text: intl.formatMessage(messages.mute_notifications), action: handleMuteNotifications }];
|
||||||
|
}
|
||||||
|
|
||||||
|
buttons = (
|
||||||
|
<>
|
||||||
|
<DropdownMenuContainer
|
||||||
|
items={menu}
|
||||||
|
icon='ellipsis-h'
|
||||||
|
iconComponent={MoreHorizIcon}
|
||||||
|
direction='right'
|
||||||
|
title={intl.formatMessage(messages.more)}
|
||||||
|
/>
|
||||||
|
|
||||||
|
<Button text={intl.formatMessage(messages.unmute)} onClick={handleMute} />
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
} else if (defaultAction === 'mute') {
|
||||||
|
buttons = <Button title={intl.formatMessage(messages.mute)} onClick={handleMute} />;
|
||||||
|
} else if (defaultAction === 'block') {
|
||||||
|
buttons = <Button text={intl.formatMessage(messages.block)} onClick={handleBlock} />;
|
||||||
|
} else if (!account.get('suspended') && !account.get('moved') || following) {
|
||||||
|
buttons = <Button text={intl.formatMessage(following ? messages.unfollow : messages.follow)} onClick={handleFollow} />;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let muteTimeRemaining;
|
||||||
|
|
||||||
|
if (account.get('mute_expires_at')) {
|
||||||
|
muteTimeRemaining = <>· <RelativeTimestamp timestamp={account.get('mute_expires_at')} futureDate /></>;
|
||||||
|
}
|
||||||
|
|
||||||
|
let verification;
|
||||||
|
|
||||||
|
const firstVerifiedField = account.get('fields').find(item => !!item.get('verified_at'));
|
||||||
|
|
||||||
|
if (firstVerifiedField) {
|
||||||
|
verification = <VerifiedBadge link={firstVerifiedField.get('value')} />;
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className={classNames('account', { 'account--minimal': minimal })}>
|
||||||
|
<div className='account__wrapper'>
|
||||||
|
<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>
|
||||||
|
|
||||||
|
<div className='account__contents'>
|
||||||
|
<DisplayName account={account} />
|
||||||
|
{!minimal && (
|
||||||
|
<div className='account__details'>
|
||||||
|
<ShortNumber value={account.get('followers_count')} renderer={FollowersCounter} /> {verification} {muteTimeRemaining}
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
</Link>
|
||||||
|
|
||||||
|
{!minimal && (
|
||||||
|
<div className='account__relationship'>
|
||||||
|
{buttons}
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{withBio && (account.get('note').length > 0 ? (
|
||||||
|
<div
|
||||||
|
className='account__note translate'
|
||||||
|
dangerouslySetInnerHTML={{ __html: account.get('note_emojified') }}
|
||||||
|
/>
|
||||||
|
) : (
|
||||||
|
<div className='account__note account__note--missing'><FormattedMessage id='account.no_bio' defaultMessage='No description provided.' /></div>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
Account.propTypes = {
|
||||||
|
size: PropTypes.number,
|
||||||
|
account: ImmutablePropTypes.record,
|
||||||
|
onFollow: PropTypes.func,
|
||||||
|
onBlock: PropTypes.func,
|
||||||
|
onMute: PropTypes.func,
|
||||||
|
onMuteNotifications: PropTypes.func,
|
||||||
|
intl: PropTypes.object.isRequired,
|
||||||
|
hidden: PropTypes.bool,
|
||||||
|
minimal: PropTypes.bool,
|
||||||
|
defaultAction: PropTypes.string,
|
||||||
|
withBio: PropTypes.bool,
|
||||||
|
};
|
||||||
|
|
||||||
|
export default Account;
|
||||||
|
|
|
@ -7,7 +7,7 @@ import PersonIcon from '@/material-icons/400-24px/person.svg?react';
|
||||||
import SmartToyIcon from '@/material-icons/400-24px/smart_toy.svg?react';
|
import SmartToyIcon from '@/material-icons/400-24px/smart_toy.svg?react';
|
||||||
|
|
||||||
|
|
||||||
export const Badge = ({ icon, label, domain, roleId }) => (
|
export const Badge = ({ icon = <PersonIcon />, label, domain, roleId }) => (
|
||||||
<div className='account-role' data-account-role-id={roleId}>
|
<div className='account-role' data-account-role-id={roleId}>
|
||||||
{icon}
|
{icon}
|
||||||
{label}
|
{label}
|
||||||
|
@ -22,10 +22,6 @@ Badge.propTypes = {
|
||||||
roleId: PropTypes.string
|
roleId: PropTypes.string
|
||||||
};
|
};
|
||||||
|
|
||||||
Badge.defaultProps = {
|
|
||||||
icon: <PersonIcon />,
|
|
||||||
};
|
|
||||||
|
|
||||||
export const GroupBadge = () => (
|
export const GroupBadge = () => (
|
||||||
<Badge icon={<GroupsIcon />} label={<FormattedMessage id='account.badges.group' defaultMessage='Group' />} />
|
<Badge icon={<GroupsIcon />} label={<FormattedMessage id='account.badges.group' defaultMessage='Group' />} />
|
||||||
);
|
);
|
||||||
|
|
|
@ -1,16 +1,16 @@
|
||||||
import PropTypes from 'prop-types';
|
import { useCallback } from 'react';
|
||||||
|
|
||||||
import { FormattedMessage } from 'react-intl';
|
import { FormattedMessage } from 'react-intl';
|
||||||
|
|
||||||
import ImmutablePropTypes from 'react-immutable-proptypes';
|
|
||||||
import ImmutablePureComponent from 'react-immutable-pure-component';
|
|
||||||
|
|
||||||
import FindInPageIcon from '@/material-icons/400-24px/find_in_page.svg?react';
|
import FindInPageIcon from '@/material-icons/400-24px/find_in_page.svg?react';
|
||||||
import PeopleIcon from '@/material-icons/400-24px/group.svg?react';
|
import PeopleIcon from '@/material-icons/400-24px/group.svg?react';
|
||||||
import TagIcon from '@/material-icons/400-24px/tag.svg?react';
|
import TagIcon from '@/material-icons/400-24px/tag.svg?react';
|
||||||
|
import { expandSearch } from 'mastodon/actions/search';
|
||||||
import { Icon } from 'mastodon/components/icon';
|
import { Icon } from 'mastodon/components/icon';
|
||||||
import { LoadMore } from 'mastodon/components/load_more';
|
import { LoadMore } from 'mastodon/components/load_more';
|
||||||
|
import { LoadingIndicator } from 'mastodon/components/loading_indicator';
|
||||||
import { SearchSection } from 'mastodon/features/explore/components/search_section';
|
import { SearchSection } from 'mastodon/features/explore/components/search_section';
|
||||||
|
import { useAppDispatch, useAppSelector } from 'mastodon/store';
|
||||||
|
|
||||||
import { ImmutableHashtag as Hashtag } from '../../../components/hashtag';
|
import { ImmutableHashtag as Hashtag } from '../../../components/hashtag';
|
||||||
import AccountContainer from '../../../containers/account_container';
|
import AccountContainer from '../../../containers/account_container';
|
||||||
|
@ -26,62 +26,68 @@ const withoutLastResult = list => {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
class SearchResults extends ImmutablePureComponent {
|
export const SearchResults = () => {
|
||||||
|
const results = useAppSelector((state) => state.getIn(['search', 'results']));
|
||||||
|
const isLoading = useAppSelector((state) => state.getIn(['search', 'isLoading']));
|
||||||
|
|
||||||
static propTypes = {
|
const dispatch = useAppDispatch();
|
||||||
results: ImmutablePropTypes.map.isRequired,
|
|
||||||
expandSearch: PropTypes.func.isRequired,
|
|
||||||
searchTerm: PropTypes.string,
|
|
||||||
};
|
|
||||||
|
|
||||||
handleLoadMoreAccounts = () => this.props.expandSearch('accounts');
|
const handleLoadMoreAccounts = useCallback(() => {
|
||||||
|
dispatch(expandSearch('accounts'));
|
||||||
|
}, [dispatch]);
|
||||||
|
|
||||||
handleLoadMoreStatuses = () => this.props.expandSearch('statuses');
|
const handleLoadMoreStatuses = useCallback(() => {
|
||||||
|
dispatch(expandSearch('statuses'));
|
||||||
|
}, [dispatch]);
|
||||||
|
|
||||||
handleLoadMoreHashtags = () => this.props.expandSearch('hashtags');
|
const handleLoadMoreHashtags = useCallback(() => {
|
||||||
|
dispatch(expandSearch('hashtags'));
|
||||||
|
}, [dispatch]);
|
||||||
|
|
||||||
render () {
|
let accounts, statuses, hashtags;
|
||||||
const { results } = this.props;
|
|
||||||
|
|
||||||
let accounts, statuses, hashtags;
|
if (results.get('accounts') && results.get('accounts').size > 0) {
|
||||||
|
accounts = (
|
||||||
if (results.get('accounts') && results.get('accounts').size > 0) {
|
<SearchSection title={<><Icon id='users' icon={PeopleIcon} /><FormattedMessage id='search_results.accounts' defaultMessage='Profiles' /></>}>
|
||||||
accounts = (
|
{withoutLastResult(results.get('accounts')).map(accountId => <AccountContainer key={accountId} id={accountId} />)}
|
||||||
<SearchSection title={<><Icon id='users' icon={PeopleIcon} /><FormattedMessage id='search_results.accounts' defaultMessage='Profiles' /></>}>
|
{(results.get('accounts').size > INITIAL_PAGE_LIMIT && results.get('accounts').size % INITIAL_PAGE_LIMIT === 1) && <LoadMore visible onClick={handleLoadMoreAccounts} />}
|
||||||
{withoutLastResult(results.get('accounts')).map(accountId => <AccountContainer key={accountId} id={accountId} />)}
|
</SearchSection>
|
||||||
{(results.get('accounts').size > INITIAL_PAGE_LIMIT && results.get('accounts').size % INITIAL_PAGE_LIMIT === 1) && <LoadMore visible onClick={this.handleLoadMoreAccounts} />}
|
|
||||||
</SearchSection>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (results.get('hashtags') && results.get('hashtags').size > 0) {
|
|
||||||
hashtags = (
|
|
||||||
<SearchSection title={<><Icon id='hashtag' icon={TagIcon} /><FormattedMessage id='search_results.hashtags' defaultMessage='Hashtags' /></>}>
|
|
||||||
{withoutLastResult(results.get('hashtags')).map(hashtag => <Hashtag key={hashtag.get('name')} hashtag={hashtag} />)}
|
|
||||||
{(results.get('hashtags').size > INITIAL_PAGE_LIMIT && results.get('hashtags').size % INITIAL_PAGE_LIMIT === 1) && <LoadMore visible onClick={this.handleLoadMoreHashtags} />}
|
|
||||||
</SearchSection>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (results.get('statuses') && results.get('statuses').size > 0) {
|
|
||||||
statuses = (
|
|
||||||
<SearchSection title={<><Icon id='quote-right' icon={FindInPageIcon} /><FormattedMessage id='search_results.statuses' defaultMessage='Posts' /></>}>
|
|
||||||
{withoutLastResult(results.get('statuses')).map(statusId => <StatusContainer key={statusId} id={statusId} />)}
|
|
||||||
{(results.get('statuses').size > INITIAL_PAGE_LIMIT && results.get('statuses').size % INITIAL_PAGE_LIMIT === 1) && <LoadMore visible onClick={this.handleLoadMoreStatuses} />}
|
|
||||||
</SearchSection>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
return (
|
|
||||||
<div className='search-results'>
|
|
||||||
{accounts}
|
|
||||||
{hashtags}
|
|
||||||
{statuses}
|
|
||||||
</div>
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
if (results.get('hashtags') && results.get('hashtags').size > 0) {
|
||||||
|
hashtags = (
|
||||||
|
<SearchSection title={<><Icon id='hashtag' icon={TagIcon} /><FormattedMessage id='search_results.hashtags' defaultMessage='Hashtags' /></>}>
|
||||||
|
{withoutLastResult(results.get('hashtags')).map(hashtag => <Hashtag key={hashtag.get('name')} hashtag={hashtag} />)}
|
||||||
|
{(results.get('hashtags').size > INITIAL_PAGE_LIMIT && results.get('hashtags').size % INITIAL_PAGE_LIMIT === 1) && <LoadMore visible onClick={handleLoadMoreHashtags} />}
|
||||||
|
</SearchSection>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
export default SearchResults;
|
if (results.get('statuses') && results.get('statuses').size > 0) {
|
||||||
|
statuses = (
|
||||||
|
<SearchSection title={<><Icon id='quote-right' icon={FindInPageIcon} /><FormattedMessage id='search_results.statuses' defaultMessage='Posts' /></>}>
|
||||||
|
{withoutLastResult(results.get('statuses')).map(statusId => <StatusContainer key={statusId} id={statusId} />)}
|
||||||
|
{(results.get('statuses').size > INITIAL_PAGE_LIMIT && results.get('statuses').size % INITIAL_PAGE_LIMIT === 1) && <LoadMore visible onClick={handleLoadMoreStatuses} />}
|
||||||
|
</SearchSection>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className='search-results'>
|
||||||
|
{!accounts && !hashtags && !statuses && (
|
||||||
|
isLoading ? (
|
||||||
|
<LoadingIndicator />
|
||||||
|
) : (
|
||||||
|
<div className='empty-column-indicator'>
|
||||||
|
<FormattedMessage id='search_results.nothing_found' defaultMessage='Could not find anything for these search terms' />
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
)}
|
||||||
|
{accounts}
|
||||||
|
{hashtags}
|
||||||
|
{statuses}
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
|
||||||
|
};
|
||||||
|
|
|
@ -1,20 +0,0 @@
|
||||||
import { connect } from 'react-redux';
|
|
||||||
|
|
||||||
import { expandSearch } from 'mastodon/actions/search';
|
|
||||||
import { fetchSuggestions, dismissSuggestion } from 'mastodon/actions/suggestions';
|
|
||||||
|
|
||||||
import SearchResults from '../components/search_results';
|
|
||||||
|
|
||||||
const mapStateToProps = state => ({
|
|
||||||
results: state.getIn(['search', 'results']),
|
|
||||||
suggestions: state.getIn(['suggestions', 'items']),
|
|
||||||
searchTerm: state.getIn(['search', 'searchTerm']),
|
|
||||||
});
|
|
||||||
|
|
||||||
const mapDispatchToProps = dispatch => ({
|
|
||||||
fetchSuggestions: () => dispatch(fetchSuggestions()),
|
|
||||||
expandSearch: type => dispatch(expandSearch(type)),
|
|
||||||
dismissSuggestion: account => dispatch(dismissSuggestion(account.get('id'))),
|
|
||||||
});
|
|
||||||
|
|
||||||
export default connect(mapStateToProps, mapDispatchToProps)(SearchResults);
|
|
|
@ -29,9 +29,9 @@ import { mascot } from '../../initial_state';
|
||||||
import { isMobile } from '../../is_mobile';
|
import { isMobile } from '../../is_mobile';
|
||||||
import Motion from '../ui/util/optional_motion';
|
import Motion from '../ui/util/optional_motion';
|
||||||
|
|
||||||
|
import { SearchResults } from './components/search_results';
|
||||||
import ComposeFormContainer from './containers/compose_form_container';
|
import ComposeFormContainer from './containers/compose_form_container';
|
||||||
import SearchContainer from './containers/search_container';
|
import SearchContainer from './containers/search_container';
|
||||||
import SearchResultsContainer from './containers/search_results_container';
|
|
||||||
|
|
||||||
const messages = defineMessages({
|
const messages = defineMessages({
|
||||||
start: { id: 'getting_started.heading', defaultMessage: 'Getting started' },
|
start: { id: 'getting_started.heading', defaultMessage: 'Getting started' },
|
||||||
|
@ -138,7 +138,7 @@ class Compose extends PureComponent {
|
||||||
<Motion defaultStyle={{ x: -100 }} style={{ x: spring(showSearch ? 0 : -100, { stiffness: 210, damping: 20 }) }}>
|
<Motion defaultStyle={{ x: -100 }} style={{ x: spring(showSearch ? 0 : -100, { stiffness: 210, damping: 20 }) }}>
|
||||||
{({ x }) => (
|
{({ x }) => (
|
||||||
<div className='drawer__inner darker' style={{ transform: `translateX(${x}%)`, visibility: x === -100 ? 'hidden' : 'visible' }}>
|
<div className='drawer__inner darker' style={{ transform: `translateX(${x}%)`, visibility: x === -100 ? 'hidden' : 'visible' }}>
|
||||||
<SearchResultsContainer />
|
<SearchResults />
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
</Motion>
|
</Motion>
|
||||||
|
|
88
app/javascript/mastodon/features/explore/components/card.jsx
Normal file
88
app/javascript/mastodon/features/explore/components/card.jsx
Normal file
|
@ -0,0 +1,88 @@
|
||||||
|
import PropTypes from 'prop-types';
|
||||||
|
import { useCallback } from 'react';
|
||||||
|
|
||||||
|
import { FormattedMessage, useIntl, defineMessages } from 'react-intl';
|
||||||
|
|
||||||
|
import { Link } from 'react-router-dom';
|
||||||
|
|
||||||
|
import { useDispatch, useSelector } from 'react-redux';
|
||||||
|
|
||||||
|
import CloseIcon from '@/material-icons/400-24px/close.svg?react';
|
||||||
|
import { followAccount, unfollowAccount } from 'mastodon/actions/accounts';
|
||||||
|
import { dismissSuggestion } from 'mastodon/actions/suggestions';
|
||||||
|
import { Avatar } from 'mastodon/components/avatar';
|
||||||
|
import { Button } from 'mastodon/components/button';
|
||||||
|
import { DisplayName } from 'mastodon/components/display_name';
|
||||||
|
import { IconButton } from 'mastodon/components/icon_button';
|
||||||
|
import { domain } from 'mastodon/initial_state';
|
||||||
|
|
||||||
|
const messages = defineMessages({
|
||||||
|
follow: { id: 'account.follow', defaultMessage: 'Follow' },
|
||||||
|
unfollow: { id: 'account.unfollow', defaultMessage: 'Unfollow' },
|
||||||
|
dismiss: { id: 'follow_suggestions.dismiss', defaultMessage: "Don't show again" },
|
||||||
|
});
|
||||||
|
|
||||||
|
export const Card = ({ id, source }) => {
|
||||||
|
const intl = useIntl();
|
||||||
|
const account = useSelector(state => state.getIn(['accounts', id]));
|
||||||
|
const relationship = useSelector(state => state.getIn(['relationships', id]));
|
||||||
|
const dispatch = useDispatch();
|
||||||
|
const following = relationship?.get('following') ?? relationship?.get('requested');
|
||||||
|
|
||||||
|
const handleFollow = useCallback(() => {
|
||||||
|
if (following) {
|
||||||
|
dispatch(unfollowAccount(id));
|
||||||
|
} else {
|
||||||
|
dispatch(followAccount(id));
|
||||||
|
}
|
||||||
|
}, [id, following, dispatch]);
|
||||||
|
|
||||||
|
const handleDismiss = useCallback(() => {
|
||||||
|
dispatch(dismissSuggestion(id));
|
||||||
|
}, [id, dispatch]);
|
||||||
|
|
||||||
|
let label;
|
||||||
|
|
||||||
|
switch (source) {
|
||||||
|
case 'friends_of_friends':
|
||||||
|
label = <FormattedMessage id='follow_suggestions.friends_of_friends_longer' defaultMessage='Popular among people you follow' />;
|
||||||
|
break;
|
||||||
|
case 'similar_to_recently_followed':
|
||||||
|
label = <FormattedMessage id='follow_suggestions.similar_to_recently_followed_longer' defaultMessage='Similar to profiles you recently followed' />;
|
||||||
|
break;
|
||||||
|
case 'featured':
|
||||||
|
label = <FormattedMessage id='follow_suggestions.featured_longer' defaultMessage='Hand-picked by the {domain} team' values={{ domain }} />;
|
||||||
|
break;
|
||||||
|
case 'most_followed':
|
||||||
|
label = <FormattedMessage id='follow_suggestions.popular_suggestion_longer' defaultMessage='Popular on {domain}' values={{ domain }} />;
|
||||||
|
break;
|
||||||
|
case 'most_interactions':
|
||||||
|
label = <FormattedMessage id='follow_suggestions.popular_suggestion_longer' defaultMessage='Popular on {domain}' values={{ domain }} />;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className='explore__suggestions__card'>
|
||||||
|
<div className='explore__suggestions__card__source'>
|
||||||
|
{label}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className='explore__suggestions__card__body'>
|
||||||
|
<Link to={`/@${account.get('acct')}`}><Avatar account={account} size={48} /></Link>
|
||||||
|
|
||||||
|
<div className='explore__suggestions__card__body__main'>
|
||||||
|
<div className='explore__suggestions__card__body__main__name-button'>
|
||||||
|
<Link className='explore__suggestions__card__body__main__name-button__name' to={`/@${account.get('acct')}`}><DisplayName account={account} /></Link>
|
||||||
|
<IconButton iconComponent={CloseIcon} onClick={handleDismiss} title={intl.formatMessage(messages.dismiss)} />
|
||||||
|
<Button text={intl.formatMessage(following ? messages.unfollow : messages.follow)} secondary={following} onClick={handleFollow} />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
Card.propTypes = {
|
||||||
|
id: PropTypes.string.isRequired,
|
||||||
|
source: PropTypes.oneOf(['friends_of_friends', 'similar_to_recently_followed', 'featured', 'most_followed', 'most_interactions']),
|
||||||
|
};
|
|
@ -10,9 +10,10 @@ import { connect } from 'react-redux';
|
||||||
|
|
||||||
import { fetchSuggestions } from 'mastodon/actions/suggestions';
|
import { fetchSuggestions } from 'mastodon/actions/suggestions';
|
||||||
import { LoadingIndicator } from 'mastodon/components/loading_indicator';
|
import { LoadingIndicator } from 'mastodon/components/loading_indicator';
|
||||||
import AccountCard from 'mastodon/features/directory/components/account_card';
|
|
||||||
import { WithRouterPropTypes } from 'mastodon/utils/react_router';
|
import { WithRouterPropTypes } from 'mastodon/utils/react_router';
|
||||||
|
|
||||||
|
import { Card } from './components/card';
|
||||||
|
|
||||||
const mapStateToProps = state => ({
|
const mapStateToProps = state => ({
|
||||||
suggestions: state.getIn(['suggestions', 'items']),
|
suggestions: state.getIn(['suggestions', 'items']),
|
||||||
isLoading: state.getIn(['suggestions', 'isLoading']),
|
isLoading: state.getIn(['suggestions', 'isLoading']),
|
||||||
|
@ -54,7 +55,11 @@ class Suggestions extends PureComponent {
|
||||||
return (
|
return (
|
||||||
<div className='explore__suggestions scrollable' data-nosnippet>
|
<div className='explore__suggestions scrollable' data-nosnippet>
|
||||||
{isLoading ? <LoadingIndicator /> : suggestions.map(suggestion => (
|
{isLoading ? <LoadingIndicator /> : suggestions.map(suggestion => (
|
||||||
<AccountCard key={suggestion.get('account')} id={suggestion.get('account')} />
|
<Card
|
||||||
|
key={suggestion.get('account')}
|
||||||
|
id={suggestion.get('account')}
|
||||||
|
source={suggestion.getIn(['sources', 0])}
|
||||||
|
/>
|
||||||
))}
|
))}
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
|
|
@ -0,0 +1,78 @@
|
||||||
|
import { defineMessages, FormattedMessage, useIntl } from 'react-intl';
|
||||||
|
|
||||||
|
import GavelIcon from '@/material-icons/400-24px/gavel.svg?react';
|
||||||
|
import { Icon } from 'mastodon/components/icon';
|
||||||
|
|
||||||
|
// This needs to be kept in sync with app/models/account_warning.rb
|
||||||
|
const messages = defineMessages({
|
||||||
|
none: {
|
||||||
|
id: 'notification.moderation_warning.action_none',
|
||||||
|
defaultMessage: 'Your account has received a moderation warning.',
|
||||||
|
},
|
||||||
|
disable: {
|
||||||
|
id: 'notification.moderation_warning.action_disable',
|
||||||
|
defaultMessage: 'Your account has been disabled.',
|
||||||
|
},
|
||||||
|
mark_statuses_as_sensitive: {
|
||||||
|
id: 'notification.moderation_warning.action_mark_statuses_as_sensitive',
|
||||||
|
defaultMessage: 'Some of your posts have been marked as sensitive.',
|
||||||
|
},
|
||||||
|
delete_statuses: {
|
||||||
|
id: 'notification.moderation_warning.action_delete_statuses',
|
||||||
|
defaultMessage: 'Some of your posts have been removed.',
|
||||||
|
},
|
||||||
|
sensitive: {
|
||||||
|
id: 'notification.moderation_warning.action_sensitive',
|
||||||
|
defaultMessage: 'Your posts will be marked as sensitive from now on.',
|
||||||
|
},
|
||||||
|
silence: {
|
||||||
|
id: 'notification.moderation_warning.action_silence',
|
||||||
|
defaultMessage: 'Your account has been limited.',
|
||||||
|
},
|
||||||
|
suspend: {
|
||||||
|
id: 'notification.moderation_warning.action_suspend',
|
||||||
|
defaultMessage: 'Your account has been suspended.',
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
interface Props {
|
||||||
|
action:
|
||||||
|
| 'none'
|
||||||
|
| 'disable'
|
||||||
|
| 'mark_statuses_as_sensitive'
|
||||||
|
| 'delete_statuses'
|
||||||
|
| 'sensitive'
|
||||||
|
| 'silence'
|
||||||
|
| 'suspend';
|
||||||
|
id: string;
|
||||||
|
hidden: boolean;
|
||||||
|
}
|
||||||
|
|
||||||
|
export const ModerationWarning: React.FC<Props> = ({ action, id, hidden }) => {
|
||||||
|
const intl = useIntl();
|
||||||
|
|
||||||
|
if (hidden) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<a
|
||||||
|
href={`/disputes/strikes/${id}`}
|
||||||
|
target='_blank'
|
||||||
|
rel='noopener noreferrer'
|
||||||
|
className='notification__moderation-warning'
|
||||||
|
>
|
||||||
|
<Icon id='warning' icon={GavelIcon} />
|
||||||
|
|
||||||
|
<div className='notification__moderation-warning__content'>
|
||||||
|
<p>{intl.formatMessage(messages[action])}</p>
|
||||||
|
<span className='link-button'>
|
||||||
|
<FormattedMessage
|
||||||
|
id='notification.moderation-warning.learn_more'
|
||||||
|
defaultMessage='Learn more'
|
||||||
|
/>
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
</a>
|
||||||
|
);
|
||||||
|
};
|
|
@ -26,6 +26,7 @@ import { WithRouterPropTypes } from 'mastodon/utils/react_router';
|
||||||
|
|
||||||
import FollowRequestContainer from '../containers/follow_request_container';
|
import FollowRequestContainer from '../containers/follow_request_container';
|
||||||
|
|
||||||
|
import { ModerationWarning } from './moderation_warning';
|
||||||
import { RelationshipsSeveranceEvent } from './relationships_severance_event';
|
import { RelationshipsSeveranceEvent } from './relationships_severance_event';
|
||||||
import Report from './report';
|
import Report from './report';
|
||||||
|
|
||||||
|
@ -40,6 +41,7 @@ const messages = defineMessages({
|
||||||
adminSignUp: { id: 'notification.admin.sign_up', defaultMessage: '{name} signed up' },
|
adminSignUp: { id: 'notification.admin.sign_up', defaultMessage: '{name} signed up' },
|
||||||
adminReport: { id: 'notification.admin.report', defaultMessage: '{name} reported {target}' },
|
adminReport: { id: 'notification.admin.report', defaultMessage: '{name} reported {target}' },
|
||||||
relationshipsSevered: { id: 'notification.relationships_severance_event', defaultMessage: 'Lost connections with {name}' },
|
relationshipsSevered: { id: 'notification.relationships_severance_event', defaultMessage: 'Lost connections with {name}' },
|
||||||
|
moderationWarning: { id: 'notification.moderation_warning', defaultMessage: 'Your have received a moderation warning' },
|
||||||
});
|
});
|
||||||
|
|
||||||
const notificationForScreenReader = (intl, message, timestamp) => {
|
const notificationForScreenReader = (intl, message, timestamp) => {
|
||||||
|
@ -383,6 +385,27 @@ class Notification extends ImmutablePureComponent {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
renderModerationWarning (notification) {
|
||||||
|
const { intl, unread, hidden } = this.props;
|
||||||
|
const warning = notification.get('moderation_warning');
|
||||||
|
|
||||||
|
if (!warning) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<HotKeys handlers={this.getHandlers()}>
|
||||||
|
<div className={classNames('notification notification-moderation-warning focusable', { unread })} tabIndex={0} aria-label={notificationForScreenReader(intl, intl.formatMessage(messages.moderationWarning), notification.get('created_at'))}>
|
||||||
|
<ModerationWarning
|
||||||
|
action={warning.get('action')}
|
||||||
|
id={warning.get('id')}
|
||||||
|
hidden={hidden}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</HotKeys>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
renderAdminSignUp (notification, account, link) {
|
renderAdminSignUp (notification, account, link) {
|
||||||
const { intl, unread } = this.props;
|
const { intl, unread } = this.props;
|
||||||
|
|
||||||
|
@ -456,6 +479,8 @@ class Notification extends ImmutablePureComponent {
|
||||||
return this.renderPoll(notification, account);
|
return this.renderPoll(notification, account);
|
||||||
case 'severed_relationships':
|
case 'severed_relationships':
|
||||||
return this.renderRelationshipsSevered(notification);
|
return this.renderRelationshipsSevered(notification);
|
||||||
|
case 'moderation_warning':
|
||||||
|
return this.renderModerationWarning(notification);
|
||||||
case 'admin.sign_up':
|
case 'admin.sign_up':
|
||||||
return this.renderAdminSignUp(notification, account, link);
|
return this.renderAdminSignUp(notification, account, link);
|
||||||
case 'admin.report':
|
case 'admin.report':
|
||||||
|
|
|
@ -297,6 +297,7 @@
|
||||||
"filter_modal.select_filter.subtitle": "Изберете съществуваща категория или създайте нова",
|
"filter_modal.select_filter.subtitle": "Изберете съществуваща категория или създайте нова",
|
||||||
"filter_modal.select_filter.title": "Филтриране на публ.",
|
"filter_modal.select_filter.title": "Филтриране на публ.",
|
||||||
"filter_modal.title.status": "Филтриране на публ.",
|
"filter_modal.title.status": "Филтриране на публ.",
|
||||||
|
"filtered_notifications_banner.mentions": "{count, plural, one {споменаване} other {споменавания}}",
|
||||||
"filtered_notifications_banner.pending_requests": "Известията от {count, plural, =0 {никого, когото може да познавате} one {едно лице, което може да познавате} other {# души, които може да познавате}}",
|
"filtered_notifications_banner.pending_requests": "Известията от {count, plural, =0 {никого, когото може да познавате} one {едно лице, което може да познавате} other {# души, които може да познавате}}",
|
||||||
"filtered_notifications_banner.title": "Филтрирани известия",
|
"filtered_notifications_banner.title": "Филтрирани известия",
|
||||||
"firehose.all": "Всичко",
|
"firehose.all": "Всичко",
|
||||||
|
@ -307,6 +308,8 @@
|
||||||
"follow_requests.unlocked_explanation": "Въпреки че акаунтът ви не е заключен, служителите на {domain} помислиха, че може да искате да преглеждате ръчно заявките за последване на тези профили.",
|
"follow_requests.unlocked_explanation": "Въпреки че акаунтът ви не е заключен, служителите на {domain} помислиха, че може да искате да преглеждате ръчно заявките за последване на тези профили.",
|
||||||
"follow_suggestions.curated_suggestion": "Избор на персонал",
|
"follow_suggestions.curated_suggestion": "Избор на персонал",
|
||||||
"follow_suggestions.dismiss": "Без ново показване",
|
"follow_suggestions.dismiss": "Без ново показване",
|
||||||
|
"follow_suggestions.featured_longer": "Ръчно избрано от отбора на {domain}",
|
||||||
|
"follow_suggestions.friends_of_friends_longer": "Популярно измежду хората, които следвате",
|
||||||
"follow_suggestions.hints.featured": "Този профил е ръчно подбран от отбора на {domain}.",
|
"follow_suggestions.hints.featured": "Този профил е ръчно подбран от отбора на {domain}.",
|
||||||
"follow_suggestions.hints.friends_of_friends": "Този профил е популярен измежду хората, които следвате.",
|
"follow_suggestions.hints.friends_of_friends": "Този профил е популярен измежду хората, които следвате.",
|
||||||
"follow_suggestions.hints.most_followed": "Този профил е един от най-следваните при {domain}.",
|
"follow_suggestions.hints.most_followed": "Този профил е един от най-следваните при {domain}.",
|
||||||
|
@ -314,6 +317,8 @@
|
||||||
"follow_suggestions.hints.similar_to_recently_followed": "Този профил е подобен на профилите, които сте последвали наскоро.",
|
"follow_suggestions.hints.similar_to_recently_followed": "Този профил е подобен на профилите, които сте последвали наскоро.",
|
||||||
"follow_suggestions.personalized_suggestion": "Персонализирано предложение",
|
"follow_suggestions.personalized_suggestion": "Персонализирано предложение",
|
||||||
"follow_suggestions.popular_suggestion": "Популярно предложение",
|
"follow_suggestions.popular_suggestion": "Популярно предложение",
|
||||||
|
"follow_suggestions.popular_suggestion_longer": "Популярно из {domain}",
|
||||||
|
"follow_suggestions.similar_to_recently_followed_longer": "Подобни на профилите, които наскоро сте последвали",
|
||||||
"follow_suggestions.view_all": "Преглед на всички",
|
"follow_suggestions.view_all": "Преглед на всички",
|
||||||
"follow_suggestions.who_to_follow": "Кого да се следва",
|
"follow_suggestions.who_to_follow": "Кого да се следва",
|
||||||
"followed_tags": "Последвани хаштагове",
|
"followed_tags": "Последвани хаштагове",
|
||||||
|
@ -468,6 +473,15 @@
|
||||||
"notification.follow": "{name} ви последва",
|
"notification.follow": "{name} ви последва",
|
||||||
"notification.follow_request": "{name} поиска да ви последва",
|
"notification.follow_request": "{name} поиска да ви последва",
|
||||||
"notification.mention": "{name} ви спомена",
|
"notification.mention": "{name} ви спомена",
|
||||||
|
"notification.moderation-warning.learn_more": "Научете повече",
|
||||||
|
"notification.moderation_warning": "Получихте предупреждение за модериране",
|
||||||
|
"notification.moderation_warning.action_delete_statuses": "Някои от публикациите ви са премахнати.",
|
||||||
|
"notification.moderation_warning.action_disable": "Вашият акаунт е изключен.",
|
||||||
|
"notification.moderation_warning.action_mark_statuses_as_sensitive": "Някои от публикациите ви са означени като деликатни.",
|
||||||
|
"notification.moderation_warning.action_none": "Акаунтът ви получи предупреждение за модериране.",
|
||||||
|
"notification.moderation_warning.action_sensitive": "Публикациите ви ще се означават като деликатни от сега нататък.",
|
||||||
|
"notification.moderation_warning.action_silence": "Вашият акаунт е ограничен.",
|
||||||
|
"notification.moderation_warning.action_suspend": "Вашият акаунт е спрян.",
|
||||||
"notification.own_poll": "Анкетата ви приключи",
|
"notification.own_poll": "Анкетата ви приключи",
|
||||||
"notification.poll": "Анкета, в която гласувахте, приключи",
|
"notification.poll": "Анкета, в която гласувахте, приключи",
|
||||||
"notification.reblog": "{name} подсили ваша публикация",
|
"notification.reblog": "{name} подсили ваша публикация",
|
||||||
|
|
|
@ -263,6 +263,8 @@
|
||||||
"follow_request.authorize": "Aotren",
|
"follow_request.authorize": "Aotren",
|
||||||
"follow_request.reject": "Nac'hañ",
|
"follow_request.reject": "Nac'hañ",
|
||||||
"follow_requests.unlocked_explanation": "Daoust ma n'eo ket ho kont prennet, skipailh {domain} a soñj e fellfe deoc'h gwiriekaat pedadennoù heuliañ deus ar c'hontoù-se diwar-zorn.",
|
"follow_requests.unlocked_explanation": "Daoust ma n'eo ket ho kont prennet, skipailh {domain} a soñj e fellfe deoc'h gwiriekaat pedadennoù heuliañ deus ar c'hontoù-se diwar-zorn.",
|
||||||
|
"follow_suggestions.friends_of_friends_longer": "Diouzh ar c'hiz e-touez an dud heuliet ganeoc'h",
|
||||||
|
"follow_suggestions.popular_suggestion_longer": "Diouzh ar c'hiz war {domain}",
|
||||||
"follow_suggestions.view_all": "Gwelet pep tra",
|
"follow_suggestions.view_all": "Gwelet pep tra",
|
||||||
"followed_tags": "Hashtagoù o heuliañ",
|
"followed_tags": "Hashtagoù o heuliañ",
|
||||||
"footer.about": "Diwar-benn",
|
"footer.about": "Diwar-benn",
|
||||||
|
@ -395,6 +397,7 @@
|
||||||
"notification.follow": "heuliañ a ra {name} ac'hanoc'h",
|
"notification.follow": "heuliañ a ra {name} ac'hanoc'h",
|
||||||
"notification.follow_request": "Gant {name} eo bet goulennet ho heuliañ",
|
"notification.follow_request": "Gant {name} eo bet goulennet ho heuliañ",
|
||||||
"notification.mention": "Gant {name} oc'h bet meneget",
|
"notification.mention": "Gant {name} oc'h bet meneget",
|
||||||
|
"notification.moderation-warning.learn_more": "Gouzout hiroc'h",
|
||||||
"notification.own_poll": "Echu eo ho sontadeg",
|
"notification.own_poll": "Echu eo ho sontadeg",
|
||||||
"notification.poll": "Ur sontadeg ho deus mouezhet warnañ a zo echuet",
|
"notification.poll": "Ur sontadeg ho deus mouezhet warnañ a zo echuet",
|
||||||
"notification.reblog": "Gant {name} eo bet skignet ho toud",
|
"notification.reblog": "Gant {name} eo bet skignet ho toud",
|
||||||
|
|
|
@ -308,6 +308,8 @@
|
||||||
"follow_requests.unlocked_explanation": "Tot i que el teu compte no està blocat, el personal de {domain} ha pensat que és possible que vulguis revisar manualment les sol·licituds de seguiment d’aquests comptes.",
|
"follow_requests.unlocked_explanation": "Tot i que el teu compte no està blocat, el personal de {domain} ha pensat que és possible que vulguis revisar manualment les sol·licituds de seguiment d’aquests comptes.",
|
||||||
"follow_suggestions.curated_suggestion": "Tria de l'equip",
|
"follow_suggestions.curated_suggestion": "Tria de l'equip",
|
||||||
"follow_suggestions.dismiss": "No ho tornis a mostrar",
|
"follow_suggestions.dismiss": "No ho tornis a mostrar",
|
||||||
|
"follow_suggestions.featured_longer": "Triat personalment per l'equip de {domain}",
|
||||||
|
"follow_suggestions.friends_of_friends_longer": "Popular entre la gent que segueixes",
|
||||||
"follow_suggestions.hints.featured": "L'equip de {domain} ha seleccionat aquest perfil.",
|
"follow_suggestions.hints.featured": "L'equip de {domain} ha seleccionat aquest perfil.",
|
||||||
"follow_suggestions.hints.friends_of_friends": "Aquest perfil és popular entre la gent que seguiu.",
|
"follow_suggestions.hints.friends_of_friends": "Aquest perfil és popular entre la gent que seguiu.",
|
||||||
"follow_suggestions.hints.most_followed": "Aquest perfil és un dels més seguits a {domain}.",
|
"follow_suggestions.hints.most_followed": "Aquest perfil és un dels més seguits a {domain}.",
|
||||||
|
@ -315,6 +317,8 @@
|
||||||
"follow_suggestions.hints.similar_to_recently_followed": "Aquest perfil és similar a d'altres que heu seguit recentment.",
|
"follow_suggestions.hints.similar_to_recently_followed": "Aquest perfil és similar a d'altres que heu seguit recentment.",
|
||||||
"follow_suggestions.personalized_suggestion": "Suggeriment personalitzat",
|
"follow_suggestions.personalized_suggestion": "Suggeriment personalitzat",
|
||||||
"follow_suggestions.popular_suggestion": "Suggeriment popular",
|
"follow_suggestions.popular_suggestion": "Suggeriment popular",
|
||||||
|
"follow_suggestions.popular_suggestion_longer": "Popular a {domain}",
|
||||||
|
"follow_suggestions.similar_to_recently_followed_longer": "Semblant a perfils que seguiu fa poc",
|
||||||
"follow_suggestions.view_all": "Mostra-ho tot",
|
"follow_suggestions.view_all": "Mostra-ho tot",
|
||||||
"follow_suggestions.who_to_follow": "A qui seguir",
|
"follow_suggestions.who_to_follow": "A qui seguir",
|
||||||
"followed_tags": "Etiquetes seguides",
|
"followed_tags": "Etiquetes seguides",
|
||||||
|
@ -469,6 +473,14 @@
|
||||||
"notification.follow": "{name} et segueix",
|
"notification.follow": "{name} et segueix",
|
||||||
"notification.follow_request": "{name} ha sol·licitat de seguir-te",
|
"notification.follow_request": "{name} ha sol·licitat de seguir-te",
|
||||||
"notification.mention": "{name} t'ha esmentat",
|
"notification.mention": "{name} t'ha esmentat",
|
||||||
|
"notification.moderation_warning": "Heu rebut un avís de moderació",
|
||||||
|
"notification.moderation_warning.action_delete_statuses": "S'han eliminat algunes de les vostres publicacions.",
|
||||||
|
"notification.moderation_warning.action_disable": "S'ha desactivat el vostre compte.",
|
||||||
|
"notification.moderation_warning.action_mark_statuses_as_sensitive": "S'ha marcat com a sensibles algunes de les vostres publicacions.",
|
||||||
|
"notification.moderation_warning.action_none": "El vostre compte ha rebut un avís de moderació.",
|
||||||
|
"notification.moderation_warning.action_sensitive": "A partir d'ara les vostres publicacions es marcaran com sensibles.",
|
||||||
|
"notification.moderation_warning.action_silence": "S'ha limitat el vostre compte.",
|
||||||
|
"notification.moderation_warning.action_suspend": "S'ha suspès el vostre compte.",
|
||||||
"notification.own_poll": "La teva enquesta ha finalitzat",
|
"notification.own_poll": "La teva enquesta ha finalitzat",
|
||||||
"notification.poll": "Ha finalitzat una enquesta en què has votat",
|
"notification.poll": "Ha finalitzat una enquesta en què has votat",
|
||||||
"notification.reblog": "{name} t'ha impulsat",
|
"notification.reblog": "{name} t'ha impulsat",
|
||||||
|
|
|
@ -308,6 +308,8 @@
|
||||||
"follow_requests.unlocked_explanation": "Přestože váš účet není uzamčen, personál {domain} usoudil, že byste mohli chtít tyto požadavky na sledování zkontrolovat ručně.",
|
"follow_requests.unlocked_explanation": "Přestože váš účet není uzamčen, personál {domain} usoudil, že byste mohli chtít tyto požadavky na sledování zkontrolovat ručně.",
|
||||||
"follow_suggestions.curated_suggestion": "Výběr personálů",
|
"follow_suggestions.curated_suggestion": "Výběr personálů",
|
||||||
"follow_suggestions.dismiss": "Znovu nezobrazovat",
|
"follow_suggestions.dismiss": "Znovu nezobrazovat",
|
||||||
|
"follow_suggestions.featured_longer": "Ručně vybráno týmem {domain}",
|
||||||
|
"follow_suggestions.friends_of_friends_longer": "Populární mezi lidmi, které sledujete",
|
||||||
"follow_suggestions.hints.featured": "Tento profil byl ručně vybrán týmem {domain}.",
|
"follow_suggestions.hints.featured": "Tento profil byl ručně vybrán týmem {domain}.",
|
||||||
"follow_suggestions.hints.friends_of_friends": "Tento profil je populární mezi lidmi, které sledujete.",
|
"follow_suggestions.hints.friends_of_friends": "Tento profil je populární mezi lidmi, které sledujete.",
|
||||||
"follow_suggestions.hints.most_followed": "Tento profil je jedním z nejvíce sledovaných na {domain}.",
|
"follow_suggestions.hints.most_followed": "Tento profil je jedním z nejvíce sledovaných na {domain}.",
|
||||||
|
@ -315,6 +317,8 @@
|
||||||
"follow_suggestions.hints.similar_to_recently_followed": "Tento profil je podobný profilům, které jste nedávno sledovali.",
|
"follow_suggestions.hints.similar_to_recently_followed": "Tento profil je podobný profilům, které jste nedávno sledovali.",
|
||||||
"follow_suggestions.personalized_suggestion": "Přizpůsobený návrh",
|
"follow_suggestions.personalized_suggestion": "Přizpůsobený návrh",
|
||||||
"follow_suggestions.popular_suggestion": "Populární návrh",
|
"follow_suggestions.popular_suggestion": "Populární návrh",
|
||||||
|
"follow_suggestions.popular_suggestion_longer": "Populární na {domain}",
|
||||||
|
"follow_suggestions.similar_to_recently_followed_longer": "Podobné profilům, které jste nedávno sledovali",
|
||||||
"follow_suggestions.view_all": "Zobrazit vše",
|
"follow_suggestions.view_all": "Zobrazit vše",
|
||||||
"follow_suggestions.who_to_follow": "Koho sledovat",
|
"follow_suggestions.who_to_follow": "Koho sledovat",
|
||||||
"followed_tags": "Sledované hashtagy",
|
"followed_tags": "Sledované hashtagy",
|
||||||
|
@ -469,6 +473,15 @@
|
||||||
"notification.follow": "Uživatel {name} vás začal sledovat",
|
"notification.follow": "Uživatel {name} vás začal sledovat",
|
||||||
"notification.follow_request": "Uživatel {name} požádal o povolení vás sledovat",
|
"notification.follow_request": "Uživatel {name} požádal o povolení vás sledovat",
|
||||||
"notification.mention": "Uživatel {name} vás zmínil",
|
"notification.mention": "Uživatel {name} vás zmínil",
|
||||||
|
"notification.moderation-warning.learn_more": "Zjistit více",
|
||||||
|
"notification.moderation_warning": "Obdrželi jste moderační varování",
|
||||||
|
"notification.moderation_warning.action_delete_statuses": "Některé z vašich příspěvků byly odstraněny.",
|
||||||
|
"notification.moderation_warning.action_disable": "Váš účet je zablokován.",
|
||||||
|
"notification.moderation_warning.action_mark_statuses_as_sensitive": "Některé z vašich příspěvků byly označeny jako citlivé.",
|
||||||
|
"notification.moderation_warning.action_none": "Váš účet obdržel moderační varování.",
|
||||||
|
"notification.moderation_warning.action_sensitive": "Vaše příspěvky budou od nynějška označeny jako citlivé.",
|
||||||
|
"notification.moderation_warning.action_silence": "Váš účet byl omezen.",
|
||||||
|
"notification.moderation_warning.action_suspend": "Váš účet byl pozastaven.",
|
||||||
"notification.own_poll": "Vaše anketa skončila",
|
"notification.own_poll": "Vaše anketa skončila",
|
||||||
"notification.poll": "Anketa, ve které jste hlasovali, skončila",
|
"notification.poll": "Anketa, ve které jste hlasovali, skončila",
|
||||||
"notification.reblog": "Uživatel {name} boostnul váš příspěvek",
|
"notification.reblog": "Uživatel {name} boostnul váš příspěvek",
|
||||||
|
|
|
@ -89,6 +89,14 @@
|
||||||
"announcement.announcement": "Cyhoeddiad",
|
"announcement.announcement": "Cyhoeddiad",
|
||||||
"attachments_list.unprocessed": "(heb eu prosesu)",
|
"attachments_list.unprocessed": "(heb eu prosesu)",
|
||||||
"audio.hide": "Cuddio sain",
|
"audio.hide": "Cuddio sain",
|
||||||
|
"block_modal.remote_users_caveat": "Byddwn yn gofyn i'r gweinydd {domain} barchu eich penderfyniad. Fodd bynnag, nid yw cydymffurfiad wedi'i warantu gan y gall rhai gweinyddwyr drin rhwystro mewn ffyrdd gwahanol. Mae'n bosibl y bydd postiadau cyhoeddus yn dal i fod yn weladwy i ddefnyddwyr nad ydynt wedi mewngofnodi.",
|
||||||
|
"block_modal.show_less": "Dangos llai",
|
||||||
|
"block_modal.show_more": "Dangos mwy",
|
||||||
|
"block_modal.they_cant_mention": "Nid ydynt yn gallu eich crybwyll na'ch dilyn.",
|
||||||
|
"block_modal.they_cant_see_posts": "Nid ydynt yn gallu gweld eich postiadau ac ni fyddwch yn gweld eu rhai hwy.",
|
||||||
|
"block_modal.they_will_know": "Gallant weld eu bod wedi'u rhwystro.",
|
||||||
|
"block_modal.title": "Rhwystro defnyddiwr?",
|
||||||
|
"block_modal.you_wont_see_mentions": "Ni welwch bostiadau sy'n sôn amdanynt.",
|
||||||
"boost_modal.combo": "Mae modd pwyso {combo} er mwyn hepgor hyn tro nesa",
|
"boost_modal.combo": "Mae modd pwyso {combo} er mwyn hepgor hyn tro nesa",
|
||||||
"bundle_column_error.copy_stacktrace": "Copïo'r adroddiad gwall",
|
"bundle_column_error.copy_stacktrace": "Copïo'r adroddiad gwall",
|
||||||
"bundle_column_error.error.body": "Nid oedd modd cynhyrchu'r dudalen honno. Gall fod oherwydd gwall yn ein cod neu fater cydnawsedd porwr.",
|
"bundle_column_error.error.body": "Nid oedd modd cynhyrchu'r dudalen honno. Gall fod oherwydd gwall yn ein cod neu fater cydnawsedd porwr.",
|
||||||
|
@ -169,6 +177,7 @@
|
||||||
"confirmations.delete_list.message": "Ydych chi'n siŵr eich bod eisiau dileu'r rhestr hwn am byth?",
|
"confirmations.delete_list.message": "Ydych chi'n siŵr eich bod eisiau dileu'r rhestr hwn am byth?",
|
||||||
"confirmations.discard_edit_media.confirm": "Dileu",
|
"confirmations.discard_edit_media.confirm": "Dileu",
|
||||||
"confirmations.discard_edit_media.message": "Mae gennych newidiadau heb eu cadw i'r disgrifiad cyfryngau neu'r rhagolwg - eu dileu beth bynnag?",
|
"confirmations.discard_edit_media.message": "Mae gennych newidiadau heb eu cadw i'r disgrifiad cyfryngau neu'r rhagolwg - eu dileu beth bynnag?",
|
||||||
|
"confirmations.domain_block.confirm": "Rhwystro gweinydd",
|
||||||
"confirmations.domain_block.message": "Ydych chi wir, wir eisiau blocio'r holl {domain}? Fel arfer, mae blocio neu dewi pobl penodol yn broses mwy effeithiol. Fyddwch chi ddim yn gweld cynnwys o'r parth hwnnw mewn ffrydiau cyhoeddus neu yn eich hysbysiadau. Bydd eich dilynwyr o'r parth hwnnw yn cael eu ddileu.",
|
"confirmations.domain_block.message": "Ydych chi wir, wir eisiau blocio'r holl {domain}? Fel arfer, mae blocio neu dewi pobl penodol yn broses mwy effeithiol. Fyddwch chi ddim yn gweld cynnwys o'r parth hwnnw mewn ffrydiau cyhoeddus neu yn eich hysbysiadau. Bydd eich dilynwyr o'r parth hwnnw yn cael eu ddileu.",
|
||||||
"confirmations.edit.confirm": "Golygu",
|
"confirmations.edit.confirm": "Golygu",
|
||||||
"confirmations.edit.message": "Bydd golygu nawr yn trosysgrifennu'r neges rydych yn ei ysgrifennu ar hyn o bryd. Ydych chi'n siŵr eich bod eisiau gwneud hyn?",
|
"confirmations.edit.message": "Bydd golygu nawr yn trosysgrifennu'r neges rydych yn ei ysgrifennu ar hyn o bryd. Ydych chi'n siŵr eich bod eisiau gwneud hyn?",
|
||||||
|
@ -200,6 +209,27 @@
|
||||||
"dismissable_banner.explore_statuses": "Mae'r rhain yn bostiadau o bob rhan o'r we gymdeithasol sydd ar gynnydd heddiw. Mae postiadau mwy diweddar sydd â mwy o hybiau a ffefrynu'n cael eu graddio'n uwch.",
|
"dismissable_banner.explore_statuses": "Mae'r rhain yn bostiadau o bob rhan o'r we gymdeithasol sydd ar gynnydd heddiw. Mae postiadau mwy diweddar sydd â mwy o hybiau a ffefrynu'n cael eu graddio'n uwch.",
|
||||||
"dismissable_banner.explore_tags": "Mae'r rhain yn hashnodau sydd ar gynnydd ar y we gymdeithasol heddiw. Mae hashnodau sy'n cael eu defnyddio gan fwy o unigolion gwahanol yn cael eu graddio'n uwch.",
|
"dismissable_banner.explore_tags": "Mae'r rhain yn hashnodau sydd ar gynnydd ar y we gymdeithasol heddiw. Mae hashnodau sy'n cael eu defnyddio gan fwy o unigolion gwahanol yn cael eu graddio'n uwch.",
|
||||||
"dismissable_banner.public_timeline": "Dyma'r postiadau cyhoeddus diweddaraf gan bobl ar y we gymdeithasol y mae pobl ar {domain} yn eu dilyn.",
|
"dismissable_banner.public_timeline": "Dyma'r postiadau cyhoeddus diweddaraf gan bobl ar y we gymdeithasol y mae pobl ar {domain} yn eu dilyn.",
|
||||||
|
"domain_block_modal.block": "Rhwystro gweinydd",
|
||||||
|
"domain_block_modal.block_account_instead": "Rhwystro @{name} yn lle hynny",
|
||||||
|
"domain_block_modal.they_can_interact_with_old_posts": "Gall pobl o'r gweinydd hwn ryngweithio â'ch hen bostiadau.",
|
||||||
|
"domain_block_modal.they_cant_follow": "Ni all neb o'r gweinydd hwn eich dilyn.",
|
||||||
|
"domain_block_modal.they_wont_know": "Fyddan nhw ddim yn gwybod eu bod wedi cael eu rhwystro.",
|
||||||
|
"domain_block_modal.title": "Rhwystro parth?",
|
||||||
|
"domain_block_modal.you_will_lose_followers": "Bydd eich holl ddilynwyr o'r gweinydd hwn yn cael eu tynnu.",
|
||||||
|
"domain_block_modal.you_wont_see_posts": "Fyddwch chi ddim yn gweld postiadau na hysbysiadau gan ddefnyddwyr ar y gweinydd hwn.",
|
||||||
|
"domain_pill.activitypub_lets_connect": "Mae'n caniatáu ichi gysylltu a rhyngweithio â phobl nid yn unig ar Mastodon, ond ar draws gwahanol apiau cymdeithasol hefyd.",
|
||||||
|
"domain_pill.activitypub_like_language": "Mae ActivityPub fel yr iaith y mae Mastodon yn ei siarad â rhwydweithiau cymdeithasol eraill.",
|
||||||
|
"domain_pill.server": "Gweinydd",
|
||||||
|
"domain_pill.their_handle": "Eu handlen:",
|
||||||
|
"domain_pill.their_server": "Eu cartref digidol, lle mae eu holl negeseuon yn byw.",
|
||||||
|
"domain_pill.their_username": "Eu dynodwr unigryw ar eu gweinydd. Mae'n bosibl dod o hyd i ddefnyddwyr gyda'r un enw defnyddiwr ar wahanol weinyddion.",
|
||||||
|
"domain_pill.username": "Enw Defnyddiwr",
|
||||||
|
"domain_pill.whats_in_a_handle": "Beth sydd mewn handlen?",
|
||||||
|
"domain_pill.who_they_are": "Gan fod handlen yn dweud pwy yw rhywun a ble maen nhw, gallwch chi ryngweithio â phobl ar draws gwe gymdeithasol <button>llwyfannau wedi'u pweru gan ActivityPub</button> .",
|
||||||
|
"domain_pill.who_you_are": "Oherwydd bod eich handlen yn dweud pwy ydych chi a ble rydych chi, gall pobl ryngweithio â chi ar draws gwe gymdeithasol <button>llwyfannau wedi'u pweru gan ActivityPub</button> .",
|
||||||
|
"domain_pill.your_handle": "Eich handlen:",
|
||||||
|
"domain_pill.your_server": "Eich cartref digidol, lle mae'ch holl bostiadau'n byw. Ddim yn hoffi'r un hon? Trosglwyddwch weinyddion ar unrhyw adeg a dewch â'ch dilynwyr hefyd.",
|
||||||
|
"domain_pill.your_username": "Eich dynodwr unigryw ar y gweinydd hwn. Mae'n bosibl dod o hyd i ddefnyddwyr gyda'r un enw defnyddiwr ar wahanol weinyddion.",
|
||||||
"embed.instructions": "Gosodwch y post hwn ar eich gwefan drwy gopïo'r côd isod.",
|
"embed.instructions": "Gosodwch y post hwn ar eich gwefan drwy gopïo'r côd isod.",
|
||||||
"embed.preview": "Dyma sut olwg fydd arno:",
|
"embed.preview": "Dyma sut olwg fydd arno:",
|
||||||
"emoji_button.activity": "Gweithgarwch",
|
"emoji_button.activity": "Gweithgarwch",
|
||||||
|
@ -267,6 +297,8 @@
|
||||||
"filter_modal.select_filter.subtitle": "Defnyddiwch gategori sy'n bodoli eisoes neu crëu un newydd",
|
"filter_modal.select_filter.subtitle": "Defnyddiwch gategori sy'n bodoli eisoes neu crëu un newydd",
|
||||||
"filter_modal.select_filter.title": "Hidlo'r postiad hwn",
|
"filter_modal.select_filter.title": "Hidlo'r postiad hwn",
|
||||||
"filter_modal.title.status": "Hidlo postiad",
|
"filter_modal.title.status": "Hidlo postiad",
|
||||||
|
"filtered_notifications_banner.mentions": "{count, plural, one {crybwylliad} other {crybwylliad}}",
|
||||||
|
"filtered_notifications_banner.pending_requests": "Hysbysiadau gan {count, plural, =0 {neb} one {un person} other {# person}} efallai y gwyddoch amdanyn nhw",
|
||||||
"filtered_notifications_banner.title": "Hysbysiadau wedi'u hidlo",
|
"filtered_notifications_banner.title": "Hysbysiadau wedi'u hidlo",
|
||||||
"firehose.all": "Popeth",
|
"firehose.all": "Popeth",
|
||||||
"firehose.local": "Gweinydd hwn",
|
"firehose.local": "Gweinydd hwn",
|
||||||
|
@ -276,6 +308,8 @@
|
||||||
"follow_requests.unlocked_explanation": "Er nid yw eich cyfrif wedi'i gloi, roedd y staff {domain} yn meddwl efallai hoffech adolygu ceisiadau dilyn o'r cyfrifau rhain wrth law.",
|
"follow_requests.unlocked_explanation": "Er nid yw eich cyfrif wedi'i gloi, roedd y staff {domain} yn meddwl efallai hoffech adolygu ceisiadau dilyn o'r cyfrifau rhain wrth law.",
|
||||||
"follow_suggestions.curated_suggestion": "Dewis staff",
|
"follow_suggestions.curated_suggestion": "Dewis staff",
|
||||||
"follow_suggestions.dismiss": "Peidio â dangos hwn eto",
|
"follow_suggestions.dismiss": "Peidio â dangos hwn eto",
|
||||||
|
"follow_suggestions.featured_longer": "Wedi'i ddewis â llaw gan dîm {domain}",
|
||||||
|
"follow_suggestions.friends_of_friends_longer": "Yn boblogaidd ymhlith y bobl rydych chi'n eu dilyn",
|
||||||
"follow_suggestions.hints.featured": "Mae'r proffil hwn wedi'i ddewis yn arbennig gan dîm {domain}.",
|
"follow_suggestions.hints.featured": "Mae'r proffil hwn wedi'i ddewis yn arbennig gan dîm {domain}.",
|
||||||
"follow_suggestions.hints.friends_of_friends": "Mae'r proffil hwn yn boblogaidd ymhlith y bobl rydych chi'n eu dilyn.",
|
"follow_suggestions.hints.friends_of_friends": "Mae'r proffil hwn yn boblogaidd ymhlith y bobl rydych chi'n eu dilyn.",
|
||||||
"follow_suggestions.hints.most_followed": "Mae'r proffil hwn yn un o'r rhai sy'n cael ei ddilyn fwyaf ar {domain}.",
|
"follow_suggestions.hints.most_followed": "Mae'r proffil hwn yn un o'r rhai sy'n cael ei ddilyn fwyaf ar {domain}.",
|
||||||
|
@ -283,6 +317,8 @@
|
||||||
"follow_suggestions.hints.similar_to_recently_followed": "Mae'r proffil hwn yn debyg i'r proffiliau rydych chi wedi'u dilyn yn fwyaf diweddar.",
|
"follow_suggestions.hints.similar_to_recently_followed": "Mae'r proffil hwn yn debyg i'r proffiliau rydych chi wedi'u dilyn yn fwyaf diweddar.",
|
||||||
"follow_suggestions.personalized_suggestion": "Awgrym personol",
|
"follow_suggestions.personalized_suggestion": "Awgrym personol",
|
||||||
"follow_suggestions.popular_suggestion": "Awgrym poblogaidd",
|
"follow_suggestions.popular_suggestion": "Awgrym poblogaidd",
|
||||||
|
"follow_suggestions.popular_suggestion_longer": "Yn boblogaidd ar {domain}",
|
||||||
|
"follow_suggestions.similar_to_recently_followed_longer": "Yn debyg i broffiliau y gwnaethoch chi eu dilyn yn ddiweddar",
|
||||||
"follow_suggestions.view_all": "Gweld y cyfan",
|
"follow_suggestions.view_all": "Gweld y cyfan",
|
||||||
"follow_suggestions.who_to_follow": "Pwy i ddilyn",
|
"follow_suggestions.who_to_follow": "Pwy i ddilyn",
|
||||||
"followed_tags": "Hashnodau rydych yn eu dilyn",
|
"followed_tags": "Hashnodau rydych yn eu dilyn",
|
||||||
|
@ -396,6 +432,15 @@
|
||||||
"loading_indicator.label": "Yn llwytho…",
|
"loading_indicator.label": "Yn llwytho…",
|
||||||
"media_gallery.toggle_visible": "{number, plural, one {Cuddio delwedd} other {Cuddio delwedd}}",
|
"media_gallery.toggle_visible": "{number, plural, one {Cuddio delwedd} other {Cuddio delwedd}}",
|
||||||
"moved_to_account_banner.text": "Ar hyn y bryd, mae eich cyfrif {disabledAccount} wedi ei analluogi am i chi symud i {movedToAccount}.",
|
"moved_to_account_banner.text": "Ar hyn y bryd, mae eich cyfrif {disabledAccount} wedi ei analluogi am i chi symud i {movedToAccount}.",
|
||||||
|
"mute_modal.hide_from_notifications": "Cuddio rhag hysbysiadau",
|
||||||
|
"mute_modal.hide_options": "Cuddio'r dewis",
|
||||||
|
"mute_modal.indefinite": "Nes i mi eu dad-dewi",
|
||||||
|
"mute_modal.show_options": "Dangos y dewis",
|
||||||
|
"mute_modal.they_can_mention_and_follow": "Gallan nhw eich crybwyll a'ch dilyn, ond fyddwch chi ddim yn eu gweld.",
|
||||||
|
"mute_modal.they_wont_know": "Fyddan nhw ddim yn gwybod eu bod wedi cael eu tawelu.",
|
||||||
|
"mute_modal.title": "Tewi defnyddiwr?",
|
||||||
|
"mute_modal.you_wont_see_mentions": "Welwch chi ddim postiadau sy'n sôn amdanyn nhw.",
|
||||||
|
"mute_modal.you_wont_see_posts": "Gallan nhw weld eich postiadau o hyd, ond fyddwch chi ddim yn gweld eu rhai hwy.",
|
||||||
"navigation_bar.about": "Ynghylch",
|
"navigation_bar.about": "Ynghylch",
|
||||||
"navigation_bar.advanced_interface": "Agor mewn rhyngwyneb gwe uwch",
|
"navigation_bar.advanced_interface": "Agor mewn rhyngwyneb gwe uwch",
|
||||||
"navigation_bar.blocks": "Defnyddwyr wedi eu blocio",
|
"navigation_bar.blocks": "Defnyddwyr wedi eu blocio",
|
||||||
|
@ -428,9 +473,23 @@
|
||||||
"notification.follow": "Dilynodd {name} chi",
|
"notification.follow": "Dilynodd {name} chi",
|
||||||
"notification.follow_request": "Mae {name} wedi gwneud cais i'ch dilyn",
|
"notification.follow_request": "Mae {name} wedi gwneud cais i'ch dilyn",
|
||||||
"notification.mention": "Crybwyllodd {name} amdanoch chi",
|
"notification.mention": "Crybwyllodd {name} amdanoch chi",
|
||||||
|
"notification.moderation-warning.learn_more": "Dysgu mwy",
|
||||||
|
"notification.moderation_warning": "Rydych wedi derbyn rhybudd cymedroli",
|
||||||
|
"notification.moderation_warning.action_delete_statuses": "Mae rhai o'ch postiadau wedi'u dileu.",
|
||||||
|
"notification.moderation_warning.action_disable": "Mae eich cyfrif wedi'i analluogi.",
|
||||||
|
"notification.moderation_warning.action_mark_statuses_as_sensitive": "Mae rhai o'ch postiadau wedi'u marcio'n sensitif.",
|
||||||
|
"notification.moderation_warning.action_none": "Mae eich cyfrif wedi derbyn rhybudd cymedroli.",
|
||||||
|
"notification.moderation_warning.action_sensitive": "Bydd eich postiadau'n cael eu marcio'n sensitif o hyn ymlaen.",
|
||||||
|
"notification.moderation_warning.action_silence": "Mae eich cyfrif wedi'i gyfyngu.",
|
||||||
|
"notification.moderation_warning.action_suspend": "Mae eich cyfrif wedi'i hatal.",
|
||||||
"notification.own_poll": "Mae eich pleidlais wedi dod i ben",
|
"notification.own_poll": "Mae eich pleidlais wedi dod i ben",
|
||||||
"notification.poll": "Mae pleidlais rydych wedi pleidleisio ynddi wedi dod i ben",
|
"notification.poll": "Mae pleidlais rydych wedi pleidleisio ynddi wedi dod i ben",
|
||||||
"notification.reblog": "Hybodd {name} eich post",
|
"notification.reblog": "Hybodd {name} eich post",
|
||||||
|
"notification.relationships_severance_event": "Wedi colli cysylltiad â {name}",
|
||||||
|
"notification.relationships_severance_event.account_suspension": "Mae gweinyddwr o {from} wedi atal {target}, sy'n golygu na allwch dderbyn diweddariadau ganddynt mwyach na rhyngweithio â nhw.",
|
||||||
|
"notification.relationships_severance_event.domain_block": "Mae gweinyddwr o {from} wedi rhwystro {target}, gan gynnwys {followersCount} o'ch dilynwyr a {followingCount, plural, one {# cyfrif} other {# cyfrif}} arall rydych chi'n ei ddilyn.",
|
||||||
|
"notification.relationships_severance_event.learn_more": "Dysgu mwy",
|
||||||
|
"notification.relationships_severance_event.user_domain_block": "Rydych wedi rhwystro {target}, gan ddileu {followersCount} o'ch dilynwyr a {followingCount, plural, one {# cyfrif} other {#cyfrifon}} arall rydych yn ei ddilyn.",
|
||||||
"notification.status": "{name} newydd ei bostio",
|
"notification.status": "{name} newydd ei bostio",
|
||||||
"notification.update": "Golygodd {name} bostiad",
|
"notification.update": "Golygodd {name} bostiad",
|
||||||
"notification_requests.accept": "Derbyn",
|
"notification_requests.accept": "Derbyn",
|
||||||
|
@ -443,6 +502,8 @@
|
||||||
"notifications.column_settings.admin.sign_up": "Cofrestriadau newydd:",
|
"notifications.column_settings.admin.sign_up": "Cofrestriadau newydd:",
|
||||||
"notifications.column_settings.alert": "Hysbysiadau bwrdd gwaith",
|
"notifications.column_settings.alert": "Hysbysiadau bwrdd gwaith",
|
||||||
"notifications.column_settings.favourite": "Ffefrynnau:",
|
"notifications.column_settings.favourite": "Ffefrynnau:",
|
||||||
|
"notifications.column_settings.filter_bar.advanced": "Dangos pob categori",
|
||||||
|
"notifications.column_settings.filter_bar.category": "Bar hidlo cyflym",
|
||||||
"notifications.column_settings.follow": "Dilynwyr newydd:",
|
"notifications.column_settings.follow": "Dilynwyr newydd:",
|
||||||
"notifications.column_settings.follow_request": "Ceisiadau dilyn newydd:",
|
"notifications.column_settings.follow_request": "Ceisiadau dilyn newydd:",
|
||||||
"notifications.column_settings.mention": "Crybwylliadau:",
|
"notifications.column_settings.mention": "Crybwylliadau:",
|
||||||
|
@ -653,9 +714,11 @@
|
||||||
"status.direct": "Crybwyll yn breifat @{name}",
|
"status.direct": "Crybwyll yn breifat @{name}",
|
||||||
"status.direct_indicator": "Crybwyll preifat",
|
"status.direct_indicator": "Crybwyll preifat",
|
||||||
"status.edit": "Golygu",
|
"status.edit": "Golygu",
|
||||||
|
"status.edited": "Golygwyd ddiwethaf {date}",
|
||||||
"status.edited_x_times": "Golygwyd {count, plural, one {count} two {count} other {{count} gwaith}}",
|
"status.edited_x_times": "Golygwyd {count, plural, one {count} two {count} other {{count} gwaith}}",
|
||||||
"status.embed": "Mewnblannu",
|
"status.embed": "Mewnblannu",
|
||||||
"status.favourite": "Hoffi",
|
"status.favourite": "Hoffi",
|
||||||
|
"status.favourites": "{count, plural, one {ffefryn} other {ffefryn}}",
|
||||||
"status.filter": "Hidlo'r postiad hwn",
|
"status.filter": "Hidlo'r postiad hwn",
|
||||||
"status.filtered": "Wedi'i hidlo",
|
"status.filtered": "Wedi'i hidlo",
|
||||||
"status.hide": "Cuddio'r postiad",
|
"status.hide": "Cuddio'r postiad",
|
||||||
|
@ -676,6 +739,7 @@
|
||||||
"status.reblog": "Hybu",
|
"status.reblog": "Hybu",
|
||||||
"status.reblog_private": "Hybu i'r gynulleidfa wreiddiol",
|
"status.reblog_private": "Hybu i'r gynulleidfa wreiddiol",
|
||||||
"status.reblogged_by": "Hybodd {name}",
|
"status.reblogged_by": "Hybodd {name}",
|
||||||
|
"status.reblogs": "{count, plural, one {hwb} other {hwb}}",
|
||||||
"status.reblogs.empty": "Does neb wedi hybio'r post yma eto. Pan y bydd rhywun yn gwneud, byddent yn ymddangos yma.",
|
"status.reblogs.empty": "Does neb wedi hybio'r post yma eto. Pan y bydd rhywun yn gwneud, byddent yn ymddangos yma.",
|
||||||
"status.redraft": "Dileu ac ailddrafftio",
|
"status.redraft": "Dileu ac ailddrafftio",
|
||||||
"status.remove_bookmark": "Tynnu nod tudalen",
|
"status.remove_bookmark": "Tynnu nod tudalen",
|
||||||
|
|
|
@ -306,6 +306,8 @@
|
||||||
"follow_requests.unlocked_explanation": "Selvom din konto ikke er låst, synes {domain}-personalet, du måske bør gennemgå disse anmodninger manuelt.",
|
"follow_requests.unlocked_explanation": "Selvom din konto ikke er låst, synes {domain}-personalet, du måske bør gennemgå disse anmodninger manuelt.",
|
||||||
"follow_suggestions.curated_suggestion": "Personaleudvalgt",
|
"follow_suggestions.curated_suggestion": "Personaleudvalgt",
|
||||||
"follow_suggestions.dismiss": "Vis ikke igen",
|
"follow_suggestions.dismiss": "Vis ikke igen",
|
||||||
|
"follow_suggestions.featured_longer": "Håndplukket af {domain}-teamet",
|
||||||
|
"follow_suggestions.friends_of_friends_longer": "Populært blandt personer, som følges",
|
||||||
"follow_suggestions.hints.featured": "Denne profil er håndplukket af {domain}-teamet.",
|
"follow_suggestions.hints.featured": "Denne profil er håndplukket af {domain}-teamet.",
|
||||||
"follow_suggestions.hints.friends_of_friends": "Denne profil er populær blandt de personer, som følges.",
|
"follow_suggestions.hints.friends_of_friends": "Denne profil er populær blandt de personer, som følges.",
|
||||||
"follow_suggestions.hints.most_followed": "Denne profil er en af de mest fulgte på {domain}.",
|
"follow_suggestions.hints.most_followed": "Denne profil er en af de mest fulgte på {domain}.",
|
||||||
|
@ -313,6 +315,8 @@
|
||||||
"follow_suggestions.hints.similar_to_recently_followed": "Denne profil svarer til de profiler, som senest er blevet fulgt.",
|
"follow_suggestions.hints.similar_to_recently_followed": "Denne profil svarer til de profiler, som senest er blevet fulgt.",
|
||||||
"follow_suggestions.personalized_suggestion": "Personligt forslag",
|
"follow_suggestions.personalized_suggestion": "Personligt forslag",
|
||||||
"follow_suggestions.popular_suggestion": "Populært forslag",
|
"follow_suggestions.popular_suggestion": "Populært forslag",
|
||||||
|
"follow_suggestions.popular_suggestion_longer": "Populært på {domain}",
|
||||||
|
"follow_suggestions.similar_to_recently_followed_longer": "Svarende til profiler, som for nylig er fulgt",
|
||||||
"follow_suggestions.view_all": "Vis alle",
|
"follow_suggestions.view_all": "Vis alle",
|
||||||
"follow_suggestions.who_to_follow": "Hvem, som skal følges",
|
"follow_suggestions.who_to_follow": "Hvem, som skal følges",
|
||||||
"followed_tags": "Hashtag, som følges",
|
"followed_tags": "Hashtag, som følges",
|
||||||
|
@ -467,6 +471,15 @@
|
||||||
"notification.follow": "{name} begyndte at følge dig",
|
"notification.follow": "{name} begyndte at følge dig",
|
||||||
"notification.follow_request": "{name} har anmodet om at følge dig",
|
"notification.follow_request": "{name} har anmodet om at følge dig",
|
||||||
"notification.mention": "{name} nævnte dig",
|
"notification.mention": "{name} nævnte dig",
|
||||||
|
"notification.moderation-warning.learn_more": "Læs mere",
|
||||||
|
"notification.moderation_warning": "Du er tildelt en moderationsadvarsel",
|
||||||
|
"notification.moderation_warning.action_delete_statuses": "Nogle af dine indlæg er blevet fjernet.",
|
||||||
|
"notification.moderation_warning.action_disable": "Din konto er blevet deaktiveret.",
|
||||||
|
"notification.moderation_warning.action_mark_statuses_as_sensitive": "Nogle af dine indlæg er blevet markeret som sensitive.",
|
||||||
|
"notification.moderation_warning.action_none": "Din konto er tildelt en moderationsadvarsel.",
|
||||||
|
"notification.moderation_warning.action_sensitive": "Dine indlæg markeres fra nu af som sensitive.",
|
||||||
|
"notification.moderation_warning.action_silence": "Din konto er blevet begrænset.",
|
||||||
|
"notification.moderation_warning.action_suspend": "Din konto er suspenderet.",
|
||||||
"notification.own_poll": "Din afstemning er afsluttet",
|
"notification.own_poll": "Din afstemning er afsluttet",
|
||||||
"notification.poll": "En afstemning, hvori du stemte, er slut",
|
"notification.poll": "En afstemning, hvori du stemte, er slut",
|
||||||
"notification.reblog": "{name} boostede dit indlæg",
|
"notification.reblog": "{name} boostede dit indlæg",
|
||||||
|
|
|
@ -308,6 +308,8 @@
|
||||||
"follow_requests.unlocked_explanation": "Auch wenn dein Konto öffentlich bzw. nicht geschützt ist, haben die Moderator*innen von {domain} gedacht, dass du diesen Follower lieber manuell bestätigen solltest.",
|
"follow_requests.unlocked_explanation": "Auch wenn dein Konto öffentlich bzw. nicht geschützt ist, haben die Moderator*innen von {domain} gedacht, dass du diesen Follower lieber manuell bestätigen solltest.",
|
||||||
"follow_suggestions.curated_suggestion": "Vom Server-Team empfohlen",
|
"follow_suggestions.curated_suggestion": "Vom Server-Team empfohlen",
|
||||||
"follow_suggestions.dismiss": "Nicht mehr anzeigen",
|
"follow_suggestions.dismiss": "Nicht mehr anzeigen",
|
||||||
|
"follow_suggestions.featured_longer": "Vom {domain}-Team ausgewählt",
|
||||||
|
"follow_suggestions.friends_of_friends_longer": "Beliebt bei Leuten, denen du folgst",
|
||||||
"follow_suggestions.hints.featured": "Dieses Profil wurde vom {domain}-Team ausgewählt.",
|
"follow_suggestions.hints.featured": "Dieses Profil wurde vom {domain}-Team ausgewählt.",
|
||||||
"follow_suggestions.hints.friends_of_friends": "Dieses Profil ist bei deinen Followern beliebt.",
|
"follow_suggestions.hints.friends_of_friends": "Dieses Profil ist bei deinen Followern beliebt.",
|
||||||
"follow_suggestions.hints.most_followed": "Dieses Profil ist eines der am meisten gefolgten auf {domain}.",
|
"follow_suggestions.hints.most_followed": "Dieses Profil ist eines der am meisten gefolgten auf {domain}.",
|
||||||
|
@ -315,6 +317,8 @@
|
||||||
"follow_suggestions.hints.similar_to_recently_followed": "Dieses Profil ähnelt den Profilen, denen du in letzter Zeit gefolgt hast.",
|
"follow_suggestions.hints.similar_to_recently_followed": "Dieses Profil ähnelt den Profilen, denen du in letzter Zeit gefolgt hast.",
|
||||||
"follow_suggestions.personalized_suggestion": "Persönliche Empfehlung",
|
"follow_suggestions.personalized_suggestion": "Persönliche Empfehlung",
|
||||||
"follow_suggestions.popular_suggestion": "Beliebte Empfehlung",
|
"follow_suggestions.popular_suggestion": "Beliebte Empfehlung",
|
||||||
|
"follow_suggestions.popular_suggestion_longer": "Beliebt auf {domain}",
|
||||||
|
"follow_suggestions.similar_to_recently_followed_longer": "Ähnlich zu Profilen, denen du seit kurzem folgst",
|
||||||
"follow_suggestions.view_all": "Alle anzeigen",
|
"follow_suggestions.view_all": "Alle anzeigen",
|
||||||
"follow_suggestions.who_to_follow": "Empfohlene Profile",
|
"follow_suggestions.who_to_follow": "Empfohlene Profile",
|
||||||
"followed_tags": "Gefolgte Hashtags",
|
"followed_tags": "Gefolgte Hashtags",
|
||||||
|
@ -469,6 +473,15 @@
|
||||||
"notification.follow": "{name} folgt dir",
|
"notification.follow": "{name} folgt dir",
|
||||||
"notification.follow_request": "{name} möchte dir folgen",
|
"notification.follow_request": "{name} möchte dir folgen",
|
||||||
"notification.mention": "{name} erwähnte dich",
|
"notification.mention": "{name} erwähnte dich",
|
||||||
|
"notification.moderation-warning.learn_more": "Mehr erfahren",
|
||||||
|
"notification.moderation_warning": "Du wurdest von den Moderator*innen verwarnt",
|
||||||
|
"notification.moderation_warning.action_delete_statuses": "Einige deiner Beiträge sind entfernt worden.",
|
||||||
|
"notification.moderation_warning.action_disable": "Dein Konto wurde deaktiviert.",
|
||||||
|
"notification.moderation_warning.action_mark_statuses_as_sensitive": "Einige deiner Beiträge wurden mit einer Inhaltswarnung versehen.",
|
||||||
|
"notification.moderation_warning.action_none": "Dein Konto ist von den Moderator*innen verwarnt worden.",
|
||||||
|
"notification.moderation_warning.action_sensitive": "Deine zukünftigen Beiträge werden mit einer Inhaltswarnung versehen.",
|
||||||
|
"notification.moderation_warning.action_silence": "Dein Konto wurde eingeschränkt.",
|
||||||
|
"notification.moderation_warning.action_suspend": "Dein Konto wurde gesperrt.",
|
||||||
"notification.own_poll": "Deine Umfrage ist beendet",
|
"notification.own_poll": "Deine Umfrage ist beendet",
|
||||||
"notification.poll": "Eine Umfrage, an der du teilgenommen hast, ist beendet",
|
"notification.poll": "Eine Umfrage, an der du teilgenommen hast, ist beendet",
|
||||||
"notification.reblog": "{name} teilte deinen Beitrag",
|
"notification.reblog": "{name} teilte deinen Beitrag",
|
||||||
|
@ -536,11 +549,11 @@
|
||||||
"onboarding.follows.empty": "Bedauerlicherweise können aktuell keine Ergebnisse angezeigt werden. Du kannst die Suche verwenden oder den Reiter „Entdecken“ auswählen, um neue Leute zum Folgen zu finden – oder du versuchst es später erneut.",
|
"onboarding.follows.empty": "Bedauerlicherweise können aktuell keine Ergebnisse angezeigt werden. Du kannst die Suche verwenden oder den Reiter „Entdecken“ auswählen, um neue Leute zum Folgen zu finden – oder du versuchst es später erneut.",
|
||||||
"onboarding.follows.lead": "Deine Startseite ist der primäre Anlaufpunkt, um Mastodon zu erleben. Je mehr Profilen du folgst, umso aktiver und interessanter wird sie. Damit du direkt loslegen kannst, gibt es hier ein paar Vorschläge:",
|
"onboarding.follows.lead": "Deine Startseite ist der primäre Anlaufpunkt, um Mastodon zu erleben. Je mehr Profilen du folgst, umso aktiver und interessanter wird sie. Damit du direkt loslegen kannst, gibt es hier ein paar Vorschläge:",
|
||||||
"onboarding.follows.title": "Personalisiere deine Startseite",
|
"onboarding.follows.title": "Personalisiere deine Startseite",
|
||||||
"onboarding.profile.discoverable": "Mein Profil auffindbar machen",
|
"onboarding.profile.discoverable": "Mein Profil darf entdeckt werden",
|
||||||
"onboarding.profile.discoverable_hint": "Wenn du entdeckt werden möchtest, dann können deine Beiträge in Suchergebnissen und Trends erscheinen. Dein Profil kann ebenfalls anderen mit ähnlichen Interessen vorgeschlagen werden.",
|
"onboarding.profile.discoverable_hint": "Wenn du entdeckt werden möchtest, dann können deine Beiträge in Suchergebnissen und Trends erscheinen. Dein Profil kann ebenfalls anderen mit ähnlichen Interessen vorgeschlagen werden.",
|
||||||
"onboarding.profile.display_name": "Anzeigename",
|
"onboarding.profile.display_name": "Anzeigename",
|
||||||
"onboarding.profile.display_name_hint": "Dein richtiger Name oder dein Fantasiename …",
|
"onboarding.profile.display_name_hint": "Dein richtiger Name oder dein Fantasiename …",
|
||||||
"onboarding.profile.lead": "Du kannst das später in den Einstellungen vervollständigen, wo noch mehr Anpassungsmöglichkeiten zur Verfügung stehen.",
|
"onboarding.profile.lead": "Du kannst dein Profil später in den Einstellungen vervollständigen. Dort stehen weitere Anpassungsmöglichkeiten zur Verfügung.",
|
||||||
"onboarding.profile.note": "Über mich",
|
"onboarding.profile.note": "Über mich",
|
||||||
"onboarding.profile.note_hint": "Du kannst andere @Profile erwähnen oder #Hashtags verwenden …",
|
"onboarding.profile.note_hint": "Du kannst andere @Profile erwähnen oder #Hashtags verwenden …",
|
||||||
"onboarding.profile.save_and_continue": "Speichern und fortfahren",
|
"onboarding.profile.save_and_continue": "Speichern und fortfahren",
|
||||||
|
@ -556,16 +569,16 @@
|
||||||
"onboarding.start.title": "Du hast es geschafft!",
|
"onboarding.start.title": "Du hast es geschafft!",
|
||||||
"onboarding.steps.follow_people.body": "Interessanten Profilen zu folgen ist das, was Mastodon ausmacht.",
|
"onboarding.steps.follow_people.body": "Interessanten Profilen zu folgen ist das, was Mastodon ausmacht.",
|
||||||
"onboarding.steps.follow_people.title": "Personalisiere deine Startseite",
|
"onboarding.steps.follow_people.title": "Personalisiere deine Startseite",
|
||||||
"onboarding.steps.publish_status.body": "Begrüße die Welt mit Text, Fotos, Videos oder Umfragen {emoji}",
|
"onboarding.steps.publish_status.body": "Begrüße die Welt mit Text, Fotos, Videos oder Umfragen. {emoji}",
|
||||||
"onboarding.steps.publish_status.title": "Erstelle deinen ersten Beitrag",
|
"onboarding.steps.publish_status.title": "Erstelle deinen ersten Beitrag",
|
||||||
"onboarding.steps.setup_profile.body": "Mit einem vollständigen Profil interagieren andere eher mit dir.",
|
"onboarding.steps.setup_profile.body": "Mit einem vollständigen Profil interagieren andere eher mit dir.",
|
||||||
"onboarding.steps.setup_profile.title": "Personalisiere dein Profil",
|
"onboarding.steps.setup_profile.title": "Personalisiere dein Profil",
|
||||||
"onboarding.steps.share_profile.body": "Lass deine Freund*innen wissen, wie sie dich auf Mastodon finden können",
|
"onboarding.steps.share_profile.body": "Lass deine Freund*innen wissen, wie sie dich auf Mastodon finden können.",
|
||||||
"onboarding.steps.share_profile.title": "Teile dein Mastodon-Profil",
|
"onboarding.steps.share_profile.title": "Teile dein Mastodon-Profil",
|
||||||
"onboarding.tips.2fa": "<strong>Wusstest du schon?</strong> Du kannst die Sicherheit deines Kontos erhöhen, indem du die Zwei-Faktor-Authentisierung in deinen Kontoeinstellungen aktivierst. Dafür ist keine Telefonnummer notwendig und es funktioniert jede beliebige TOTP-App!",
|
"onboarding.tips.2fa": "<strong>Wusstest du schon?</strong> Du kannst die Sicherheit deines Kontos erhöhen, indem du die Zwei-Faktor-Authentisierung in deinen Kontoeinstellungen aktivierst. Dafür ist keine Telefonnummer notwendig und es funktioniert jede beliebige TOTP-App!",
|
||||||
"onboarding.tips.accounts_from_other_servers": "<strong>Wusstest du schon?</strong> Da Mastodon dezentralisiert ist, werden einige Profile, denen du begegnest, auf anderen Servern als deinem bereitgestellt. Und trotzdem kannst du uneingeschränkt mit ihnen interagieren! Der Servername befindet sich in der zweiten Hälfte ihres Profilnamens!",
|
"onboarding.tips.accounts_from_other_servers": "<strong>Wusstest du schon?</strong> Da Mastodon dezentralisiert ist, werden einige Profile, denen du begegnest, auf anderen Servern als deinem bereitgestellt. Und trotzdem kannst du uneingeschränkt mit ihnen interagieren! Der Servername befindet sich in der zweiten Hälfte ihres Profilnamens!",
|
||||||
"onboarding.tips.migration": "<strong>Wusstest du schon?</strong> Wenn du das Gefühl hast, dass {domain} in Zukunft nicht die richtige Serverwahl für dich ist, kannst du auf einen anderen Mastodon-Server umziehen, ohne deine Follower zu verlieren. Du kannst sogar deinen eigenen Server betreiben!",
|
"onboarding.tips.migration": "<strong>Wusstest du schon?</strong> Wenn du das Gefühl hast, dass {domain} in Zukunft nicht die richtige Serverwahl für dich ist, kannst du auf einen anderen Mastodon-Server umziehen, ohne deine Follower zu verlieren. Du kannst sogar deinen eigenen Server betreiben!",
|
||||||
"onboarding.tips.verification": "<strong>Wusstest du schon?</strong> Du kannst dein Konto verifizieren, indem du auf deiner Website auf dein Mastodon-Profil verlinkst und den Link deiner Website zu deinem Profil hinzufügst. Keine Gebühren oder Dokumente erforderlich!",
|
"onboarding.tips.verification": "<strong>Wusstest du schon?</strong> Du kannst dein Konto verifizieren, indem du auf deiner Website auf dein Mastodon-Profil verlinkst und den Link deiner Website zu deinem Profil hinzufügst. Völlig kostenlos und ohne Dokumente einsenden zu müssen!",
|
||||||
"password_confirmation.exceeds_maxlength": "Passwortbestätigung überschreitet die maximal erlaubte Zeichenanzahl",
|
"password_confirmation.exceeds_maxlength": "Passwortbestätigung überschreitet die maximal erlaubte Zeichenanzahl",
|
||||||
"password_confirmation.mismatching": "Passwortbestätigung stimmt nicht überein",
|
"password_confirmation.mismatching": "Passwortbestätigung stimmt nicht überein",
|
||||||
"picture_in_picture.restore": "Zurücksetzen",
|
"picture_in_picture.restore": "Zurücksetzen",
|
||||||
|
|
|
@ -308,6 +308,8 @@
|
||||||
"follow_requests.unlocked_explanation": "Even though your account is not locked, the {domain} staff thought you might want to review follow requests from these accounts manually.",
|
"follow_requests.unlocked_explanation": "Even though your account is not locked, the {domain} staff thought you might want to review follow requests from these accounts manually.",
|
||||||
"follow_suggestions.curated_suggestion": "Staff pick",
|
"follow_suggestions.curated_suggestion": "Staff pick",
|
||||||
"follow_suggestions.dismiss": "Don't show again",
|
"follow_suggestions.dismiss": "Don't show again",
|
||||||
|
"follow_suggestions.featured_longer": "Hand-picked by the {domain} team",
|
||||||
|
"follow_suggestions.friends_of_friends_longer": "Popular among people you follow",
|
||||||
"follow_suggestions.hints.featured": "This profile has been hand-picked by the {domain} team.",
|
"follow_suggestions.hints.featured": "This profile has been hand-picked by the {domain} team.",
|
||||||
"follow_suggestions.hints.friends_of_friends": "This profile is popular among the people you follow.",
|
"follow_suggestions.hints.friends_of_friends": "This profile is popular among the people you follow.",
|
||||||
"follow_suggestions.hints.most_followed": "This profile is one of the most followed on {domain}.",
|
"follow_suggestions.hints.most_followed": "This profile is one of the most followed on {domain}.",
|
||||||
|
@ -315,6 +317,8 @@
|
||||||
"follow_suggestions.hints.similar_to_recently_followed": "This profile is similar to the profiles you have most recently followed.",
|
"follow_suggestions.hints.similar_to_recently_followed": "This profile is similar to the profiles you have most recently followed.",
|
||||||
"follow_suggestions.personalized_suggestion": "Personalized suggestion",
|
"follow_suggestions.personalized_suggestion": "Personalized suggestion",
|
||||||
"follow_suggestions.popular_suggestion": "Popular suggestion",
|
"follow_suggestions.popular_suggestion": "Popular suggestion",
|
||||||
|
"follow_suggestions.popular_suggestion_longer": "Popular on {domain}",
|
||||||
|
"follow_suggestions.similar_to_recently_followed_longer": "Similar to profiles you recently followed",
|
||||||
"follow_suggestions.view_all": "View all",
|
"follow_suggestions.view_all": "View all",
|
||||||
"follow_suggestions.who_to_follow": "Who to follow",
|
"follow_suggestions.who_to_follow": "Who to follow",
|
||||||
"followed_tags": "Followed hashtags",
|
"followed_tags": "Followed hashtags",
|
||||||
|
@ -469,6 +473,15 @@
|
||||||
"notification.follow": "{name} followed you",
|
"notification.follow": "{name} followed you",
|
||||||
"notification.follow_request": "{name} has requested to follow you",
|
"notification.follow_request": "{name} has requested to follow you",
|
||||||
"notification.mention": "{name} mentioned you",
|
"notification.mention": "{name} mentioned you",
|
||||||
|
"notification.moderation-warning.learn_more": "Learn more",
|
||||||
|
"notification.moderation_warning": "Your have received a moderation warning",
|
||||||
|
"notification.moderation_warning.action_delete_statuses": "Some of your posts have been removed.",
|
||||||
|
"notification.moderation_warning.action_disable": "Your account has been disabled.",
|
||||||
|
"notification.moderation_warning.action_mark_statuses_as_sensitive": "Some of your posts have been marked as sensitive.",
|
||||||
|
"notification.moderation_warning.action_none": "Your account has received a moderation warning.",
|
||||||
|
"notification.moderation_warning.action_sensitive": "Your posts will be marked as sensitive from now on.",
|
||||||
|
"notification.moderation_warning.action_silence": "Your account has been limited.",
|
||||||
|
"notification.moderation_warning.action_suspend": "Your account has been suspended.",
|
||||||
"notification.own_poll": "Your poll has ended",
|
"notification.own_poll": "Your poll has ended",
|
||||||
"notification.poll": "A poll you have voted in has ended",
|
"notification.poll": "A poll you have voted in has ended",
|
||||||
"notification.reblog": "{name} boosted your post",
|
"notification.reblog": "{name} boosted your post",
|
||||||
|
|
|
@ -241,7 +241,7 @@
|
||||||
"emoji_button.nature": "Naturaleza",
|
"emoji_button.nature": "Naturaleza",
|
||||||
"emoji_button.not_found": "No se encontraron emojis coincidentes",
|
"emoji_button.not_found": "No se encontraron emojis coincidentes",
|
||||||
"emoji_button.objects": "Objetos",
|
"emoji_button.objects": "Objetos",
|
||||||
"emoji_button.people": "Gente",
|
"emoji_button.people": "Cuentas",
|
||||||
"emoji_button.recent": "Usados frecuentemente",
|
"emoji_button.recent": "Usados frecuentemente",
|
||||||
"emoji_button.search": "Buscar...",
|
"emoji_button.search": "Buscar...",
|
||||||
"emoji_button.search_results": "Resultados de búsqueda",
|
"emoji_button.search_results": "Resultados de búsqueda",
|
||||||
|
@ -308,6 +308,8 @@
|
||||||
"follow_requests.unlocked_explanation": "A pesar de que tu cuenta no es privada, el equipo de {domain} pensó que podrías querer revisar manualmente las solicitudes de seguimiento de estas cuentas.",
|
"follow_requests.unlocked_explanation": "A pesar de que tu cuenta no es privada, el equipo de {domain} pensó que podrías querer revisar manualmente las solicitudes de seguimiento de estas cuentas.",
|
||||||
"follow_suggestions.curated_suggestion": "Selección del equipo",
|
"follow_suggestions.curated_suggestion": "Selección del equipo",
|
||||||
"follow_suggestions.dismiss": "No mostrar de nuevo",
|
"follow_suggestions.dismiss": "No mostrar de nuevo",
|
||||||
|
"follow_suggestions.featured_longer": "Seleccionada a mano por el equipo de {domain}",
|
||||||
|
"follow_suggestions.friends_of_friends_longer": "Populares entre las cuentas que seguís",
|
||||||
"follow_suggestions.hints.featured": "Este perfil fue seleccionado a mano por el equipo de {domain}.",
|
"follow_suggestions.hints.featured": "Este perfil fue seleccionado a mano por el equipo de {domain}.",
|
||||||
"follow_suggestions.hints.friends_of_friends": "Este perfil es popular entre las cuentas que seguís.",
|
"follow_suggestions.hints.friends_of_friends": "Este perfil es popular entre las cuentas que seguís.",
|
||||||
"follow_suggestions.hints.most_followed": "Este perfil es uno de los más seguidos en {domain}.",
|
"follow_suggestions.hints.most_followed": "Este perfil es uno de los más seguidos en {domain}.",
|
||||||
|
@ -315,6 +317,8 @@
|
||||||
"follow_suggestions.hints.similar_to_recently_followed": "Este perfil es similar a los que comenzaste a seguir.",
|
"follow_suggestions.hints.similar_to_recently_followed": "Este perfil es similar a los que comenzaste a seguir.",
|
||||||
"follow_suggestions.personalized_suggestion": "Sugerencia personalizada",
|
"follow_suggestions.personalized_suggestion": "Sugerencia personalizada",
|
||||||
"follow_suggestions.popular_suggestion": "Sugerencia popular",
|
"follow_suggestions.popular_suggestion": "Sugerencia popular",
|
||||||
|
"follow_suggestions.popular_suggestion_longer": "Popular en {domain}",
|
||||||
|
"follow_suggestions.similar_to_recently_followed_longer": "Similares a perfiles que comenzaste a seguir recientemente",
|
||||||
"follow_suggestions.view_all": "Ver todo",
|
"follow_suggestions.view_all": "Ver todo",
|
||||||
"follow_suggestions.who_to_follow": "A quién seguir",
|
"follow_suggestions.who_to_follow": "A quién seguir",
|
||||||
"followed_tags": "Etiquetas seguidas",
|
"followed_tags": "Etiquetas seguidas",
|
||||||
|
@ -469,6 +473,15 @@
|
||||||
"notification.follow": "{name} te empezó a seguir",
|
"notification.follow": "{name} te empezó a seguir",
|
||||||
"notification.follow_request": "{name} solicitó seguirte",
|
"notification.follow_request": "{name} solicitó seguirte",
|
||||||
"notification.mention": "{name} te mencionó",
|
"notification.mention": "{name} te mencionó",
|
||||||
|
"notification.moderation-warning.learn_more": "Aprendé más",
|
||||||
|
"notification.moderation_warning": "Recibiste una advertencia de moderación",
|
||||||
|
"notification.moderation_warning.action_delete_statuses": "Se eliminaron algunos de tus mensajes.",
|
||||||
|
"notification.moderation_warning.action_disable": "Se deshabilitó tu cuenta.",
|
||||||
|
"notification.moderation_warning.action_mark_statuses_as_sensitive": "Se marcaron como sensibles a algunos de tus mensajes.",
|
||||||
|
"notification.moderation_warning.action_none": "Tu cuenta recibió una advertencia de moderación.",
|
||||||
|
"notification.moderation_warning.action_sensitive": "A partir de ahora, tus mensajes serán marcados como sensibles.",
|
||||||
|
"notification.moderation_warning.action_silence": "Tu cuenta fue limitada.",
|
||||||
|
"notification.moderation_warning.action_suspend": "Tu cuenta fue suspendida.",
|
||||||
"notification.own_poll": "Tu encuesta finalizó",
|
"notification.own_poll": "Tu encuesta finalizó",
|
||||||
"notification.poll": "Finalizó una encuesta en la que votaste",
|
"notification.poll": "Finalizó una encuesta en la que votaste",
|
||||||
"notification.reblog": "{name} adhirió a tu mensaje",
|
"notification.reblog": "{name} adhirió a tu mensaje",
|
||||||
|
|
|
@ -308,6 +308,8 @@
|
||||||
"follow_requests.unlocked_explanation": "A pesar de que tu cuenta no es privada, el personal de {domain} ha pensado que quizás deberías revisar manualmente las solicitudes de seguimiento de estas cuentas.",
|
"follow_requests.unlocked_explanation": "A pesar de que tu cuenta no es privada, el personal de {domain} ha pensado que quizás deberías revisar manualmente las solicitudes de seguimiento de estas cuentas.",
|
||||||
"follow_suggestions.curated_suggestion": "Recomendaciones del equipo",
|
"follow_suggestions.curated_suggestion": "Recomendaciones del equipo",
|
||||||
"follow_suggestions.dismiss": "No mostrar de nuevo",
|
"follow_suggestions.dismiss": "No mostrar de nuevo",
|
||||||
|
"follow_suggestions.featured_longer": "Escogidos por el equipo de {domain}",
|
||||||
|
"follow_suggestions.friends_of_friends_longer": "Populares entre las personas a las que sigues",
|
||||||
"follow_suggestions.hints.featured": "Este perfil ha sido seleccionado a mano por el equipo de {domain}.",
|
"follow_suggestions.hints.featured": "Este perfil ha sido seleccionado a mano por el equipo de {domain}.",
|
||||||
"follow_suggestions.hints.friends_of_friends": "Este perfil es popular entre las personas que sigues.",
|
"follow_suggestions.hints.friends_of_friends": "Este perfil es popular entre las personas que sigues.",
|
||||||
"follow_suggestions.hints.most_followed": "Este perfil es uno de los más seguidos en {domain}.",
|
"follow_suggestions.hints.most_followed": "Este perfil es uno de los más seguidos en {domain}.",
|
||||||
|
@ -315,6 +317,8 @@
|
||||||
"follow_suggestions.hints.similar_to_recently_followed": "Este perfil es similar a los perfiles que has seguido recientemente.",
|
"follow_suggestions.hints.similar_to_recently_followed": "Este perfil es similar a los perfiles que has seguido recientemente.",
|
||||||
"follow_suggestions.personalized_suggestion": "Sugerencia personalizada",
|
"follow_suggestions.personalized_suggestion": "Sugerencia personalizada",
|
||||||
"follow_suggestions.popular_suggestion": "Sugerencia popular",
|
"follow_suggestions.popular_suggestion": "Sugerencia popular",
|
||||||
|
"follow_suggestions.popular_suggestion_longer": "Populares en {domain}",
|
||||||
|
"follow_suggestions.similar_to_recently_followed_longer": "Similares a los perfiles que has seguido recientemente",
|
||||||
"follow_suggestions.view_all": "Ver todo",
|
"follow_suggestions.view_all": "Ver todo",
|
||||||
"follow_suggestions.who_to_follow": "Recomendamos seguir",
|
"follow_suggestions.who_to_follow": "Recomendamos seguir",
|
||||||
"followed_tags": "Hashtags seguidos",
|
"followed_tags": "Hashtags seguidos",
|
||||||
|
@ -469,6 +473,15 @@
|
||||||
"notification.follow": "{name} te empezó a seguir",
|
"notification.follow": "{name} te empezó a seguir",
|
||||||
"notification.follow_request": "{name} ha solicitado seguirte",
|
"notification.follow_request": "{name} ha solicitado seguirte",
|
||||||
"notification.mention": "{name} te ha mencionado",
|
"notification.mention": "{name} te ha mencionado",
|
||||||
|
"notification.moderation-warning.learn_more": "Saber más",
|
||||||
|
"notification.moderation_warning": "Has recibido una advertencia de moderación",
|
||||||
|
"notification.moderation_warning.action_delete_statuses": "Se han eliminado algunas de tus publicaciones.",
|
||||||
|
"notification.moderation_warning.action_disable": "Se ha desactivado su cuenta.",
|
||||||
|
"notification.moderation_warning.action_mark_statuses_as_sensitive": "Se han marcado como sensibles algunas de tus publicaciones.",
|
||||||
|
"notification.moderation_warning.action_none": "Tu cuenta ha recibido un aviso de moderación.",
|
||||||
|
"notification.moderation_warning.action_sensitive": "De ahora en adelante, todas tus publicaciones se marcarán como sensibles.",
|
||||||
|
"notification.moderation_warning.action_silence": "Se ha limitado tu cuenta.",
|
||||||
|
"notification.moderation_warning.action_suspend": "Se ha suspendido tu cuenta.",
|
||||||
"notification.own_poll": "Tu encuesta ha terminado",
|
"notification.own_poll": "Tu encuesta ha terminado",
|
||||||
"notification.poll": "Una encuesta en la que has votado ha terminado",
|
"notification.poll": "Una encuesta en la que has votado ha terminado",
|
||||||
"notification.reblog": "{name} ha retooteado tu estado",
|
"notification.reblog": "{name} ha retooteado tu estado",
|
||||||
|
|
|
@ -308,6 +308,8 @@
|
||||||
"follow_requests.unlocked_explanation": "A pesar de que tu cuenta no es privada, el personal de {domain} ha pensado que quizás deberías revisar manualmente las solicitudes de seguimiento de estas cuentas.",
|
"follow_requests.unlocked_explanation": "A pesar de que tu cuenta no es privada, el personal de {domain} ha pensado que quizás deberías revisar manualmente las solicitudes de seguimiento de estas cuentas.",
|
||||||
"follow_suggestions.curated_suggestion": "Recomendaciones del equipo",
|
"follow_suggestions.curated_suggestion": "Recomendaciones del equipo",
|
||||||
"follow_suggestions.dismiss": "No mostrar de nuevo",
|
"follow_suggestions.dismiss": "No mostrar de nuevo",
|
||||||
|
"follow_suggestions.featured_longer": "Escogidos por el equipo de {domain}",
|
||||||
|
"follow_suggestions.friends_of_friends_longer": "Populares entre las personas a las que sigues",
|
||||||
"follow_suggestions.hints.featured": "Este perfil ha sido elegido a mano por el equipo de {domain}.",
|
"follow_suggestions.hints.featured": "Este perfil ha sido elegido a mano por el equipo de {domain}.",
|
||||||
"follow_suggestions.hints.friends_of_friends": "Este perfil es popular entre las personas que sigues.",
|
"follow_suggestions.hints.friends_of_friends": "Este perfil es popular entre las personas que sigues.",
|
||||||
"follow_suggestions.hints.most_followed": "Este perfil es uno de los más seguidos en {domain}.",
|
"follow_suggestions.hints.most_followed": "Este perfil es uno de los más seguidos en {domain}.",
|
||||||
|
@ -315,6 +317,8 @@
|
||||||
"follow_suggestions.hints.similar_to_recently_followed": "Este perfil es similar a los perfiles que has seguido recientemente.",
|
"follow_suggestions.hints.similar_to_recently_followed": "Este perfil es similar a los perfiles que has seguido recientemente.",
|
||||||
"follow_suggestions.personalized_suggestion": "Sugerencia personalizada",
|
"follow_suggestions.personalized_suggestion": "Sugerencia personalizada",
|
||||||
"follow_suggestions.popular_suggestion": "Sugerencia popular",
|
"follow_suggestions.popular_suggestion": "Sugerencia popular",
|
||||||
|
"follow_suggestions.popular_suggestion_longer": "Populares en {domain}",
|
||||||
|
"follow_suggestions.similar_to_recently_followed_longer": "Similares a los perfiles que has seguido recientemente",
|
||||||
"follow_suggestions.view_all": "Ver todo",
|
"follow_suggestions.view_all": "Ver todo",
|
||||||
"follow_suggestions.who_to_follow": "A quién seguir",
|
"follow_suggestions.who_to_follow": "A quién seguir",
|
||||||
"followed_tags": "Etiquetas seguidas",
|
"followed_tags": "Etiquetas seguidas",
|
||||||
|
@ -469,6 +473,15 @@
|
||||||
"notification.follow": "{name} te empezó a seguir",
|
"notification.follow": "{name} te empezó a seguir",
|
||||||
"notification.follow_request": "{name} ha solicitado seguirte",
|
"notification.follow_request": "{name} ha solicitado seguirte",
|
||||||
"notification.mention": "{name} te ha mencionado",
|
"notification.mention": "{name} te ha mencionado",
|
||||||
|
"notification.moderation-warning.learn_more": "Saber más",
|
||||||
|
"notification.moderation_warning": "Has recibido una advertencia de moderación",
|
||||||
|
"notification.moderation_warning.action_delete_statuses": "Se han eliminado algunas de tus publicaciones.",
|
||||||
|
"notification.moderation_warning.action_disable": "Se ha desactivado su cuenta.",
|
||||||
|
"notification.moderation_warning.action_mark_statuses_as_sensitive": "Se han marcado como sensibles algunas de tus publicaciones.",
|
||||||
|
"notification.moderation_warning.action_none": "Tu cuenta ha recibido un aviso de moderación.",
|
||||||
|
"notification.moderation_warning.action_sensitive": "De ahora en adelante, todas tus publicaciones se marcarán como sensibles.",
|
||||||
|
"notification.moderation_warning.action_silence": "Se ha limitado tu cuenta.",
|
||||||
|
"notification.moderation_warning.action_suspend": "Se ha suspendido tu cuenta.",
|
||||||
"notification.own_poll": "Tu encuesta ha terminado",
|
"notification.own_poll": "Tu encuesta ha terminado",
|
||||||
"notification.poll": "Una encuesta en la que has votado ha terminado",
|
"notification.poll": "Una encuesta en la que has votado ha terminado",
|
||||||
"notification.reblog": "{name} ha impulsado tu publicación",
|
"notification.reblog": "{name} ha impulsado tu publicación",
|
||||||
|
|
|
@ -308,6 +308,8 @@
|
||||||
"follow_requests.unlocked_explanation": "Zure kontua blokeatuta ez badago ere, {domain} domeinuko arduradunek uste dute kontu hauetako jarraipen eskaerak agian eskuz begiratu nahiko dituzula.",
|
"follow_requests.unlocked_explanation": "Zure kontua blokeatuta ez badago ere, {domain} domeinuko arduradunek uste dute kontu hauetako jarraipen eskaerak agian eskuz begiratu nahiko dituzula.",
|
||||||
"follow_suggestions.curated_suggestion": "Domeinuaren iradokizuna",
|
"follow_suggestions.curated_suggestion": "Domeinuaren iradokizuna",
|
||||||
"follow_suggestions.dismiss": "Ez erakutsi berriro",
|
"follow_suggestions.dismiss": "Ez erakutsi berriro",
|
||||||
|
"follow_suggestions.featured_longer": "{domain} domeinuko taldeak hautaturikoak",
|
||||||
|
"follow_suggestions.friends_of_friends_longer": "Jarraitzen duzun jendearen artean ezagunak direnak",
|
||||||
"follow_suggestions.hints.featured": "Profil hau {domain} domeinuko taldeak eskuz aukeratu du.",
|
"follow_suggestions.hints.featured": "Profil hau {domain} domeinuko taldeak eskuz aukeratu du.",
|
||||||
"follow_suggestions.hints.friends_of_friends": "Profil hau ezaguna da jarraitzen duzun jendearen artean.",
|
"follow_suggestions.hints.friends_of_friends": "Profil hau ezaguna da jarraitzen duzun jendearen artean.",
|
||||||
"follow_suggestions.hints.most_followed": "Profil hau {domain} domeinuan gehien jarraitzen den profiletako bat da.",
|
"follow_suggestions.hints.most_followed": "Profil hau {domain} domeinuan gehien jarraitzen den profiletako bat da.",
|
||||||
|
@ -315,6 +317,8 @@
|
||||||
"follow_suggestions.hints.similar_to_recently_followed": "Profil hau duela gutxi jarraitu dituzun profil askoren antzekoa da.",
|
"follow_suggestions.hints.similar_to_recently_followed": "Profil hau duela gutxi jarraitu dituzun profil askoren antzekoa da.",
|
||||||
"follow_suggestions.personalized_suggestion": "Iradokizun pertsonalizatua",
|
"follow_suggestions.personalized_suggestion": "Iradokizun pertsonalizatua",
|
||||||
"follow_suggestions.popular_suggestion": "Iradokizun ezaguna",
|
"follow_suggestions.popular_suggestion": "Iradokizun ezaguna",
|
||||||
|
"follow_suggestions.popular_suggestion_longer": "{domain} domeinuan ezagunak direnak",
|
||||||
|
"follow_suggestions.similar_to_recently_followed_longer": "Berriki jarraitu dituzun profilen antzekoa",
|
||||||
"follow_suggestions.view_all": "Ikusi denak",
|
"follow_suggestions.view_all": "Ikusi denak",
|
||||||
"follow_suggestions.who_to_follow": "Zein jarraitu",
|
"follow_suggestions.who_to_follow": "Zein jarraitu",
|
||||||
"followed_tags": "Jarraitutako traolak",
|
"followed_tags": "Jarraitutako traolak",
|
||||||
|
@ -469,6 +473,15 @@
|
||||||
"notification.follow": "{name}(e)k jarraitzen dizu",
|
"notification.follow": "{name}(e)k jarraitzen dizu",
|
||||||
"notification.follow_request": "{name}(e)k zu jarraitzeko eskaera egin du",
|
"notification.follow_request": "{name}(e)k zu jarraitzeko eskaera egin du",
|
||||||
"notification.mention": "{name}(e)k aipatu zaitu",
|
"notification.mention": "{name}(e)k aipatu zaitu",
|
||||||
|
"notification.moderation-warning.learn_more": "Informazio gehiago",
|
||||||
|
"notification.moderation_warning": "Moderazio-abisu bat jaso duzu",
|
||||||
|
"notification.moderation_warning.action_delete_statuses": "Argitalpen batzuk kendu dira.",
|
||||||
|
"notification.moderation_warning.action_disable": "Zure kontua desaktibatua izan da.",
|
||||||
|
"notification.moderation_warning.action_mark_statuses_as_sensitive": "Argitalpen batzuk hunkigarri gisa ezarri dira.",
|
||||||
|
"notification.moderation_warning.action_none": "Kontuak moderazio-abisu bat jaso du.",
|
||||||
|
"notification.moderation_warning.action_sensitive": "Argitalpenak hunkigarri gisa markatuko dira hemendik aurrera.",
|
||||||
|
"notification.moderation_warning.action_silence": "Kontua murriztu egin da.",
|
||||||
|
"notification.moderation_warning.action_suspend": "Kontua itxi da.",
|
||||||
"notification.own_poll": "Zure inkesta amaitu da",
|
"notification.own_poll": "Zure inkesta amaitu da",
|
||||||
"notification.poll": "Zuk erantzun duzun inkesta bat bukatu da",
|
"notification.poll": "Zuk erantzun duzun inkesta bat bukatu da",
|
||||||
"notification.reblog": "{name}(e)k bultzada eman dio zure bidalketari",
|
"notification.reblog": "{name}(e)k bultzada eman dio zure bidalketari",
|
||||||
|
|
|
@ -308,6 +308,8 @@
|
||||||
"follow_requests.unlocked_explanation": "Vaikkei tiliäsi ole lukittu, palvelimen {domain} ylläpito on arvioinut, että saatat olla halukas tarkistamaan nämä seuraamispyynnöt erikseen.",
|
"follow_requests.unlocked_explanation": "Vaikkei tiliäsi ole lukittu, palvelimen {domain} ylläpito on arvioinut, että saatat olla halukas tarkistamaan nämä seuraamispyynnöt erikseen.",
|
||||||
"follow_suggestions.curated_suggestion": "Ehdotus ylläpidolta",
|
"follow_suggestions.curated_suggestion": "Ehdotus ylläpidolta",
|
||||||
"follow_suggestions.dismiss": "Älä näytä uudelleen",
|
"follow_suggestions.dismiss": "Älä näytä uudelleen",
|
||||||
|
"follow_suggestions.featured_longer": "Käsin valinnut palvelimen {domain} tiimi",
|
||||||
|
"follow_suggestions.friends_of_friends_longer": "Suosittu seuraamiesi ihmisten keskuudessa",
|
||||||
"follow_suggestions.hints.featured": "Tämän profiilin on valinnut palvelimen {domain} tiimi.",
|
"follow_suggestions.hints.featured": "Tämän profiilin on valinnut palvelimen {domain} tiimi.",
|
||||||
"follow_suggestions.hints.friends_of_friends": "Seuraamasi käyttäjät suosivat tätä profiilia.",
|
"follow_suggestions.hints.friends_of_friends": "Seuraamasi käyttäjät suosivat tätä profiilia.",
|
||||||
"follow_suggestions.hints.most_followed": "Tämä profiili on palvelimen {domain} seuratuimpia.",
|
"follow_suggestions.hints.most_followed": "Tämä profiili on palvelimen {domain} seuratuimpia.",
|
||||||
|
@ -315,6 +317,8 @@
|
||||||
"follow_suggestions.hints.similar_to_recently_followed": "Tämä profiili on samankaltainen kuin profiilit, joita olet viimeksi seurannut.",
|
"follow_suggestions.hints.similar_to_recently_followed": "Tämä profiili on samankaltainen kuin profiilit, joita olet viimeksi seurannut.",
|
||||||
"follow_suggestions.personalized_suggestion": "Mukautettu ehdotus",
|
"follow_suggestions.personalized_suggestion": "Mukautettu ehdotus",
|
||||||
"follow_suggestions.popular_suggestion": "Suosittu ehdotus",
|
"follow_suggestions.popular_suggestion": "Suosittu ehdotus",
|
||||||
|
"follow_suggestions.popular_suggestion_longer": "Suosittu palvelimella {domain}",
|
||||||
|
"follow_suggestions.similar_to_recently_followed_longer": "Samankaltainen kuin äskettäin seuraamasi profiilit",
|
||||||
"follow_suggestions.view_all": "Näytä kaikki",
|
"follow_suggestions.view_all": "Näytä kaikki",
|
||||||
"follow_suggestions.who_to_follow": "Ehdotuksia seurattavaksi",
|
"follow_suggestions.who_to_follow": "Ehdotuksia seurattavaksi",
|
||||||
"followed_tags": "Seuratut aihetunnisteet",
|
"followed_tags": "Seuratut aihetunnisteet",
|
||||||
|
@ -469,6 +473,15 @@
|
||||||
"notification.follow": "{name} seurasi sinua",
|
"notification.follow": "{name} seurasi sinua",
|
||||||
"notification.follow_request": "{name} on pyytänyt lupaa saada seurata sinua",
|
"notification.follow_request": "{name} on pyytänyt lupaa saada seurata sinua",
|
||||||
"notification.mention": "{name} mainitsi sinut",
|
"notification.mention": "{name} mainitsi sinut",
|
||||||
|
"notification.moderation-warning.learn_more": "Lue lisää",
|
||||||
|
"notification.moderation_warning": "Olet saanut moderointivaroituksen",
|
||||||
|
"notification.moderation_warning.action_delete_statuses": "Jotkin julkaisusi on poistettu.",
|
||||||
|
"notification.moderation_warning.action_disable": "Tilisi on poistettu käytöstä.",
|
||||||
|
"notification.moderation_warning.action_mark_statuses_as_sensitive": "Jotkin julkaisusi on merkitty arkaluonteisiksi.",
|
||||||
|
"notification.moderation_warning.action_none": "Tilisi on saanut moderointivaroituksen.",
|
||||||
|
"notification.moderation_warning.action_sensitive": "Tästä lähtien julkaisusi merkitään arkaluonteisiksi.",
|
||||||
|
"notification.moderation_warning.action_silence": "Tiliäsi on rajoitettu.",
|
||||||
|
"notification.moderation_warning.action_suspend": "Tilisi on jäädytetty.",
|
||||||
"notification.own_poll": "Äänestyksesi on päättynyt",
|
"notification.own_poll": "Äänestyksesi on päättynyt",
|
||||||
"notification.poll": "Kysely, johon osallistuit, on päättynyt",
|
"notification.poll": "Kysely, johon osallistuit, on päättynyt",
|
||||||
"notification.reblog": "{name} tehosti julkaisuasi",
|
"notification.reblog": "{name} tehosti julkaisuasi",
|
||||||
|
|
|
@ -308,6 +308,8 @@
|
||||||
"follow_requests.unlocked_explanation": "Sjálvt um konta tín ikki er læst, so hugsa {domain} starvsfólkini, at tú kanska hevur hug at kanna umbønir um at fylgja frá hesum kontum við hond.",
|
"follow_requests.unlocked_explanation": "Sjálvt um konta tín ikki er læst, so hugsa {domain} starvsfólkini, at tú kanska hevur hug at kanna umbønir um at fylgja frá hesum kontum við hond.",
|
||||||
"follow_suggestions.curated_suggestion": "Val hjá ábyrgdarfólki",
|
"follow_suggestions.curated_suggestion": "Val hjá ábyrgdarfólki",
|
||||||
"follow_suggestions.dismiss": "Lat vera við at vísa",
|
"follow_suggestions.dismiss": "Lat vera við at vísa",
|
||||||
|
"follow_suggestions.featured_longer": "Vald burturúr av {domain} toyminum",
|
||||||
|
"follow_suggestions.friends_of_friends_longer": "Vælumtókt millum fólk, sum tú fylgir",
|
||||||
"follow_suggestions.hints.featured": "Hesin vangin er úrvaldur av toyminum handan {domain}.",
|
"follow_suggestions.hints.featured": "Hesin vangin er úrvaldur av toyminum handan {domain}.",
|
||||||
"follow_suggestions.hints.friends_of_friends": "Hesin vangin er vælumtóktur millum tey, tú fylgir.",
|
"follow_suggestions.hints.friends_of_friends": "Hesin vangin er vælumtóktur millum tey, tú fylgir.",
|
||||||
"follow_suggestions.hints.most_followed": "Hesin vangin er ein av teimum, sum er mest fylgdur á {domain}.",
|
"follow_suggestions.hints.most_followed": "Hesin vangin er ein av teimum, sum er mest fylgdur á {domain}.",
|
||||||
|
@ -315,6 +317,8 @@
|
||||||
"follow_suggestions.hints.similar_to_recently_followed": "Hesin vangin líkist teimum, sum tú nýliga hevur fylgt.",
|
"follow_suggestions.hints.similar_to_recently_followed": "Hesin vangin líkist teimum, sum tú nýliga hevur fylgt.",
|
||||||
"follow_suggestions.personalized_suggestion": "Persónligt uppskot",
|
"follow_suggestions.personalized_suggestion": "Persónligt uppskot",
|
||||||
"follow_suggestions.popular_suggestion": "Vælumtókt uppskot",
|
"follow_suggestions.popular_suggestion": "Vælumtókt uppskot",
|
||||||
|
"follow_suggestions.popular_suggestion_longer": "Vælumtókt á {domain}",
|
||||||
|
"follow_suggestions.similar_to_recently_followed_longer": "Líkist vangum, sum tú nýliga hevur fylgt",
|
||||||
"follow_suggestions.view_all": "Vís øll",
|
"follow_suggestions.view_all": "Vís øll",
|
||||||
"follow_suggestions.who_to_follow": "Hvørji tú átti at fylgt",
|
"follow_suggestions.who_to_follow": "Hvørji tú átti at fylgt",
|
||||||
"followed_tags": "Fylgd frámerki",
|
"followed_tags": "Fylgd frámerki",
|
||||||
|
@ -469,6 +473,15 @@
|
||||||
"notification.follow": "{name} fylgdi tær",
|
"notification.follow": "{name} fylgdi tær",
|
||||||
"notification.follow_request": "{name} biður um at fylgja tær",
|
"notification.follow_request": "{name} biður um at fylgja tær",
|
||||||
"notification.mention": "{name} nevndi teg",
|
"notification.mention": "{name} nevndi teg",
|
||||||
|
"notification.moderation-warning.learn_more": "Lær meira",
|
||||||
|
"notification.moderation_warning": "Tú hevur móttikið eina umsjónarávarðing",
|
||||||
|
"notification.moderation_warning.action_delete_statuses": "Onkrir av tínum postum eru strikaðir.",
|
||||||
|
"notification.moderation_warning.action_disable": "Konta tín er gjørd óvirkin.",
|
||||||
|
"notification.moderation_warning.action_mark_statuses_as_sensitive": "Nakrir av postum tínum eru merktir sum viðkvæmir.",
|
||||||
|
"notification.moderation_warning.action_none": "Konta tín hevur móttikið eina umsjónarávarðing.",
|
||||||
|
"notification.moderation_warning.action_sensitive": "Postar tínir verða merktir sum viðkvæmir frá nú av.",
|
||||||
|
"notification.moderation_warning.action_silence": "Konta tín er avmarkað.",
|
||||||
|
"notification.moderation_warning.action_suspend": "Konta tín er ógildað.",
|
||||||
"notification.own_poll": "Tín atkvøðugreiðsla er endað",
|
"notification.own_poll": "Tín atkvøðugreiðsla er endað",
|
||||||
"notification.poll": "Ein atkvøðugreiðsla, har tú hevur atkvøtt, er endað",
|
"notification.poll": "Ein atkvøðugreiðsla, har tú hevur atkvøtt, er endað",
|
||||||
"notification.reblog": "{name} lyfti tín post",
|
"notification.reblog": "{name} lyfti tín post",
|
||||||
|
|
|
@ -297,6 +297,7 @@
|
||||||
"filter_modal.select_filter.subtitle": "Cleachd roinn-seòrsa a tha ann no cruthaich tè ùr",
|
"filter_modal.select_filter.subtitle": "Cleachd roinn-seòrsa a tha ann no cruthaich tè ùr",
|
||||||
"filter_modal.select_filter.title": "Criathraich am post seo",
|
"filter_modal.select_filter.title": "Criathraich am post seo",
|
||||||
"filter_modal.title.status": "Criathraich post",
|
"filter_modal.title.status": "Criathraich post",
|
||||||
|
"filtered_notifications_banner.mentions": "{count, plural, one {iomradh} two {iomradh} few {iomraidhean} other {iomradh}}",
|
||||||
"filtered_notifications_banner.pending_requests": "{count, plural, =0 {Chan eil brath ann o dhaoine} one {Tha brathan ann o # neach} two {Tha brathan ann o # neach} few {Tha brathan ann o # daoine} other {Tha brathan ann o # duine}} air a bheil thu eòlach ’s dòcha",
|
"filtered_notifications_banner.pending_requests": "{count, plural, =0 {Chan eil brath ann o dhaoine} one {Tha brathan ann o # neach} two {Tha brathan ann o # neach} few {Tha brathan ann o # daoine} other {Tha brathan ann o # duine}} air a bheil thu eòlach ’s dòcha",
|
||||||
"filtered_notifications_banner.title": "Brathan criathraichte",
|
"filtered_notifications_banner.title": "Brathan criathraichte",
|
||||||
"firehose.all": "Na h-uile",
|
"firehose.all": "Na h-uile",
|
||||||
|
@ -307,6 +308,7 @@
|
||||||
"follow_requests.unlocked_explanation": "Ged nach eil an cunntas agad glaiste, tha sgioba {domain} dhen bheachd gum b’ fheàirrde thu lèirmheas a dhèanamh air na h-iarrtasan leantainn o na cunntasan seo a làimh.",
|
"follow_requests.unlocked_explanation": "Ged nach eil an cunntas agad glaiste, tha sgioba {domain} dhen bheachd gum b’ fheàirrde thu lèirmheas a dhèanamh air na h-iarrtasan leantainn o na cunntasan seo a làimh.",
|
||||||
"follow_suggestions.curated_suggestion": "Roghainn an sgioba",
|
"follow_suggestions.curated_suggestion": "Roghainn an sgioba",
|
||||||
"follow_suggestions.dismiss": "Na seall seo a-rithist",
|
"follow_suggestions.dismiss": "Na seall seo a-rithist",
|
||||||
|
"follow_suggestions.friends_of_friends_longer": "Fèill mhòr am measg nan daoine a leanas tu",
|
||||||
"follow_suggestions.hints.featured": "Chaidh a’ phròifil seo a thaghadh le sgioba {domain} a làimh.",
|
"follow_suggestions.hints.featured": "Chaidh a’ phròifil seo a thaghadh le sgioba {domain} a làimh.",
|
||||||
"follow_suggestions.hints.friends_of_friends": "Tha fèill mhòr air a’ phròifil seo am measg nan daoine a leanas tu.",
|
"follow_suggestions.hints.friends_of_friends": "Tha fèill mhòr air a’ phròifil seo am measg nan daoine a leanas tu.",
|
||||||
"follow_suggestions.hints.most_followed": "Tha a’ phròifil seo am measg an fheadhainn a leanar as trice air {domain}.",
|
"follow_suggestions.hints.most_followed": "Tha a’ phròifil seo am measg an fheadhainn a leanar as trice air {domain}.",
|
||||||
|
@ -314,6 +316,7 @@
|
||||||
"follow_suggestions.hints.similar_to_recently_followed": "Tha a’ phròifil seo coltach ris na pròifilean air an lean thu o chionn goirid.",
|
"follow_suggestions.hints.similar_to_recently_followed": "Tha a’ phròifil seo coltach ris na pròifilean air an lean thu o chionn goirid.",
|
||||||
"follow_suggestions.personalized_suggestion": "Moladh pearsanaichte",
|
"follow_suggestions.personalized_suggestion": "Moladh pearsanaichte",
|
||||||
"follow_suggestions.popular_suggestion": "Moladh air a bheil fèill mhòr",
|
"follow_suggestions.popular_suggestion": "Moladh air a bheil fèill mhòr",
|
||||||
|
"follow_suggestions.popular_suggestion_longer": "Fèill mhòr air {domain}",
|
||||||
"follow_suggestions.view_all": "Seall na h-uile",
|
"follow_suggestions.view_all": "Seall na h-uile",
|
||||||
"follow_suggestions.who_to_follow": "Molaidhean leantainn",
|
"follow_suggestions.who_to_follow": "Molaidhean leantainn",
|
||||||
"followed_tags": "Tagaichean hais ’gan leantainn",
|
"followed_tags": "Tagaichean hais ’gan leantainn",
|
||||||
|
@ -468,6 +471,7 @@
|
||||||
"notification.follow": "Tha {name} ’gad leantainn a-nis",
|
"notification.follow": "Tha {name} ’gad leantainn a-nis",
|
||||||
"notification.follow_request": "Dh’iarr {name} ’gad leantainn",
|
"notification.follow_request": "Dh’iarr {name} ’gad leantainn",
|
||||||
"notification.mention": "Thug {name} iomradh ort",
|
"notification.mention": "Thug {name} iomradh ort",
|
||||||
|
"notification.moderation-warning.learn_more": "Barrachd fiosrachaidh",
|
||||||
"notification.own_poll": "Thàinig an cunntas-bheachd agad gu crìoch",
|
"notification.own_poll": "Thàinig an cunntas-bheachd agad gu crìoch",
|
||||||
"notification.poll": "Thàinig cunntas-bheachd sa bhòt thu gu crìoch",
|
"notification.poll": "Thàinig cunntas-bheachd sa bhòt thu gu crìoch",
|
||||||
"notification.reblog": "Bhrosnaich {name} am post agad",
|
"notification.reblog": "Bhrosnaich {name} am post agad",
|
||||||
|
|
|
@ -308,6 +308,8 @@
|
||||||
"follow_requests.unlocked_explanation": "Malia que a túa conta non é privada, a administración de {domain} pensou que quizabes terías que revisar de xeito manual as solicitudes de seguiminto.",
|
"follow_requests.unlocked_explanation": "Malia que a túa conta non é privada, a administración de {domain} pensou que quizabes terías que revisar de xeito manual as solicitudes de seguiminto.",
|
||||||
"follow_suggestions.curated_suggestion": "Suxestións do Servidor",
|
"follow_suggestions.curated_suggestion": "Suxestións do Servidor",
|
||||||
"follow_suggestions.dismiss": "Non mostrar máis",
|
"follow_suggestions.dismiss": "Non mostrar máis",
|
||||||
|
"follow_suggestions.featured_longer": "Elección persoal do equipo de {domain}",
|
||||||
|
"follow_suggestions.friends_of_friends_longer": "Popular entre as persoas que sigues",
|
||||||
"follow_suggestions.hints.featured": "Este perfil foi escollido pola administración de {domain}.",
|
"follow_suggestions.hints.featured": "Este perfil foi escollido pola administración de {domain}.",
|
||||||
"follow_suggestions.hints.friends_of_friends": "Este perfil é popular entre as persoas que segues.",
|
"follow_suggestions.hints.friends_of_friends": "Este perfil é popular entre as persoas que segues.",
|
||||||
"follow_suggestions.hints.most_followed": "Este perfil é un dos máis seguidos en {domain}.",
|
"follow_suggestions.hints.most_followed": "Este perfil é un dos máis seguidos en {domain}.",
|
||||||
|
@ -315,6 +317,8 @@
|
||||||
"follow_suggestions.hints.similar_to_recently_followed": "Este perfil ten semellanzas cos perfís que ti seguiches últimamente.",
|
"follow_suggestions.hints.similar_to_recently_followed": "Este perfil ten semellanzas cos perfís que ti seguiches últimamente.",
|
||||||
"follow_suggestions.personalized_suggestion": "Suxestión personalizada",
|
"follow_suggestions.personalized_suggestion": "Suxestión personalizada",
|
||||||
"follow_suggestions.popular_suggestion": "Suxestión popular",
|
"follow_suggestions.popular_suggestion": "Suxestión popular",
|
||||||
|
"follow_suggestions.popular_suggestion_longer": "Popular en {domain}",
|
||||||
|
"follow_suggestions.similar_to_recently_followed_longer": "Perfís semellantes aos que seguiches recentemente",
|
||||||
"follow_suggestions.view_all": "Ver todas",
|
"follow_suggestions.view_all": "Ver todas",
|
||||||
"follow_suggestions.who_to_follow": "A quen seguir",
|
"follow_suggestions.who_to_follow": "A quen seguir",
|
||||||
"followed_tags": "Cancelos seguidos",
|
"followed_tags": "Cancelos seguidos",
|
||||||
|
@ -469,6 +473,15 @@
|
||||||
"notification.follow": "{name} comezou a seguirte",
|
"notification.follow": "{name} comezou a seguirte",
|
||||||
"notification.follow_request": "{name} solicitou seguirte",
|
"notification.follow_request": "{name} solicitou seguirte",
|
||||||
"notification.mention": "{name} mencionoute",
|
"notification.mention": "{name} mencionoute",
|
||||||
|
"notification.moderation-warning.learn_more": "Saber máis",
|
||||||
|
"notification.moderation_warning": "Recibiches unha advertencia da moderación",
|
||||||
|
"notification.moderation_warning.action_delete_statuses": "Algunha das túas publicacións foron eliminadas.",
|
||||||
|
"notification.moderation_warning.action_disable": "A túa conta foi desactivada.",
|
||||||
|
"notification.moderation_warning.action_mark_statuses_as_sensitive": "Algunha das túas publicacións foron marcadas como sensibles.",
|
||||||
|
"notification.moderation_warning.action_none": "A túa conta recibeu unha advertencia da moderación.",
|
||||||
|
"notification.moderation_warning.action_sensitive": "De agora en diante as túas publicacións van ser marcadas como sensibles.",
|
||||||
|
"notification.moderation_warning.action_silence": "A túa conta foi limitada.",
|
||||||
|
"notification.moderation_warning.action_suspend": "A túa conta foi suspendida.",
|
||||||
"notification.own_poll": "A túa enquisa rematou",
|
"notification.own_poll": "A túa enquisa rematou",
|
||||||
"notification.poll": "Rematou a enquisa na que votaches",
|
"notification.poll": "Rematou a enquisa na que votaches",
|
||||||
"notification.reblog": "{name} compartiu a túa publicación",
|
"notification.reblog": "{name} compartiu a túa publicación",
|
||||||
|
|
|
@ -308,6 +308,8 @@
|
||||||
"follow_requests.unlocked_explanation": "למרות שחשבונך אינו נעול, צוות {domain} חושב שאולי כדאי לוודא את בקשות המעקב האלה ידנית.",
|
"follow_requests.unlocked_explanation": "למרות שחשבונך אינו נעול, צוות {domain} חושב שאולי כדאי לוודא את בקשות המעקב האלה ידנית.",
|
||||||
"follow_suggestions.curated_suggestion": "בחירת הצוות",
|
"follow_suggestions.curated_suggestion": "בחירת הצוות",
|
||||||
"follow_suggestions.dismiss": "לא להציג שוב",
|
"follow_suggestions.dismiss": "לא להציג שוב",
|
||||||
|
"follow_suggestions.featured_longer": "נבחר ידנית על ידי הצוות של {domain}",
|
||||||
|
"follow_suggestions.friends_of_friends_longer": "פופולרי בין הנעקבים שלך",
|
||||||
"follow_suggestions.hints.featured": "החשבון הזה נבחר אישית על ידי צוות {domain}.",
|
"follow_suggestions.hints.featured": "החשבון הזה נבחר אישית על ידי צוות {domain}.",
|
||||||
"follow_suggestions.hints.friends_of_friends": "חשבון זה פופולרי בין הנעקבים שלך.",
|
"follow_suggestions.hints.friends_of_friends": "חשבון זה פופולרי בין הנעקבים שלך.",
|
||||||
"follow_suggestions.hints.most_followed": "חשבון זה הוא מבין הנעקבים ביותר בשרת {domain}.",
|
"follow_suggestions.hints.most_followed": "חשבון זה הוא מבין הנעקבים ביותר בשרת {domain}.",
|
||||||
|
@ -315,6 +317,8 @@
|
||||||
"follow_suggestions.hints.similar_to_recently_followed": "חשבון זה דומה לחשבונות אחרים שאחריהם התחלת לעקוב לאחרונה.",
|
"follow_suggestions.hints.similar_to_recently_followed": "חשבון זה דומה לחשבונות אחרים שאחריהם התחלת לעקוב לאחרונה.",
|
||||||
"follow_suggestions.personalized_suggestion": "הצעות מותאמות אישית",
|
"follow_suggestions.personalized_suggestion": "הצעות מותאמות אישית",
|
||||||
"follow_suggestions.popular_suggestion": "הצעה פופולרית",
|
"follow_suggestions.popular_suggestion": "הצעה פופולרית",
|
||||||
|
"follow_suggestions.popular_suggestion_longer": "פופולרי בקהילת {domain}",
|
||||||
|
"follow_suggestions.similar_to_recently_followed_longer": "דומה למשתמשות.ים שעקבת אחריהן.ם לאחרונה",
|
||||||
"follow_suggestions.view_all": "צפיה בכל",
|
"follow_suggestions.view_all": "צפיה בכל",
|
||||||
"follow_suggestions.who_to_follow": "אחרי מי לעקוב",
|
"follow_suggestions.who_to_follow": "אחרי מי לעקוב",
|
||||||
"followed_tags": "התגיות שהחשבון שלך עוקב אחריהן",
|
"followed_tags": "התגיות שהחשבון שלך עוקב אחריהן",
|
||||||
|
@ -469,6 +473,15 @@
|
||||||
"notification.follow": "{name} במעקב אחרייך",
|
"notification.follow": "{name} במעקב אחרייך",
|
||||||
"notification.follow_request": "{name} ביקשו לעקוב אחריך",
|
"notification.follow_request": "{name} ביקשו לעקוב אחריך",
|
||||||
"notification.mention": "אוזכרת על ידי {name}",
|
"notification.mention": "אוזכרת על ידי {name}",
|
||||||
|
"notification.moderation-warning.learn_more": "למידע נוסף",
|
||||||
|
"notification.moderation_warning": "קיבלת אזהרה מצוות ניהול התוכן",
|
||||||
|
"notification.moderation_warning.action_delete_statuses": "חלק מהודעותיך הוסרו.",
|
||||||
|
"notification.moderation_warning.action_disable": "חשבונך הושבת.",
|
||||||
|
"notification.moderation_warning.action_mark_statuses_as_sensitive": "חלק מהודעותיך סומנו כרגישות.",
|
||||||
|
"notification.moderation_warning.action_none": "חשבונך קיבל אזהרה מצוות ניהול התוכן.",
|
||||||
|
"notification.moderation_warning.action_sensitive": "הודעותיך יסומנו כרגישות מעתה ואילך.",
|
||||||
|
"notification.moderation_warning.action_silence": "חשבונך הוגבל.",
|
||||||
|
"notification.moderation_warning.action_suspend": "חשבונך הושעה.",
|
||||||
"notification.own_poll": "הסקר שלך הסתיים",
|
"notification.own_poll": "הסקר שלך הסתיים",
|
||||||
"notification.poll": "סקר שהצבעת בו הסתיים",
|
"notification.poll": "סקר שהצבעת בו הסתיים",
|
||||||
"notification.reblog": "הודעתך הודהדה על ידי {name}",
|
"notification.reblog": "הודעתך הודהדה על ידי {name}",
|
||||||
|
|
|
@ -308,6 +308,8 @@
|
||||||
"follow_requests.unlocked_explanation": "Bár a fiókod nincs zárolva, a(z) {domain} csapata úgy gondolta, hogy talán kézzel szeretnéd ellenőrizni ezen fiókok követési kéréseit.",
|
"follow_requests.unlocked_explanation": "Bár a fiókod nincs zárolva, a(z) {domain} csapata úgy gondolta, hogy talán kézzel szeretnéd ellenőrizni ezen fiókok követési kéréseit.",
|
||||||
"follow_suggestions.curated_suggestion": "A stáb választása",
|
"follow_suggestions.curated_suggestion": "A stáb választása",
|
||||||
"follow_suggestions.dismiss": "Ne jelenjen meg újra",
|
"follow_suggestions.dismiss": "Ne jelenjen meg újra",
|
||||||
|
"follow_suggestions.featured_longer": "A {domain} csapata által kézzel kiválasztott",
|
||||||
|
"follow_suggestions.friends_of_friends_longer": "Népszerű az általad követett emberek körében",
|
||||||
"follow_suggestions.hints.featured": "Ezt a profilt a(z) {domain} csapata választotta ki.",
|
"follow_suggestions.hints.featured": "Ezt a profilt a(z) {domain} csapata választotta ki.",
|
||||||
"follow_suggestions.hints.friends_of_friends": "Ez a profil népszerű az általad követett emberek körében.",
|
"follow_suggestions.hints.friends_of_friends": "Ez a profil népszerű az általad követett emberek körében.",
|
||||||
"follow_suggestions.hints.most_followed": "Ez a profil a leginkább követett a(z) {domain} oldalon.",
|
"follow_suggestions.hints.most_followed": "Ez a profil a leginkább követett a(z) {domain} oldalon.",
|
||||||
|
@ -315,6 +317,8 @@
|
||||||
"follow_suggestions.hints.similar_to_recently_followed": "Ez a profil hasonló azokhoz a profilokhoz, melyeket nemrég kezdtél el követni.",
|
"follow_suggestions.hints.similar_to_recently_followed": "Ez a profil hasonló azokhoz a profilokhoz, melyeket nemrég kezdtél el követni.",
|
||||||
"follow_suggestions.personalized_suggestion": "Személyre szabott javaslat",
|
"follow_suggestions.personalized_suggestion": "Személyre szabott javaslat",
|
||||||
"follow_suggestions.popular_suggestion": "Népszerű javaslat",
|
"follow_suggestions.popular_suggestion": "Népszerű javaslat",
|
||||||
|
"follow_suggestions.popular_suggestion_longer": "Népszerű itt: {domain}",
|
||||||
|
"follow_suggestions.similar_to_recently_followed_longer": "Hasonló azokhoz a profilokhoz, melyeket nemrég követtél be",
|
||||||
"follow_suggestions.view_all": "Összes megtekintése",
|
"follow_suggestions.view_all": "Összes megtekintése",
|
||||||
"follow_suggestions.who_to_follow": "Kit érdemes követni",
|
"follow_suggestions.who_to_follow": "Kit érdemes követni",
|
||||||
"followed_tags": "Követett hashtagek",
|
"followed_tags": "Követett hashtagek",
|
||||||
|
@ -469,6 +473,15 @@
|
||||||
"notification.follow": "{name} követ téged",
|
"notification.follow": "{name} követ téged",
|
||||||
"notification.follow_request": "{name} követni szeretne téged",
|
"notification.follow_request": "{name} követni szeretne téged",
|
||||||
"notification.mention": "{name} megemlített",
|
"notification.mention": "{name} megemlített",
|
||||||
|
"notification.moderation-warning.learn_more": "További információ",
|
||||||
|
"notification.moderation_warning": "Moderációs figyelmeztetést kaptál",
|
||||||
|
"notification.moderation_warning.action_delete_statuses": "Néhány bejegyzésedet eltávolították.",
|
||||||
|
"notification.moderation_warning.action_disable": "A fiókod le van tiltva.",
|
||||||
|
"notification.moderation_warning.action_mark_statuses_as_sensitive": "Néhány bejegyzésedet kényesnek jelölték.",
|
||||||
|
"notification.moderation_warning.action_none": "A fiókod moderációs figyelmeztetést kapott.",
|
||||||
|
"notification.moderation_warning.action_sensitive": "A bejegyzéseid mostantól érzékenynek lesznek jelölve.",
|
||||||
|
"notification.moderation_warning.action_silence": "A fiókod korlátozásra került.",
|
||||||
|
"notification.moderation_warning.action_suspend": "A fiókod felfüggesztésre került.",
|
||||||
"notification.own_poll": "A szavazásod véget ért",
|
"notification.own_poll": "A szavazásod véget ért",
|
||||||
"notification.poll": "Egy szavazás, melyben részt vettél, véget ért",
|
"notification.poll": "Egy szavazás, melyben részt vettél, véget ért",
|
||||||
"notification.reblog": "{name} megtolta a bejegyzésedet",
|
"notification.reblog": "{name} megtolta a bejegyzésedet",
|
||||||
|
|
|
@ -308,6 +308,8 @@
|
||||||
"follow_requests.unlocked_explanation": "Benque tu conto non es serrate, le personal de {domain} pensa que es un bon idea que tu revide manualmente le sequente requestas de iste contos.",
|
"follow_requests.unlocked_explanation": "Benque tu conto non es serrate, le personal de {domain} pensa que es un bon idea que tu revide manualmente le sequente requestas de iste contos.",
|
||||||
"follow_suggestions.curated_suggestion": "Selection del equipa",
|
"follow_suggestions.curated_suggestion": "Selection del equipa",
|
||||||
"follow_suggestions.dismiss": "Non monstrar novemente",
|
"follow_suggestions.dismiss": "Non monstrar novemente",
|
||||||
|
"follow_suggestions.featured_longer": "Seligite con cura per le equipa de {domain}",
|
||||||
|
"follow_suggestions.friends_of_friends_longer": "Popular inter le gente que tu seque",
|
||||||
"follow_suggestions.hints.featured": "Iste profilo ha essite seligite manualmente per le equipa de {domain}.",
|
"follow_suggestions.hints.featured": "Iste profilo ha essite seligite manualmente per le equipa de {domain}.",
|
||||||
"follow_suggestions.hints.friends_of_friends": "Iste profilo es popular inter le gente que tu seque.",
|
"follow_suggestions.hints.friends_of_friends": "Iste profilo es popular inter le gente que tu seque.",
|
||||||
"follow_suggestions.hints.most_followed": "Iste profilo es un del plus sequites sur {domain}.",
|
"follow_suggestions.hints.most_followed": "Iste profilo es un del plus sequites sur {domain}.",
|
||||||
|
@ -315,6 +317,8 @@
|
||||||
"follow_suggestions.hints.similar_to_recently_followed": "Iste profilo es similar al profilos que tu ha recentemente sequite.",
|
"follow_suggestions.hints.similar_to_recently_followed": "Iste profilo es similar al profilos que tu ha recentemente sequite.",
|
||||||
"follow_suggestions.personalized_suggestion": "Suggestion personalisate",
|
"follow_suggestions.personalized_suggestion": "Suggestion personalisate",
|
||||||
"follow_suggestions.popular_suggestion": "Suggestion personalisate",
|
"follow_suggestions.popular_suggestion": "Suggestion personalisate",
|
||||||
|
"follow_suggestions.popular_suggestion_longer": "Popular sur {domain}",
|
||||||
|
"follow_suggestions.similar_to_recently_followed_longer": "Similar al profilos que tu ha sequite recentemente",
|
||||||
"follow_suggestions.view_all": "Vider toto",
|
"follow_suggestions.view_all": "Vider toto",
|
||||||
"follow_suggestions.who_to_follow": "Qui sequer",
|
"follow_suggestions.who_to_follow": "Qui sequer",
|
||||||
"followed_tags": "Hashtags sequite",
|
"followed_tags": "Hashtags sequite",
|
||||||
|
@ -469,6 +473,15 @@
|
||||||
"notification.follow": "{name} te ha sequite",
|
"notification.follow": "{name} te ha sequite",
|
||||||
"notification.follow_request": "{name} ha requestate de sequer te",
|
"notification.follow_request": "{name} ha requestate de sequer te",
|
||||||
"notification.mention": "{name} te ha mentionate",
|
"notification.mention": "{name} te ha mentionate",
|
||||||
|
"notification.moderation-warning.learn_more": "Apprender plus",
|
||||||
|
"notification.moderation_warning": "Tu ha recipite un advertimento de moderation",
|
||||||
|
"notification.moderation_warning.action_delete_statuses": "Alcunes de tu messages ha essite removite.",
|
||||||
|
"notification.moderation_warning.action_disable": "Tu conto ha essite disactivate.",
|
||||||
|
"notification.moderation_warning.action_mark_statuses_as_sensitive": "Alcunes de tu messages ha essite marcate como sensibile.",
|
||||||
|
"notification.moderation_warning.action_none": "Tu conto ha recipite un advertimento de moderation.",
|
||||||
|
"notification.moderation_warning.action_sensitive": "Tu messages essera marcate como sensibile a partir de ora.",
|
||||||
|
"notification.moderation_warning.action_silence": "Tu conto ha essite limitate.",
|
||||||
|
"notification.moderation_warning.action_suspend": "Tu conto ha essite suspendite.",
|
||||||
"notification.own_poll": "Tu sondage ha finite",
|
"notification.own_poll": "Tu sondage ha finite",
|
||||||
"notification.poll": "Un sondage in le qual tu ha votate ha finite",
|
"notification.poll": "Un sondage in le qual tu ha votate ha finite",
|
||||||
"notification.reblog": "{name} ha impulsate tu message",
|
"notification.reblog": "{name} ha impulsate tu message",
|
||||||
|
|
|
@ -123,6 +123,7 @@
|
||||||
"column.directory": "Jelajahi profil",
|
"column.directory": "Jelajahi profil",
|
||||||
"column.domain_blocks": "Domain tersembunyi",
|
"column.domain_blocks": "Domain tersembunyi",
|
||||||
"column.favourites": "Favorit",
|
"column.favourites": "Favorit",
|
||||||
|
"column.firehose": "Feed yang sedang berlangsung",
|
||||||
"column.follow_requests": "Permintaan mengikuti",
|
"column.follow_requests": "Permintaan mengikuti",
|
||||||
"column.home": "Beranda",
|
"column.home": "Beranda",
|
||||||
"column.lists": "List",
|
"column.lists": "List",
|
||||||
|
@ -143,7 +144,9 @@
|
||||||
"community.column_settings.remote_only": "Hanya jarak jauh",
|
"community.column_settings.remote_only": "Hanya jarak jauh",
|
||||||
"compose.language.change": "Ganti bahasa",
|
"compose.language.change": "Ganti bahasa",
|
||||||
"compose.language.search": "Telusuri bahasa...",
|
"compose.language.search": "Telusuri bahasa...",
|
||||||
|
"compose.published.body": "Postingan diterbitkan.",
|
||||||
"compose.published.open": "Buka",
|
"compose.published.open": "Buka",
|
||||||
|
"compose.saved.body": "Postingan tersimpan.",
|
||||||
"compose_form.direct_message_warning_learn_more": "Pelajari lebih lanjut",
|
"compose_form.direct_message_warning_learn_more": "Pelajari lebih lanjut",
|
||||||
"compose_form.encryption_warning": "Kiriman di Mastodon tidak dienkripsi secara end-to-end. Jangan bagikan informasi sensitif melalui Mastodon.",
|
"compose_form.encryption_warning": "Kiriman di Mastodon tidak dienkripsi secara end-to-end. Jangan bagikan informasi sensitif melalui Mastodon.",
|
||||||
"compose_form.hashtag_warning": "Kiriman ini tidak akan didaftarkan di bawah tagar apapun selama tidak diatur ke publik. Hanya kiriman publik yang dapat dicari dengan tagar.",
|
"compose_form.hashtag_warning": "Kiriman ini tidak akan didaftarkan di bawah tagar apapun selama tidak diatur ke publik. Hanya kiriman publik yang dapat dicari dengan tagar.",
|
||||||
|
@ -151,11 +154,19 @@
|
||||||
"compose_form.lock_disclaimer.lock": "terkunci",
|
"compose_form.lock_disclaimer.lock": "terkunci",
|
||||||
"compose_form.placeholder": "Apa yang ada di pikiran Anda?",
|
"compose_form.placeholder": "Apa yang ada di pikiran Anda?",
|
||||||
"compose_form.poll.duration": "Durasi japat",
|
"compose_form.poll.duration": "Durasi japat",
|
||||||
|
"compose_form.poll.multiple": "Pilihan ganda",
|
||||||
|
"compose_form.poll.option_placeholder": "Opsi {number}",
|
||||||
|
"compose_form.poll.single": "Pilih Satu",
|
||||||
"compose_form.poll.switch_to_multiple": "Ubah japat menjadi pilihan ganda",
|
"compose_form.poll.switch_to_multiple": "Ubah japat menjadi pilihan ganda",
|
||||||
"compose_form.poll.switch_to_single": "Ubah japat menjadi pilihan tunggal",
|
"compose_form.poll.switch_to_single": "Ubah japat menjadi pilihan tunggal",
|
||||||
|
"compose_form.poll.type": "Gaya",
|
||||||
|
"compose_form.publish": "Postingan",
|
||||||
"compose_form.publish_form": "Terbitkan",
|
"compose_form.publish_form": "Terbitkan",
|
||||||
|
"compose_form.reply": "Balas",
|
||||||
|
"compose_form.save_changes": "Perbarui",
|
||||||
"compose_form.spoiler.marked": "Hapus peringatan tentang isi konten",
|
"compose_form.spoiler.marked": "Hapus peringatan tentang isi konten",
|
||||||
"compose_form.spoiler.unmarked": "Tambahkan peringatan tentang isi konten",
|
"compose_form.spoiler.unmarked": "Tambahkan peringatan tentang isi konten",
|
||||||
|
"compose_form.spoiler_placeholder": "Peringatan konten (opsional)",
|
||||||
"confirmation_modal.cancel": "Batal",
|
"confirmation_modal.cancel": "Batal",
|
||||||
"confirmations.block.confirm": "Blokir",
|
"confirmations.block.confirm": "Blokir",
|
||||||
"confirmations.cancel_follow_request.confirm": "Batalkan permintaan",
|
"confirmations.cancel_follow_request.confirm": "Batalkan permintaan",
|
||||||
|
@ -166,12 +177,15 @@
|
||||||
"confirmations.delete_list.message": "Apakah Anda yakin untuk menghapus daftar ini secara permanen?",
|
"confirmations.delete_list.message": "Apakah Anda yakin untuk menghapus daftar ini secara permanen?",
|
||||||
"confirmations.discard_edit_media.confirm": "Buang",
|
"confirmations.discard_edit_media.confirm": "Buang",
|
||||||
"confirmations.discard_edit_media.message": "Anda belum menyimpan perubahan deskripsi atau pratinjau media, buang saja?",
|
"confirmations.discard_edit_media.message": "Anda belum menyimpan perubahan deskripsi atau pratinjau media, buang saja?",
|
||||||
|
"confirmations.domain_block.confirm": "Blokir server",
|
||||||
"confirmations.domain_block.message": "Apakah Anda benar-benar yakin untuk memblokir keseluruhan {domain}? Dalam kasus tertentu beberapa pemblokiran atau penyembunyian lebih baik.",
|
"confirmations.domain_block.message": "Apakah Anda benar-benar yakin untuk memblokir keseluruhan {domain}? Dalam kasus tertentu beberapa pemblokiran atau penyembunyian lebih baik.",
|
||||||
"confirmations.edit.confirm": "Ubah",
|
"confirmations.edit.confirm": "Ubah",
|
||||||
|
"confirmations.edit.message": "Mengubah akan menimpa pesan yang sedang anda tulis. Apakah anda yakin ingin melanjutkan?",
|
||||||
"confirmations.logout.confirm": "Keluar",
|
"confirmations.logout.confirm": "Keluar",
|
||||||
"confirmations.logout.message": "Apakah Anda yakin ingin keluar?",
|
"confirmations.logout.message": "Apakah Anda yakin ingin keluar?",
|
||||||
"confirmations.mute.confirm": "Bisukan",
|
"confirmations.mute.confirm": "Bisukan",
|
||||||
"confirmations.redraft.confirm": "Hapus dan susun ulang",
|
"confirmations.redraft.confirm": "Hapus dan susun ulang",
|
||||||
|
"confirmations.redraft.message": "Apakah anda yakin ingin menghapus postingan ini dan menyusun ulang postingan ini? Favorit dan peningkatan akan hilang, dan balasan ke postingan asli tidak akan terhubung ke postingan manapun.",
|
||||||
"confirmations.reply.confirm": "Balas",
|
"confirmations.reply.confirm": "Balas",
|
||||||
"confirmations.reply.message": "Membalas sekarang akan menimpa pesan yang sedang Anda buat. Anda yakin ingin melanjutkan?",
|
"confirmations.reply.message": "Membalas sekarang akan menimpa pesan yang sedang Anda buat. Anda yakin ingin melanjutkan?",
|
||||||
"confirmations.unfollow.confirm": "Berhenti mengikuti",
|
"confirmations.unfollow.confirm": "Berhenti mengikuti",
|
||||||
|
@ -180,6 +194,7 @@
|
||||||
"conversation.mark_as_read": "Tandai sudah dibaca",
|
"conversation.mark_as_read": "Tandai sudah dibaca",
|
||||||
"conversation.open": "Lihat percakapan",
|
"conversation.open": "Lihat percakapan",
|
||||||
"conversation.with": "Dengan {names}",
|
"conversation.with": "Dengan {names}",
|
||||||
|
"copy_icon_button.copied": "Disalin ke clipboard",
|
||||||
"copypaste.copied": "Disalin",
|
"copypaste.copied": "Disalin",
|
||||||
"copypaste.copy_to_clipboard": "Salin ke clipboard",
|
"copypaste.copy_to_clipboard": "Salin ke clipboard",
|
||||||
"directory.federated": "Dari fediverse yang dikenal",
|
"directory.federated": "Dari fediverse yang dikenal",
|
||||||
|
@ -191,7 +206,27 @@
|
||||||
"dismissable_banner.community_timeline": "Ini adalah kiriman publik terkini dari orang yang akunnya berada di {domain}.",
|
"dismissable_banner.community_timeline": "Ini adalah kiriman publik terkini dari orang yang akunnya berada di {domain}.",
|
||||||
"dismissable_banner.dismiss": "Abaikan",
|
"dismissable_banner.dismiss": "Abaikan",
|
||||||
"dismissable_banner.explore_links": "Cerita berita ini sekarang sedang dibicarakan oleh orang di server ini dan lainnya dalam jaringan terdesentralisasi.",
|
"dismissable_banner.explore_links": "Cerita berita ini sekarang sedang dibicarakan oleh orang di server ini dan lainnya dalam jaringan terdesentralisasi.",
|
||||||
|
"dismissable_banner.explore_statuses": "Ini adalah postingan dari seluruh web sosial yang mendapatkan daya tarik saat ini. Postingan baru dengan lebih banyak peningkatan dan favorit memiliki peringkat lebih tinggi.",
|
||||||
"dismissable_banner.explore_tags": "Tagar ini sekarang sedang tren di antara orang di server ini dan lainnya dalam jaringan terdesentralisasi.",
|
"dismissable_banner.explore_tags": "Tagar ini sekarang sedang tren di antara orang di server ini dan lainnya dalam jaringan terdesentralisasi.",
|
||||||
|
"dismissable_banner.public_timeline": "Ini adalah postingan publik dari orang-orang di web sosial yang diikuti oleh {domain}.",
|
||||||
|
"domain_block_modal.block": "Blokir server",
|
||||||
|
"domain_block_modal.block_account_instead": "Blokir @{name} saja",
|
||||||
|
"domain_block_modal.they_can_interact_with_old_posts": "Orang-orang dari server ini dapat berinteraksi dengan kiriman lama anda.",
|
||||||
|
"domain_block_modal.they_cant_follow": "Tidak ada seorangpun dari server ini yang dapat mengikuti anda.",
|
||||||
|
"domain_block_modal.they_wont_know": "Mereka tidak akan tahu bahwa mereka diblokir.",
|
||||||
|
"domain_block_modal.title": "Blokir domain?",
|
||||||
|
"domain_block_modal.you_will_lose_followers": "Semua pengikut anda dari server ini akan dihapus.",
|
||||||
|
"domain_block_modal.you_wont_see_posts": "Anda tidak akan melihat postingan atau notifikasi dari pengguna di server ini.",
|
||||||
|
"domain_pill.activitypub_lets_connect": "Ini memungkinkan anda terhubung dan berinteraksi dengan orang-orang tidak hanya di Mastodon, tetapi juga di berbagai aplikasi sosial.",
|
||||||
|
"domain_pill.activitypub_like_language": "ActivityPub seperti bahasa yang digunakan Mastodon dengan jejaring sosial lainnya.",
|
||||||
|
"domain_pill.server": "Server",
|
||||||
|
"domain_pill.their_handle": "Nama penggunanya:",
|
||||||
|
"domain_pill.their_server": "Rumah digital mereka, di mana semua postingan mereka tersedia.",
|
||||||
|
"domain_pill.their_username": "Pengenal unik mereka di server tersebut. Itu memungkinkan dapat mencari pengguna dengan nama yang sama di server lain.",
|
||||||
|
"domain_pill.username": "Nama pengguna",
|
||||||
|
"domain_pill.whats_in_a_handle": "Apa itu nama pengguna?",
|
||||||
|
"domain_pill.who_they_are": "Karena nama pengguna menunjukkan siapa seseorang dan di mana server mereka berada, anda dapat berinteraksi dengan orang-orang di seluruh web sosial <button>ActivityPub-powered platforms</button>.",
|
||||||
|
"domain_pill.your_handle": "Nama pengguna anda:",
|
||||||
"embed.instructions": "Sematkan kiriman ini di situs web Anda dengan menyalin kode di bawah ini.",
|
"embed.instructions": "Sematkan kiriman ini di situs web Anda dengan menyalin kode di bawah ini.",
|
||||||
"embed.preview": "Tampilan akan seperti ini nantinya:",
|
"embed.preview": "Tampilan akan seperti ini nantinya:",
|
||||||
"emoji_button.activity": "Aktivitas",
|
"emoji_button.activity": "Aktivitas",
|
||||||
|
@ -260,6 +295,10 @@
|
||||||
"follow_request.authorize": "Izinkan",
|
"follow_request.authorize": "Izinkan",
|
||||||
"follow_request.reject": "Tolak",
|
"follow_request.reject": "Tolak",
|
||||||
"follow_requests.unlocked_explanation": "Meskipun akun Anda tidak dikunci, staf {domain} menyarankan Anda untuk meninjau permintaan mengikuti dari akun-akun ini secara manual.",
|
"follow_requests.unlocked_explanation": "Meskipun akun Anda tidak dikunci, staf {domain} menyarankan Anda untuk meninjau permintaan mengikuti dari akun-akun ini secara manual.",
|
||||||
|
"follow_suggestions.curated_suggestion": "Pilihan staf",
|
||||||
|
"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.",
|
||||||
"followed_tags": "Tagar yang diikuti",
|
"followed_tags": "Tagar yang diikuti",
|
||||||
"footer.about": "Tentang",
|
"footer.about": "Tentang",
|
||||||
"footer.directory": "Direktori profil",
|
"footer.directory": "Direktori profil",
|
||||||
|
|
|
@ -20,6 +20,7 @@
|
||||||
"column.bookmarks": "Ebenrụtụakā",
|
"column.bookmarks": "Ebenrụtụakā",
|
||||||
"column.home": "Be",
|
"column.home": "Be",
|
||||||
"column.lists": "Ndepụta",
|
"column.lists": "Ndepụta",
|
||||||
|
"column.notifications": "Nziọkwà",
|
||||||
"column.pins": "Pinned post",
|
"column.pins": "Pinned post",
|
||||||
"column_header.pin": "Gbado na profaịlụ gị",
|
"column_header.pin": "Gbado na profaịlụ gị",
|
||||||
"column_subheading.settings": "Mwube",
|
"column_subheading.settings": "Mwube",
|
||||||
|
@ -42,17 +43,28 @@
|
||||||
"confirmations.reply.confirm": "Zaa",
|
"confirmations.reply.confirm": "Zaa",
|
||||||
"confirmations.unfollow.confirm": "Kwụsị iso",
|
"confirmations.unfollow.confirm": "Kwụsị iso",
|
||||||
"conversation.delete": "Hichapụ nkata",
|
"conversation.delete": "Hichapụ nkata",
|
||||||
|
"disabled_account_banner.account_settings": "Mwube akaụntụ",
|
||||||
"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_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.",
|
"dismissable_banner.explore_tags": "These hashtags are gaining traction among people on this and other servers of the decentralized network right now.",
|
||||||
|
"domain_pill.username": "Ahaojiaru",
|
||||||
"embed.instructions": "Embed this status on your website by copying the code below.",
|
"embed.instructions": "Embed this status on your website by copying the code below.",
|
||||||
|
"emoji_button.activity": "Mmemme",
|
||||||
|
"emoji_button.label": "Tibanye emoji",
|
||||||
"emoji_button.search": "Chọọ...",
|
"emoji_button.search": "Chọọ...",
|
||||||
|
"emoji_button.symbols": "Ọdịmara",
|
||||||
"empty_column.account_timeline": "No posts found",
|
"empty_column.account_timeline": "No posts found",
|
||||||
"empty_column.home": "Your home timeline is empty! Follow more people to fill it up. {suggestions}",
|
"empty_column.home": "Your home timeline is empty! Follow more people to fill it up. {suggestions}",
|
||||||
"empty_column.list": "There is nothing in this list yet. When members of this list post new statuses, they will appear here.",
|
"empty_column.list": "There is nothing in this list yet. When members of this list post new statuses, they will appear here.",
|
||||||
"errors.unexpected_crash.report_issue": "Kpesa nsogbu",
|
"errors.unexpected_crash.report_issue": "Kpesa nsogbu",
|
||||||
|
"explore.trending_links": "Akụkọ",
|
||||||
|
"firehose.all": "Ha niine",
|
||||||
|
"follow_request.authorize": "Nye ikike",
|
||||||
"footer.privacy_policy": "Iwu nzuzu",
|
"footer.privacy_policy": "Iwu nzuzu",
|
||||||
"getting_started.heading": "Mbido",
|
"getting_started.heading": "Mbido",
|
||||||
"hashtag.column_settings.tag_toggle": "Include additional tags in this column",
|
"hashtag.column_settings.tag_toggle": "Include additional tags in this column",
|
||||||
|
"home.column_settings.show_replies": "Gosi nzaghachị",
|
||||||
|
"home.hide_announcements": "Zoo ọkwa",
|
||||||
|
"home.show_announcements": "Gosi ọkwa",
|
||||||
"keyboard_shortcuts.back": "to navigate back",
|
"keyboard_shortcuts.back": "to navigate back",
|
||||||
"keyboard_shortcuts.blocked": "to open blocked users list",
|
"keyboard_shortcuts.blocked": "to open blocked users list",
|
||||||
"keyboard_shortcuts.boost": "to boost",
|
"keyboard_shortcuts.boost": "to boost",
|
||||||
|
|
|
@ -308,6 +308,8 @@
|
||||||
"follow_requests.unlocked_explanation": "Jafnvel þótt aðgangurinn þinn sé ekki læstur, hafa umsjónarmenn {domain} ímyndað sér að þú gætir viljað yfirfara handvirkt fylgjendabeiðnir frá þessum notendum.",
|
"follow_requests.unlocked_explanation": "Jafnvel þótt aðgangurinn þinn sé ekki læstur, hafa umsjónarmenn {domain} ímyndað sér að þú gætir viljað yfirfara handvirkt fylgjendabeiðnir frá þessum notendum.",
|
||||||
"follow_suggestions.curated_suggestion": "Úrval starfsfólks",
|
"follow_suggestions.curated_suggestion": "Úrval starfsfólks",
|
||||||
"follow_suggestions.dismiss": "Ekki birta þetta aftur",
|
"follow_suggestions.dismiss": "Ekki birta þetta aftur",
|
||||||
|
"follow_suggestions.featured_longer": "Handvalið af {domain}-teyminu",
|
||||||
|
"follow_suggestions.friends_of_friends_longer": "Vinsælt hjá fólki sem þú fylgist með",
|
||||||
"follow_suggestions.hints.featured": "Þetta notandasnið hefur verið handvalið af {domain}-teyminu.",
|
"follow_suggestions.hints.featured": "Þetta notandasnið hefur verið handvalið af {domain}-teyminu.",
|
||||||
"follow_suggestions.hints.friends_of_friends": "Þetta notandasnið er vinsælt hjá fólki sem þú fylgist með.",
|
"follow_suggestions.hints.friends_of_friends": "Þetta notandasnið er vinsælt hjá fólki sem þú fylgist með.",
|
||||||
"follow_suggestions.hints.most_followed": "Þetta notandasnið er eitt af þeim sem mest er fylgst með á {domain}.",
|
"follow_suggestions.hints.most_followed": "Þetta notandasnið er eitt af þeim sem mest er fylgst með á {domain}.",
|
||||||
|
@ -315,6 +317,8 @@
|
||||||
"follow_suggestions.hints.similar_to_recently_followed": "Þetta notandasnið er líkt þeim sniðum sem þú hefur valið að fylgjast með að undanförnu.",
|
"follow_suggestions.hints.similar_to_recently_followed": "Þetta notandasnið er líkt þeim sniðum sem þú hefur valið að fylgjast með að undanförnu.",
|
||||||
"follow_suggestions.personalized_suggestion": "Persónuaðlöguð tillaga",
|
"follow_suggestions.personalized_suggestion": "Persónuaðlöguð tillaga",
|
||||||
"follow_suggestions.popular_suggestion": "Vinsæl tillaga",
|
"follow_suggestions.popular_suggestion": "Vinsæl tillaga",
|
||||||
|
"follow_suggestions.popular_suggestion_longer": "Vinsælt á {domain}",
|
||||||
|
"follow_suggestions.similar_to_recently_followed_longer": "Svipar til notenda sem þú hefur nýlega farið að fylgjast með",
|
||||||
"follow_suggestions.view_all": "Skoða allt",
|
"follow_suggestions.view_all": "Skoða allt",
|
||||||
"follow_suggestions.who_to_follow": "Hverjum á að fylgjast með",
|
"follow_suggestions.who_to_follow": "Hverjum á að fylgjast með",
|
||||||
"followed_tags": "Myllumerki sem fylgst er með",
|
"followed_tags": "Myllumerki sem fylgst er með",
|
||||||
|
@ -469,6 +473,15 @@
|
||||||
"notification.follow": "{name} fylgist með þér",
|
"notification.follow": "{name} fylgist með þér",
|
||||||
"notification.follow_request": "{name} hefur beðið um að fylgjast með þér",
|
"notification.follow_request": "{name} hefur beðið um að fylgjast með þér",
|
||||||
"notification.mention": "{name} minntist á þig",
|
"notification.mention": "{name} minntist á þig",
|
||||||
|
"notification.moderation-warning.learn_more": "Kanna nánar",
|
||||||
|
"notification.moderation_warning": "Þú hefur fengið aðvörun frá umsjónarmanni",
|
||||||
|
"notification.moderation_warning.action_delete_statuses": "Sumar færslurnar þínar hafa verið fjarlægðar.",
|
||||||
|
"notification.moderation_warning.action_disable": "Aðgangurinn þinn hefur verið gerður óvirkur.",
|
||||||
|
"notification.moderation_warning.action_mark_statuses_as_sensitive": "Sumar færslurnar þínar hafa verið merktar sem viðkvæmt efni.",
|
||||||
|
"notification.moderation_warning.action_none": "Aðgangurinn þinn hefur fengið aðvörun frá umsjónarmanni.",
|
||||||
|
"notification.moderation_warning.action_sensitive": "Færslur þínar á verða héðan í frá merktar sem viðkvæmar.",
|
||||||
|
"notification.moderation_warning.action_silence": "Notandaaðgangurinn þinn hefur verið takmarkaður.",
|
||||||
|
"notification.moderation_warning.action_suspend": "Notandaaðgangurinn þinn hefur verið settur í frysti.",
|
||||||
"notification.own_poll": "Könnuninni þinni er lokið",
|
"notification.own_poll": "Könnuninni þinni er lokið",
|
||||||
"notification.poll": "Könnun sem þú tókst þátt í er lokið",
|
"notification.poll": "Könnun sem þú tókst þátt í er lokið",
|
||||||
"notification.reblog": "{name} endurbirti færsluna þína",
|
"notification.reblog": "{name} endurbirti færsluna þína",
|
||||||
|
|
|
@ -308,6 +308,8 @@
|
||||||
"follow_requests.unlocked_explanation": "Anche se il tuo profilo non è privato, lo staff di {domain} ha pensato che potresti voler revisionare manualmente le richieste di seguirti da questi profili.",
|
"follow_requests.unlocked_explanation": "Anche se il tuo profilo non è privato, lo staff di {domain} ha pensato che potresti voler revisionare manualmente le richieste di seguirti da questi profili.",
|
||||||
"follow_suggestions.curated_suggestion": "Scelta personale",
|
"follow_suggestions.curated_suggestion": "Scelta personale",
|
||||||
"follow_suggestions.dismiss": "Non visualizzare più",
|
"follow_suggestions.dismiss": "Non visualizzare più",
|
||||||
|
"follow_suggestions.featured_longer": "Selezionato personalmente dal team di {domain}",
|
||||||
|
"follow_suggestions.friends_of_friends_longer": "Popolare tra le persone che segui",
|
||||||
"follow_suggestions.hints.featured": "Questo profilo è stato selezionato personalmente dal team di {domain}.",
|
"follow_suggestions.hints.featured": "Questo profilo è stato selezionato personalmente dal team di {domain}.",
|
||||||
"follow_suggestions.hints.friends_of_friends": "Questo profilo è popolare tra le persone che segui.",
|
"follow_suggestions.hints.friends_of_friends": "Questo profilo è popolare tra le persone che segui.",
|
||||||
"follow_suggestions.hints.most_followed": "Questo profilo è uno dei più seguiti su {domain}.",
|
"follow_suggestions.hints.most_followed": "Questo profilo è uno dei più seguiti su {domain}.",
|
||||||
|
@ -315,6 +317,8 @@
|
||||||
"follow_suggestions.hints.similar_to_recently_followed": "Questo profilo è simile ai profili che hai seguito più recentemente.",
|
"follow_suggestions.hints.similar_to_recently_followed": "Questo profilo è simile ai profili che hai seguito più recentemente.",
|
||||||
"follow_suggestions.personalized_suggestion": "Suggerimenti personalizzati",
|
"follow_suggestions.personalized_suggestion": "Suggerimenti personalizzati",
|
||||||
"follow_suggestions.popular_suggestion": "Suggerimento frequente",
|
"follow_suggestions.popular_suggestion": "Suggerimento frequente",
|
||||||
|
"follow_suggestions.popular_suggestion_longer": "Popolare su {domain}",
|
||||||
|
"follow_suggestions.similar_to_recently_followed_longer": "Simile ai profili che hai seguito di recente",
|
||||||
"follow_suggestions.view_all": "Vedi tutto",
|
"follow_suggestions.view_all": "Vedi tutto",
|
||||||
"follow_suggestions.who_to_follow": "Chi seguire",
|
"follow_suggestions.who_to_follow": "Chi seguire",
|
||||||
"followed_tags": "Hashtag seguiti",
|
"followed_tags": "Hashtag seguiti",
|
||||||
|
@ -469,6 +473,15 @@
|
||||||
"notification.follow": "{name} ha iniziato a seguirti",
|
"notification.follow": "{name} ha iniziato a seguirti",
|
||||||
"notification.follow_request": "{name} ha richiesto di seguirti",
|
"notification.follow_request": "{name} ha richiesto di seguirti",
|
||||||
"notification.mention": "{name} ti ha menzionato",
|
"notification.mention": "{name} ti ha menzionato",
|
||||||
|
"notification.moderation-warning.learn_more": "Scopri di più",
|
||||||
|
"notification.moderation_warning": "Hai ricevuto un avviso di moderazione",
|
||||||
|
"notification.moderation_warning.action_delete_statuses": "Alcuni dei tuoi post sono stati rimossi.",
|
||||||
|
"notification.moderation_warning.action_disable": "Il tuo account è stato disattivato.",
|
||||||
|
"notification.moderation_warning.action_mark_statuses_as_sensitive": "Alcuni dei tuoi post sono stati contrassegnati come sensibili.",
|
||||||
|
"notification.moderation_warning.action_none": "Il tuo account ha ricevuto un avviso di moderazione.",
|
||||||
|
"notification.moderation_warning.action_sensitive": "I tuoi post d'ora in poi saranno contrassegnati come sensibili.",
|
||||||
|
"notification.moderation_warning.action_silence": "Il tuo account è stato limitato.",
|
||||||
|
"notification.moderation_warning.action_suspend": "Il tuo account è stato sospeso.",
|
||||||
"notification.own_poll": "Il tuo sondaggio è terminato",
|
"notification.own_poll": "Il tuo sondaggio è terminato",
|
||||||
"notification.poll": "Un sondaggio in cui hai votato è terminato",
|
"notification.poll": "Un sondaggio in cui hai votato è terminato",
|
||||||
"notification.reblog": "{name} ha rebloggato il tuo post",
|
"notification.reblog": "{name} ha rebloggato il tuo post",
|
||||||
|
|
|
@ -298,8 +298,8 @@
|
||||||
"filter_modal.select_filter.title": "この投稿をフィルターする",
|
"filter_modal.select_filter.title": "この投稿をフィルターする",
|
||||||
"filter_modal.title.status": "投稿をフィルターする",
|
"filter_modal.title.status": "投稿をフィルターする",
|
||||||
"filtered_notifications_banner.mentions": "{count, plural, one {メンション} other {メンション}}",
|
"filtered_notifications_banner.mentions": "{count, plural, one {メンション} other {メンション}}",
|
||||||
"filtered_notifications_banner.pending_requests": "{count, plural, =0 {アカウント} other {#アカウント}}からの通知がブロックされています",
|
"filtered_notifications_banner.pending_requests": "{count, plural, =0 {通知がブロックされているアカウントはありません} other {#アカウントからの通知がブロックされています}}",
|
||||||
"filtered_notifications_banner.title": "ブロック済みの通知",
|
"filtered_notifications_banner.title": "保留中の通知",
|
||||||
"firehose.all": "すべて",
|
"firehose.all": "すべて",
|
||||||
"firehose.local": "このサーバー",
|
"firehose.local": "このサーバー",
|
||||||
"firehose.remote": "ほかのサーバー",
|
"firehose.remote": "ほかのサーバー",
|
||||||
|
@ -308,6 +308,8 @@
|
||||||
"follow_requests.unlocked_explanation": "あなたのアカウントは承認制ではありませんが、{domain}のスタッフはこれらのアカウントからのフォローリクエストの確認が必要であると判断しました。",
|
"follow_requests.unlocked_explanation": "あなたのアカウントは承認制ではありませんが、{domain}のスタッフはこれらのアカウントからのフォローリクエストの確認が必要であると判断しました。",
|
||||||
"follow_suggestions.curated_suggestion": "サーバースタッフ公認",
|
"follow_suggestions.curated_suggestion": "サーバースタッフ公認",
|
||||||
"follow_suggestions.dismiss": "今後表示しない",
|
"follow_suggestions.dismiss": "今後表示しない",
|
||||||
|
"follow_suggestions.featured_longer": "{domain} スタッフ公認",
|
||||||
|
"follow_suggestions.friends_of_friends_longer": "フォロー中のユーザーに人気",
|
||||||
"follow_suggestions.hints.featured": "{domain} の運営スタッフが選んだアカウントです。",
|
"follow_suggestions.hints.featured": "{domain} の運営スタッフが選んだアカウントです。",
|
||||||
"follow_suggestions.hints.friends_of_friends": "フォロー中のユーザーのあいだで人気のアカウントです。",
|
"follow_suggestions.hints.friends_of_friends": "フォロー中のユーザーのあいだで人気のアカウントです。",
|
||||||
"follow_suggestions.hints.most_followed": "{domain} でもっともフォローされているアカウントのひとつです。",
|
"follow_suggestions.hints.most_followed": "{domain} でもっともフォローされているアカウントのひとつです。",
|
||||||
|
@ -315,6 +317,8 @@
|
||||||
"follow_suggestions.hints.similar_to_recently_followed": "最近フォローしたユーザーに似ているアカウントです。",
|
"follow_suggestions.hints.similar_to_recently_followed": "最近フォローしたユーザーに似ているアカウントです。",
|
||||||
"follow_suggestions.personalized_suggestion": "フォローに基づく提案",
|
"follow_suggestions.personalized_suggestion": "フォローに基づく提案",
|
||||||
"follow_suggestions.popular_suggestion": "人気のアカウント",
|
"follow_suggestions.popular_suggestion": "人気のアカウント",
|
||||||
|
"follow_suggestions.popular_suggestion_longer": "{domain} で人気",
|
||||||
|
"follow_suggestions.similar_to_recently_followed_longer": "最近フォローしたユーザーと似ているアカウント",
|
||||||
"follow_suggestions.view_all": "すべて表示",
|
"follow_suggestions.view_all": "すべて表示",
|
||||||
"follow_suggestions.who_to_follow": "フォローを増やしてみませんか?",
|
"follow_suggestions.who_to_follow": "フォローを増やしてみませんか?",
|
||||||
"followed_tags": "フォロー中のハッシュタグ",
|
"followed_tags": "フォロー中のハッシュタグ",
|
||||||
|
@ -482,7 +486,7 @@
|
||||||
"notification_requests.accept": "受け入れる",
|
"notification_requests.accept": "受け入れる",
|
||||||
"notification_requests.dismiss": "無視",
|
"notification_requests.dismiss": "無視",
|
||||||
"notification_requests.notifications_from": "{name}からの通知",
|
"notification_requests.notifications_from": "{name}からの通知",
|
||||||
"notification_requests.title": "ブロック済みの通知",
|
"notification_requests.title": "保留中の通知",
|
||||||
"notifications.clear": "通知を消去",
|
"notifications.clear": "通知を消去",
|
||||||
"notifications.clear_confirmation": "本当に通知を消去しますか?",
|
"notifications.clear_confirmation": "本当に通知を消去しますか?",
|
||||||
"notifications.column_settings.admin.report": "新しい通報:",
|
"notifications.column_settings.admin.report": "新しい通報:",
|
||||||
|
|
|
@ -308,6 +308,8 @@
|
||||||
"follow_requests.unlocked_explanation": "귀하의 계정이 잠긴 계정이 아닐지라도, {domain} 스태프는 이 계정들의 팔로우 요청을 수동으로 처리해 주시면 좋겠다고 생각했습니다.",
|
"follow_requests.unlocked_explanation": "귀하의 계정이 잠긴 계정이 아닐지라도, {domain} 스태프는 이 계정들의 팔로우 요청을 수동으로 처리해 주시면 좋겠다고 생각했습니다.",
|
||||||
"follow_suggestions.curated_suggestion": "스태프의 추천",
|
"follow_suggestions.curated_suggestion": "스태프의 추천",
|
||||||
"follow_suggestions.dismiss": "다시 보지 않기",
|
"follow_suggestions.dismiss": "다시 보지 않기",
|
||||||
|
"follow_suggestions.featured_longer": "{domain} 팀이 손수 고름",
|
||||||
|
"follow_suggestions.friends_of_friends_longer": "내가 팔로우 하는 사람들 사이에서 인기",
|
||||||
"follow_suggestions.hints.featured": "이 프로필은 {domain} 팀이 손수 선택했습니다.",
|
"follow_suggestions.hints.featured": "이 프로필은 {domain} 팀이 손수 선택했습니다.",
|
||||||
"follow_suggestions.hints.friends_of_friends": "이 프로필은 내가 팔로우 하는 사람들에게서 유명합니다.",
|
"follow_suggestions.hints.friends_of_friends": "이 프로필은 내가 팔로우 하는 사람들에게서 유명합니다.",
|
||||||
"follow_suggestions.hints.most_followed": "이 프로필은 {domain}에서 가장 많이 팔로우 된 사람들 중 하나입니다.",
|
"follow_suggestions.hints.most_followed": "이 프로필은 {domain}에서 가장 많이 팔로우 된 사람들 중 하나입니다.",
|
||||||
|
@ -315,6 +317,8 @@
|
||||||
"follow_suggestions.hints.similar_to_recently_followed": "이 프로필은 내가 최근에 팔로우 한 프로필들과 유사합니다.",
|
"follow_suggestions.hints.similar_to_recently_followed": "이 프로필은 내가 최근에 팔로우 한 프로필들과 유사합니다.",
|
||||||
"follow_suggestions.personalized_suggestion": "개인화된 추천",
|
"follow_suggestions.personalized_suggestion": "개인화된 추천",
|
||||||
"follow_suggestions.popular_suggestion": "인기있는 추천",
|
"follow_suggestions.popular_suggestion": "인기있는 추천",
|
||||||
|
"follow_suggestions.popular_suggestion_longer": "{domain}에서 인기",
|
||||||
|
"follow_suggestions.similar_to_recently_followed_longer": "내가 최근에 팔로우 한 프로필들과 유사",
|
||||||
"follow_suggestions.view_all": "모두 보기",
|
"follow_suggestions.view_all": "모두 보기",
|
||||||
"follow_suggestions.who_to_follow": "팔로우할 만한 사람",
|
"follow_suggestions.who_to_follow": "팔로우할 만한 사람",
|
||||||
"followed_tags": "팔로우 중인 해시태그",
|
"followed_tags": "팔로우 중인 해시태그",
|
||||||
|
@ -469,6 +473,15 @@
|
||||||
"notification.follow": "{name} 님이 나를 팔로우했습니다",
|
"notification.follow": "{name} 님이 나를 팔로우했습니다",
|
||||||
"notification.follow_request": "{name} 님이 팔로우 요청을 보냈습니다",
|
"notification.follow_request": "{name} 님이 팔로우 요청을 보냈습니다",
|
||||||
"notification.mention": "{name} 님의 멘션",
|
"notification.mention": "{name} 님의 멘션",
|
||||||
|
"notification.moderation-warning.learn_more": "더 알아보기",
|
||||||
|
"notification.moderation_warning": "중재 경고를 받았습니다",
|
||||||
|
"notification.moderation_warning.action_delete_statuses": "게시물 몇 개가 삭제되었습니다.",
|
||||||
|
"notification.moderation_warning.action_disable": "계정이 비활성화되었습니다.",
|
||||||
|
"notification.moderation_warning.action_mark_statuses_as_sensitive": "게시물 몇 개가 민감함 처리되었습니다.",
|
||||||
|
"notification.moderation_warning.action_none": "계정에 중재 경고를 받았습니다.",
|
||||||
|
"notification.moderation_warning.action_sensitive": "앞으로의 게시물을 민감한 것으로 표시됩니다.",
|
||||||
|
"notification.moderation_warning.action_silence": "계정이 제한되었습니다.",
|
||||||
|
"notification.moderation_warning.action_suspend": "계정이 정지되었습니다.",
|
||||||
"notification.own_poll": "설문을 마침",
|
"notification.own_poll": "설문을 마침",
|
||||||
"notification.poll": "참여한 설문이 종료됨",
|
"notification.poll": "참여한 설문이 종료됨",
|
||||||
"notification.reblog": "{name} 님이 부스트했습니다",
|
"notification.reblog": "{name} 님이 부스트했습니다",
|
||||||
|
|
|
@ -295,6 +295,7 @@
|
||||||
"follow_requests.unlocked_explanation": "Aunke tu kuento no esta serrado, la taifa de {domain} kreye ke talvez keres revizar manualmente las solisitudes de segimento de estos kuentos.",
|
"follow_requests.unlocked_explanation": "Aunke tu kuento no esta serrado, la taifa de {domain} kreye ke talvez keres revizar manualmente las solisitudes de segimento de estos kuentos.",
|
||||||
"follow_suggestions.curated_suggestion": "Seleksyon de la taifa",
|
"follow_suggestions.curated_suggestion": "Seleksyon de la taifa",
|
||||||
"follow_suggestions.dismiss": "No amostra mas",
|
"follow_suggestions.dismiss": "No amostra mas",
|
||||||
|
"follow_suggestions.friends_of_friends_longer": "Popular entre personas a las kualas siges",
|
||||||
"follow_suggestions.hints.featured": "Este profil tiene sido eskojido por la taifa de {domain}.",
|
"follow_suggestions.hints.featured": "Este profil tiene sido eskojido por la taifa de {domain}.",
|
||||||
"follow_suggestions.hints.friends_of_friends": "Este profil es popular entre las personas ke siges.",
|
"follow_suggestions.hints.friends_of_friends": "Este profil es popular entre las personas ke siges.",
|
||||||
"follow_suggestions.hints.most_followed": "Este profil es uno de los mas segidos en {domain}.",
|
"follow_suggestions.hints.most_followed": "Este profil es uno de los mas segidos en {domain}.",
|
||||||
|
@ -454,6 +455,9 @@
|
||||||
"notification.follow": "{name} te ampeso a segir",
|
"notification.follow": "{name} te ampeso a segir",
|
||||||
"notification.follow_request": "{name} tiene solisitado segirte",
|
"notification.follow_request": "{name} tiene solisitado segirte",
|
||||||
"notification.mention": "{name} te enmento",
|
"notification.mention": "{name} te enmento",
|
||||||
|
"notification.moderation-warning.learn_more": "Ambezate mas",
|
||||||
|
"notification.moderation_warning.action_silence": "Tu kuento tiene sido limitado.",
|
||||||
|
"notification.moderation_warning.action_suspend": "Tu kuento tiene sido suspendido.",
|
||||||
"notification.own_poll": "Tu anketa eskapo",
|
"notification.own_poll": "Tu anketa eskapo",
|
||||||
"notification.poll": "Anketa en ke votates eskapo",
|
"notification.poll": "Anketa en ke votates eskapo",
|
||||||
"notification.reblog": "{name} repartajo tu publikasyon",
|
"notification.reblog": "{name} repartajo tu publikasyon",
|
||||||
|
|
|
@ -282,6 +282,7 @@
|
||||||
"filter_modal.select_filter.subtitle": "Naudok esamą kategoriją arba sukurk naują.",
|
"filter_modal.select_filter.subtitle": "Naudok esamą kategoriją arba sukurk naują.",
|
||||||
"filter_modal.select_filter.title": "Filtruoti šį įrašą",
|
"filter_modal.select_filter.title": "Filtruoti šį įrašą",
|
||||||
"filter_modal.title.status": "Filtruoti įrašą",
|
"filter_modal.title.status": "Filtruoti įrašą",
|
||||||
|
"filtered_notifications_banner.mentions": "{count, plural, one {paminėjimas} few {paminėjimai} many {paminėjimo} other {paminėjimų}}",
|
||||||
"firehose.all": "Visi",
|
"firehose.all": "Visi",
|
||||||
"firehose.local": "Šis serveris",
|
"firehose.local": "Šis serveris",
|
||||||
"firehose.remote": "Kiti serveriai",
|
"firehose.remote": "Kiti serveriai",
|
||||||
|
@ -290,6 +291,8 @@
|
||||||
"follow_requests.unlocked_explanation": "Nors tavo paskyra neužrakinta, {domain} personalas mano, kad galbūt norėsi rankiniu būdu patikrinti šių paskyrų sekimo prašymus.",
|
"follow_requests.unlocked_explanation": "Nors tavo paskyra neužrakinta, {domain} personalas mano, kad galbūt norėsi rankiniu būdu patikrinti šių paskyrų sekimo prašymus.",
|
||||||
"follow_suggestions.curated_suggestion": "Personalo pasirinkimai",
|
"follow_suggestions.curated_suggestion": "Personalo pasirinkimai",
|
||||||
"follow_suggestions.dismiss": "Daugiau nerodyti",
|
"follow_suggestions.dismiss": "Daugiau nerodyti",
|
||||||
|
"follow_suggestions.featured_longer": "Rankomis atrinkta {domain} komanda",
|
||||||
|
"follow_suggestions.friends_of_friends_longer": "Populiarus tarp žmonių, kurių seki",
|
||||||
"follow_suggestions.hints.featured": "Šį profilį atrinko {domain} komanda.",
|
"follow_suggestions.hints.featured": "Šį profilį atrinko {domain} komanda.",
|
||||||
"follow_suggestions.hints.friends_of_friends": "Šis profilis yra populiarus tarp žmonių, kuriuos seki.",
|
"follow_suggestions.hints.friends_of_friends": "Šis profilis yra populiarus tarp žmonių, kuriuos seki.",
|
||||||
"follow_suggestions.hints.most_followed": "Šis profilis yra vienas iš labiausiai sekamų {domain}.",
|
"follow_suggestions.hints.most_followed": "Šis profilis yra vienas iš labiausiai sekamų {domain}.",
|
||||||
|
@ -297,6 +300,8 @@
|
||||||
"follow_suggestions.hints.similar_to_recently_followed": "Šis profilis panašus į profilius, kuriuos neseniai sekei.",
|
"follow_suggestions.hints.similar_to_recently_followed": "Šis profilis panašus į profilius, kuriuos neseniai sekei.",
|
||||||
"follow_suggestions.personalized_suggestion": "Suasmenintas pasiūlymas",
|
"follow_suggestions.personalized_suggestion": "Suasmenintas pasiūlymas",
|
||||||
"follow_suggestions.popular_suggestion": "Populiarus pasiūlymas",
|
"follow_suggestions.popular_suggestion": "Populiarus pasiūlymas",
|
||||||
|
"follow_suggestions.popular_suggestion_longer": "Populiarus domene {domain}",
|
||||||
|
"follow_suggestions.similar_to_recently_followed_longer": "Panašūs į profilius, kuriuos neseniai seki",
|
||||||
"follow_suggestions.view_all": "Peržiūrėti viską",
|
"follow_suggestions.view_all": "Peržiūrėti viską",
|
||||||
"follow_suggestions.who_to_follow": "Ką sekti",
|
"follow_suggestions.who_to_follow": "Ką sekti",
|
||||||
"followed_tags": "Sekami saitažodžiai",
|
"followed_tags": "Sekami saitažodžiai",
|
||||||
|
@ -442,6 +447,15 @@
|
||||||
"notification.follow": "{name} seka tave",
|
"notification.follow": "{name} seka tave",
|
||||||
"notification.follow_request": "{name} paprašė tave sekti",
|
"notification.follow_request": "{name} paprašė tave sekti",
|
||||||
"notification.mention": "{name} paminėjo tave",
|
"notification.mention": "{name} paminėjo tave",
|
||||||
|
"notification.moderation-warning.learn_more": "Sužinoti daugiau",
|
||||||
|
"notification.moderation_warning": "Gavai prižiūrėjimo įspėjimą",
|
||||||
|
"notification.moderation_warning.action_delete_statuses": "Kai kurie tavo įrašai buvo pašalintos.",
|
||||||
|
"notification.moderation_warning.action_disable": "Tavo paskyra buvo išjungta.",
|
||||||
|
"notification.moderation_warning.action_mark_statuses_as_sensitive": "Kai kurie tavo įrašai buvo pažymėtos kaip jautrios.",
|
||||||
|
"notification.moderation_warning.action_none": "Tavo paskyra gavo prižiūrėjimo įspėjimą.",
|
||||||
|
"notification.moderation_warning.action_sensitive": "Nuo šiol tavo įrašai bus pažymėti kaip jautrūs.",
|
||||||
|
"notification.moderation_warning.action_silence": "Tavo paskyra buvo apribota.",
|
||||||
|
"notification.moderation_warning.action_suspend": "Tavo paskyra buvo sustabdyta.",
|
||||||
"notification.own_poll": "Tavo apklausa baigėsi",
|
"notification.own_poll": "Tavo apklausa baigėsi",
|
||||||
"notification.poll": "Apklausa, kurioje balsavai, pasibaigė",
|
"notification.poll": "Apklausa, kurioje balsavai, pasibaigė",
|
||||||
"notification.reblog": "{name} pakėlė tavo įrašą",
|
"notification.reblog": "{name} pakėlė tavo įrašą",
|
||||||
|
|
|
@ -308,13 +308,17 @@
|
||||||
"follow_requests.unlocked_explanation": "Ook al is jouw account niet besloten, de medewerkers van {domain} denken dat jij misschien de volgende volgverzoeken handmatig wil controleren.",
|
"follow_requests.unlocked_explanation": "Ook al is jouw account niet besloten, de medewerkers van {domain} denken dat jij misschien de volgende volgverzoeken handmatig wil controleren.",
|
||||||
"follow_suggestions.curated_suggestion": "Speciaal geselecteerd",
|
"follow_suggestions.curated_suggestion": "Speciaal geselecteerd",
|
||||||
"follow_suggestions.dismiss": "Niet meer weergeven",
|
"follow_suggestions.dismiss": "Niet meer weergeven",
|
||||||
"follow_suggestions.hints.featured": "Deze gebruiker is geselecteerd door het team van {domain}.",
|
"follow_suggestions.featured_longer": "Handmatig geselecteerd door het team van {domain}",
|
||||||
|
"follow_suggestions.friends_of_friends_longer": "Populair onder mensen die je volgt",
|
||||||
|
"follow_suggestions.hints.featured": "Deze gebruiker is handmatig geselecteerd door het team van {domain}.",
|
||||||
"follow_suggestions.hints.friends_of_friends": "Deze gebruiker is populair onder de mensen die jij volgt.",
|
"follow_suggestions.hints.friends_of_friends": "Deze gebruiker is populair onder de mensen die jij volgt.",
|
||||||
"follow_suggestions.hints.most_followed": "Deze gebruiker is een van de meest gevolgde gebruikers op {domain}.",
|
"follow_suggestions.hints.most_followed": "Deze gebruiker is een van de meest gevolgde gebruikers op {domain}.",
|
||||||
"follow_suggestions.hints.most_interactions": "Deze gebruiker is de laatste tijd erg populair op {domain}.",
|
"follow_suggestions.hints.most_interactions": "Deze gebruiker is de laatste tijd erg populair op {domain}.",
|
||||||
"follow_suggestions.hints.similar_to_recently_followed": "Deze gebruiker is vergelijkbaar met gebruikers die je recentelijk hebt gevolgd.",
|
"follow_suggestions.hints.similar_to_recently_followed": "Deze gebruiker is vergelijkbaar met gebruikers die je recentelijk hebt gevolgd.",
|
||||||
"follow_suggestions.personalized_suggestion": "Gepersonaliseerde aanbeveling",
|
"follow_suggestions.personalized_suggestion": "Gepersonaliseerde aanbeveling",
|
||||||
"follow_suggestions.popular_suggestion": "Populaire aanbeveling",
|
"follow_suggestions.popular_suggestion": "Populaire aanbeveling",
|
||||||
|
"follow_suggestions.popular_suggestion_longer": "Populair op {domain}",
|
||||||
|
"follow_suggestions.similar_to_recently_followed_longer": "Vergelijkbaar met accounts die je recentelijk bent gaan volgen",
|
||||||
"follow_suggestions.view_all": "Alles weergeven",
|
"follow_suggestions.view_all": "Alles weergeven",
|
||||||
"follow_suggestions.who_to_follow": "Wie te volgen",
|
"follow_suggestions.who_to_follow": "Wie te volgen",
|
||||||
"followed_tags": "Gevolgde hashtags",
|
"followed_tags": "Gevolgde hashtags",
|
||||||
|
@ -469,6 +473,15 @@
|
||||||
"notification.follow": "{name} volgt jou nu",
|
"notification.follow": "{name} volgt jou nu",
|
||||||
"notification.follow_request": "{name} wil jou graag volgen",
|
"notification.follow_request": "{name} wil jou graag volgen",
|
||||||
"notification.mention": "{name} vermeldde jou",
|
"notification.mention": "{name} vermeldde jou",
|
||||||
|
"notification.moderation-warning.learn_more": "Meer informatie",
|
||||||
|
"notification.moderation_warning": "Je hebt een moderatie-waarschuwing ontvangen",
|
||||||
|
"notification.moderation_warning.action_delete_statuses": "Sommige van je berichten zijn verwijderd.",
|
||||||
|
"notification.moderation_warning.action_disable": "Je account is uitgeschakeld.",
|
||||||
|
"notification.moderation_warning.action_mark_statuses_as_sensitive": "Sommige van je berichten zijn gemarkeerd als gevoelig.",
|
||||||
|
"notification.moderation_warning.action_none": "Jouw account heeft een moderatie-waarschuwing ontvangen.",
|
||||||
|
"notification.moderation_warning.action_sensitive": "Je berichten worden vanaf nu als gevoelig gemarkeerd.",
|
||||||
|
"notification.moderation_warning.action_silence": "Jouw account is beperkt.",
|
||||||
|
"notification.moderation_warning.action_suspend": "Jouw account is opgeschort.",
|
||||||
"notification.own_poll": "Jouw peiling is beëindigd",
|
"notification.own_poll": "Jouw peiling is beëindigd",
|
||||||
"notification.poll": "Een peiling waaraan jij hebt meegedaan is beëindigd",
|
"notification.poll": "Een peiling waaraan jij hebt meegedaan is beëindigd",
|
||||||
"notification.reblog": "{name} boostte jouw bericht",
|
"notification.reblog": "{name} boostte jouw bericht",
|
||||||
|
|
|
@ -468,6 +468,15 @@
|
||||||
"notification.follow": "{name} fylgde deg",
|
"notification.follow": "{name} fylgde deg",
|
||||||
"notification.follow_request": "{name} har bedt om å fylgja deg",
|
"notification.follow_request": "{name} har bedt om å fylgja deg",
|
||||||
"notification.mention": "{name} nemnde deg",
|
"notification.mention": "{name} nemnde deg",
|
||||||
|
"notification.moderation-warning.learn_more": "Lær meir",
|
||||||
|
"notification.moderation_warning": "Du har mottatt ei moderasjonsåtvaring",
|
||||||
|
"notification.moderation_warning.action_delete_statuses": "Nokre av innlegga dine har blitt fjerna.",
|
||||||
|
"notification.moderation_warning.action_disable": "Kontoen din har blitt deaktivert.",
|
||||||
|
"notification.moderation_warning.action_mark_statuses_as_sensitive": "Nokre av innlegga dine har blitt markert som sensitive.",
|
||||||
|
"notification.moderation_warning.action_none": "Kontoen din har mottatt ei moderasjonsåtvaring.",
|
||||||
|
"notification.moderation_warning.action_sensitive": "Innlegga dine vil bli markerte som sensitive frå no av.",
|
||||||
|
"notification.moderation_warning.action_silence": "Kontoen din har blitt avgrensa.",
|
||||||
|
"notification.moderation_warning.action_suspend": "Kontoen din har blitt suspendert.",
|
||||||
"notification.own_poll": "Rundspørjinga di er ferdig",
|
"notification.own_poll": "Rundspørjinga di er ferdig",
|
||||||
"notification.poll": "Ei rundspørjing du har røysta i er ferdig",
|
"notification.poll": "Ei rundspørjing du har røysta i er ferdig",
|
||||||
"notification.reblog": "{name} framheva innlegget ditt",
|
"notification.reblog": "{name} framheva innlegget ditt",
|
||||||
|
|
|
@ -308,6 +308,8 @@
|
||||||
"follow_requests.unlocked_explanation": "Mimo że Twoje konto nie jest zablokowane, zespół {domain} uznał że możesz chcieć ręcznie przejrzeć prośby o możliwość obserwacji.",
|
"follow_requests.unlocked_explanation": "Mimo że Twoje konto nie jest zablokowane, zespół {domain} uznał że możesz chcieć ręcznie przejrzeć prośby o możliwość obserwacji.",
|
||||||
"follow_suggestions.curated_suggestion": "Wybrane przez personel",
|
"follow_suggestions.curated_suggestion": "Wybrane przez personel",
|
||||||
"follow_suggestions.dismiss": "Nie pokazuj ponownie",
|
"follow_suggestions.dismiss": "Nie pokazuj ponownie",
|
||||||
|
"follow_suggestions.featured_longer": "Wybrane przez zespół {domain}",
|
||||||
|
"follow_suggestions.friends_of_friends_longer": "Popularni wśród ludzi których obserwujesz",
|
||||||
"follow_suggestions.hints.featured": "Ten profil został wybrany przez zespół {domain}.",
|
"follow_suggestions.hints.featured": "Ten profil został wybrany przez zespół {domain}.",
|
||||||
"follow_suggestions.hints.friends_of_friends": "Ten profil jest popularny w gronie użytkowników, których obserwujesz.",
|
"follow_suggestions.hints.friends_of_friends": "Ten profil jest popularny w gronie użytkowników, których obserwujesz.",
|
||||||
"follow_suggestions.hints.most_followed": "Ten profil jest jednym z najczęściej obserwowanych na {domain}.",
|
"follow_suggestions.hints.most_followed": "Ten profil jest jednym z najczęściej obserwowanych na {domain}.",
|
||||||
|
@ -315,6 +317,8 @@
|
||||||
"follow_suggestions.hints.similar_to_recently_followed": "Ten profil jest podobny do profili ostatnio przez ciebie zaobserwowanych.",
|
"follow_suggestions.hints.similar_to_recently_followed": "Ten profil jest podobny do profili ostatnio przez ciebie zaobserwowanych.",
|
||||||
"follow_suggestions.personalized_suggestion": "Sugestia spersonalizowana",
|
"follow_suggestions.personalized_suggestion": "Sugestia spersonalizowana",
|
||||||
"follow_suggestions.popular_suggestion": "Sugestia popularna",
|
"follow_suggestions.popular_suggestion": "Sugestia popularna",
|
||||||
|
"follow_suggestions.popular_suggestion_longer": "Popularni na {domain}",
|
||||||
|
"follow_suggestions.similar_to_recently_followed_longer": "Podobne do ostatnio zaobserwowanych przez ciebie profilów",
|
||||||
"follow_suggestions.view_all": "Pokaż wszystkie",
|
"follow_suggestions.view_all": "Pokaż wszystkie",
|
||||||
"follow_suggestions.who_to_follow": "Kogo obserwować",
|
"follow_suggestions.who_to_follow": "Kogo obserwować",
|
||||||
"followed_tags": "Obserwowane hasztagi",
|
"followed_tags": "Obserwowane hasztagi",
|
||||||
|
@ -469,6 +473,15 @@
|
||||||
"notification.follow": "{name} obserwuje Cię",
|
"notification.follow": "{name} obserwuje Cię",
|
||||||
"notification.follow_request": "{name} chce cię zaobserwować",
|
"notification.follow_request": "{name} chce cię zaobserwować",
|
||||||
"notification.mention": "Wspomniało o Tobie przez {name}",
|
"notification.mention": "Wspomniało o Tobie przez {name}",
|
||||||
|
"notification.moderation-warning.learn_more": "Dowiedz się więcej",
|
||||||
|
"notification.moderation_warning": "Otrzymałeś/-łaś ostrzeżenie moderacyjne",
|
||||||
|
"notification.moderation_warning.action_delete_statuses": "Niektóre twoje wpisy zostały usunięte.",
|
||||||
|
"notification.moderation_warning.action_disable": "Twoje konto zostało wyłączone.",
|
||||||
|
"notification.moderation_warning.action_mark_statuses_as_sensitive": "Niektóre twoje wpisy zostały oznaczone jako wrażliwe.",
|
||||||
|
"notification.moderation_warning.action_none": "Twoje konto otrzymało ostrzeżenie moderacyjne.",
|
||||||
|
"notification.moderation_warning.action_sensitive": "Twoje wpisy będą od teraz oznaczane jako wrażliwe.",
|
||||||
|
"notification.moderation_warning.action_silence": "Twoje konto zostało ograniczone.",
|
||||||
|
"notification.moderation_warning.action_suspend": "Twoje konto zostało zawieszone.",
|
||||||
"notification.own_poll": "Twoje głosowanie zakończyło się",
|
"notification.own_poll": "Twoje głosowanie zakończyło się",
|
||||||
"notification.poll": "Głosowanie w którym brałeś(-aś) udział zakończyło się",
|
"notification.poll": "Głosowanie w którym brałeś(-aś) udział zakończyło się",
|
||||||
"notification.reblog": "Twój post został podbity przez {name}",
|
"notification.reblog": "Twój post został podbity przez {name}",
|
||||||
|
|
|
@ -297,6 +297,7 @@
|
||||||
"filter_modal.select_filter.subtitle": "Use uma categoria existente ou crie uma nova",
|
"filter_modal.select_filter.subtitle": "Use uma categoria existente ou crie uma nova",
|
||||||
"filter_modal.select_filter.title": "Filtrar esta publicação",
|
"filter_modal.select_filter.title": "Filtrar esta publicação",
|
||||||
"filter_modal.title.status": "Filtrar uma publicação",
|
"filter_modal.title.status": "Filtrar uma publicação",
|
||||||
|
"filtered_notifications_banner.mentions": "{count, plural, one {menção} other {menções}}",
|
||||||
"filtered_notifications_banner.pending_requests": "Notificações de {count, plural, =0 {no one} one {one person} other {# people}} que você talvez conheça",
|
"filtered_notifications_banner.pending_requests": "Notificações de {count, plural, =0 {no one} one {one person} other {# people}} que você talvez conheça",
|
||||||
"filtered_notifications_banner.title": "Notificações filtradas",
|
"filtered_notifications_banner.title": "Notificações filtradas",
|
||||||
"firehose.all": "Tudo",
|
"firehose.all": "Tudo",
|
||||||
|
@ -307,6 +308,8 @@
|
||||||
"follow_requests.unlocked_explanation": "Apesar de seu perfil não ser trancado, {domain} exige que você revise a solicitação para te seguir destes perfis manualmente.",
|
"follow_requests.unlocked_explanation": "Apesar de seu perfil não ser trancado, {domain} exige que você revise a solicitação para te seguir destes perfis manualmente.",
|
||||||
"follow_suggestions.curated_suggestion": "Escolha da equipe",
|
"follow_suggestions.curated_suggestion": "Escolha da equipe",
|
||||||
"follow_suggestions.dismiss": "Não mostrar novamente",
|
"follow_suggestions.dismiss": "Não mostrar novamente",
|
||||||
|
"follow_suggestions.featured_longer": "Escolhido à mão pela equipe de {domain}",
|
||||||
|
"follow_suggestions.friends_of_friends_longer": "Popular entre as pessoas que você segue",
|
||||||
"follow_suggestions.hints.featured": "Este perfil foi escolhido a dedo pela equipe {domain}.",
|
"follow_suggestions.hints.featured": "Este perfil foi escolhido a dedo pela equipe {domain}.",
|
||||||
"follow_suggestions.hints.friends_of_friends": "Este perfil é popular entre as pessoas que você segue.",
|
"follow_suggestions.hints.friends_of_friends": "Este perfil é popular entre as pessoas que você segue.",
|
||||||
"follow_suggestions.hints.most_followed": "Este perfil é um dos mais seguidos em {domain}.",
|
"follow_suggestions.hints.most_followed": "Este perfil é um dos mais seguidos em {domain}.",
|
||||||
|
@ -314,6 +317,8 @@
|
||||||
"follow_suggestions.hints.similar_to_recently_followed": "Este perfil é semelhante aos perfis que você seguiu recentemente.",
|
"follow_suggestions.hints.similar_to_recently_followed": "Este perfil é semelhante aos perfis que você seguiu recentemente.",
|
||||||
"follow_suggestions.personalized_suggestion": "Sugestão personalizada",
|
"follow_suggestions.personalized_suggestion": "Sugestão personalizada",
|
||||||
"follow_suggestions.popular_suggestion": "Sugestão popular",
|
"follow_suggestions.popular_suggestion": "Sugestão popular",
|
||||||
|
"follow_suggestions.popular_suggestion_longer": "Popular em {domain}",
|
||||||
|
"follow_suggestions.similar_to_recently_followed_longer": "Similar a perfis que você seguiu recentemente",
|
||||||
"follow_suggestions.view_all": "Visualizar tudo",
|
"follow_suggestions.view_all": "Visualizar tudo",
|
||||||
"follow_suggestions.who_to_follow": "Quem seguir",
|
"follow_suggestions.who_to_follow": "Quem seguir",
|
||||||
"followed_tags": "Hashtags seguidas",
|
"followed_tags": "Hashtags seguidas",
|
||||||
|
@ -468,6 +473,15 @@
|
||||||
"notification.follow": "{name} te seguiu",
|
"notification.follow": "{name} te seguiu",
|
||||||
"notification.follow_request": "{name} quer te seguir",
|
"notification.follow_request": "{name} quer te seguir",
|
||||||
"notification.mention": "{name} te mencionou",
|
"notification.mention": "{name} te mencionou",
|
||||||
|
"notification.moderation-warning.learn_more": "Aprender mais",
|
||||||
|
"notification.moderation_warning": "Você recebeu um aviso de moderação",
|
||||||
|
"notification.moderation_warning.action_delete_statuses": "Algumas das suas publicações foram removidas.",
|
||||||
|
"notification.moderation_warning.action_disable": "Sua conta foi desativada.",
|
||||||
|
"notification.moderation_warning.action_mark_statuses_as_sensitive": "Algumas de suas publicações foram marcadas por ter conteúdo sensível.",
|
||||||
|
"notification.moderation_warning.action_none": "Sua conta recebeu um aviso de moderação.",
|
||||||
|
"notification.moderation_warning.action_sensitive": "Suas publicações serão marcadas como sensíveis a partir de agora.",
|
||||||
|
"notification.moderation_warning.action_silence": "Sua conta foi limitada.",
|
||||||
|
"notification.moderation_warning.action_suspend": "Sua conta foi suspensa.",
|
||||||
"notification.own_poll": "Sua enquete terminou",
|
"notification.own_poll": "Sua enquete terminou",
|
||||||
"notification.poll": "Uma enquete que você votou terminou",
|
"notification.poll": "Uma enquete que você votou terminou",
|
||||||
"notification.reblog": "{name} deu boost no teu toot",
|
"notification.reblog": "{name} deu boost no teu toot",
|
||||||
|
|
|
@ -308,6 +308,8 @@
|
||||||
"follow_requests.unlocked_explanation": "Apesar de a sua não ser privada, a administração de {domain} pensa que poderá querer rever manualmente os pedidos de seguimento dessas contas.",
|
"follow_requests.unlocked_explanation": "Apesar de a sua não ser privada, a administração de {domain} pensa que poderá querer rever manualmente os pedidos de seguimento dessas contas.",
|
||||||
"follow_suggestions.curated_suggestion": "Escolha da equipe",
|
"follow_suggestions.curated_suggestion": "Escolha da equipe",
|
||||||
"follow_suggestions.dismiss": "Não mostrar novamente",
|
"follow_suggestions.dismiss": "Não mostrar novamente",
|
||||||
|
"follow_suggestions.featured_longer": "Escolhido a dedo pela equipa de {domain}",
|
||||||
|
"follow_suggestions.friends_of_friends_longer": "Popular entre as pessoas que segue",
|
||||||
"follow_suggestions.hints.featured": "Este perfil foi escolhido a dedo pela equipe {domain}.",
|
"follow_suggestions.hints.featured": "Este perfil foi escolhido a dedo pela equipe {domain}.",
|
||||||
"follow_suggestions.hints.friends_of_friends": "Este perfil é popular entre as pessoas que você segue.",
|
"follow_suggestions.hints.friends_of_friends": "Este perfil é popular entre as pessoas que você segue.",
|
||||||
"follow_suggestions.hints.most_followed": "Este perfil é um dos mais seguidos no {domain}.",
|
"follow_suggestions.hints.most_followed": "Este perfil é um dos mais seguidos no {domain}.",
|
||||||
|
@ -315,6 +317,8 @@
|
||||||
"follow_suggestions.hints.similar_to_recently_followed": "Este perfil é semelhante aos perfis que você seguiu mais recentemente.",
|
"follow_suggestions.hints.similar_to_recently_followed": "Este perfil é semelhante aos perfis que você seguiu mais recentemente.",
|
||||||
"follow_suggestions.personalized_suggestion": "Sugestão personalizada",
|
"follow_suggestions.personalized_suggestion": "Sugestão personalizada",
|
||||||
"follow_suggestions.popular_suggestion": "Sugestão popular",
|
"follow_suggestions.popular_suggestion": "Sugestão popular",
|
||||||
|
"follow_suggestions.popular_suggestion_longer": "Popular em {domain}",
|
||||||
|
"follow_suggestions.similar_to_recently_followed_longer": "Semelhantes aos perfis que seguiu recentemente",
|
||||||
"follow_suggestions.view_all": "Ver tudo",
|
"follow_suggestions.view_all": "Ver tudo",
|
||||||
"follow_suggestions.who_to_follow": "Quem seguir",
|
"follow_suggestions.who_to_follow": "Quem seguir",
|
||||||
"followed_tags": "Hashtags seguidas",
|
"followed_tags": "Hashtags seguidas",
|
||||||
|
@ -469,6 +473,15 @@
|
||||||
"notification.follow": "{name} começou a seguir-te",
|
"notification.follow": "{name} começou a seguir-te",
|
||||||
"notification.follow_request": "{name} pediu para segui-lo",
|
"notification.follow_request": "{name} pediu para segui-lo",
|
||||||
"notification.mention": "{name} mencionou-te",
|
"notification.mention": "{name} mencionou-te",
|
||||||
|
"notification.moderation-warning.learn_more": "Saber mais",
|
||||||
|
"notification.moderation_warning": "Recebeu um aviso de moderação",
|
||||||
|
"notification.moderation_warning.action_delete_statuses": "Algumas das suas publicações foram removidas.",
|
||||||
|
"notification.moderation_warning.action_disable": "A sua conta foi desativada.",
|
||||||
|
"notification.moderation_warning.action_mark_statuses_as_sensitive": "Algumas das suas publicações foram assinaladas como sensíveis.",
|
||||||
|
"notification.moderation_warning.action_none": "A sua conta recebeu um aviso de moderação.",
|
||||||
|
"notification.moderation_warning.action_sensitive": "As suas publicações serão, a partir de agora, assinaladas como sensíveis.",
|
||||||
|
"notification.moderation_warning.action_silence": "A sua conta foi limitada.",
|
||||||
|
"notification.moderation_warning.action_suspend": "A sua conta foi suspensa.",
|
||||||
"notification.own_poll": "A sua votação terminou",
|
"notification.own_poll": "A sua votação terminou",
|
||||||
"notification.poll": "Uma votação em que participaste chegou ao fim",
|
"notification.poll": "Uma votação em que participaste chegou ao fim",
|
||||||
"notification.reblog": "{name} reforçou a tua publicação",
|
"notification.reblog": "{name} reforçou a tua publicação",
|
||||||
|
|
|
@ -246,6 +246,7 @@
|
||||||
"empty_column.list": "Tento zoznam je zatiaľ prázdny. Keď ale členovia tohoto zoznamu uverejnia nové príspevky, objavia sa tu.",
|
"empty_column.list": "Tento zoznam je zatiaľ prázdny. Keď ale členovia tohoto zoznamu uverejnia nové príspevky, objavia sa tu.",
|
||||||
"empty_column.lists": "Zatiaľ nemáte žiadne zoznamy. Keď nejaký vytvoríte, zobrazí sa tu.",
|
"empty_column.lists": "Zatiaľ nemáte žiadne zoznamy. Keď nejaký vytvoríte, zobrazí sa tu.",
|
||||||
"empty_column.mutes": "Zatiaľ ste si nikoho nestíšili.",
|
"empty_column.mutes": "Zatiaľ ste si nikoho nestíšili.",
|
||||||
|
"empty_column.notification_requests": "Všetko čisté! Nič tu nieje. Keď dostaneš nové oboznámenia, zobrazia sa tu podľa tvojich nastavení.",
|
||||||
"empty_column.notifications": "Zatiaľ nemáte žiadne upozornenia. Začnú vám pribúdať, keď s vami začnú interagovať ostatní.",
|
"empty_column.notifications": "Zatiaľ nemáte žiadne upozornenia. Začnú vám pribúdať, keď s vami začnú interagovať ostatní.",
|
||||||
"empty_column.public": "Zatiaľ tu nič nie je. Napíšte niečo verejné alebo začnite sledovať účty z iných serverov, aby tu niečo pribudlo.",
|
"empty_column.public": "Zatiaľ tu nič nie je. Napíšte niečo verejné alebo začnite sledovať účty z iných serverov, aby tu niečo pribudlo.",
|
||||||
"error.unexpected_crash.explanation": "Pre chybu v našom kóde alebo problém s kompatibilitou prehliadača nebolo túto stránku možné zobraziť správne.",
|
"error.unexpected_crash.explanation": "Pre chybu v našom kóde alebo problém s kompatibilitou prehliadača nebolo túto stránku možné zobraziť správne.",
|
||||||
|
@ -293,6 +294,7 @@
|
||||||
"follow_suggestions.hints.similar_to_recently_followed": "Tento profil je podobný profilom, ktoré ste nedávno začali sledovať.",
|
"follow_suggestions.hints.similar_to_recently_followed": "Tento profil je podobný profilom, ktoré ste nedávno začali sledovať.",
|
||||||
"follow_suggestions.personalized_suggestion": "Prispôsobený návrh",
|
"follow_suggestions.personalized_suggestion": "Prispôsobený návrh",
|
||||||
"follow_suggestions.popular_suggestion": "Obľúbený návrh",
|
"follow_suggestions.popular_suggestion": "Obľúbený návrh",
|
||||||
|
"follow_suggestions.popular_suggestion_longer": "Populárne na {domain}",
|
||||||
"follow_suggestions.view_all": "Zobraziť všetky",
|
"follow_suggestions.view_all": "Zobraziť všetky",
|
||||||
"follow_suggestions.who_to_follow": "Koho sledovať",
|
"follow_suggestions.who_to_follow": "Koho sledovať",
|
||||||
"followed_tags": "Sledované hashtagy",
|
"followed_tags": "Sledované hashtagy",
|
||||||
|
@ -442,9 +444,11 @@
|
||||||
"notification.follow": "{name} vás sleduje",
|
"notification.follow": "{name} vás sleduje",
|
||||||
"notification.follow_request": "{name} vás žiada sledovať",
|
"notification.follow_request": "{name} vás žiada sledovať",
|
||||||
"notification.mention": "{name} vás spomína",
|
"notification.mention": "{name} vás spomína",
|
||||||
|
"notification.moderation-warning.learn_more": "Zisti viac",
|
||||||
"notification.own_poll": "Vaša anketa sa skončila",
|
"notification.own_poll": "Vaša anketa sa skončila",
|
||||||
"notification.poll": "Anketa, v ktorej ste hlasovali, sa skončila",
|
"notification.poll": "Anketa, v ktorej ste hlasovali, sa skončila",
|
||||||
"notification.reblog": "{name} zdieľa váš príspevok",
|
"notification.reblog": "{name} zdieľa váš príspevok",
|
||||||
|
"notification.relationships_severance_event": "Stratené prepojenia s {name}",
|
||||||
"notification.relationships_severance_event.learn_more": "Zisti viac",
|
"notification.relationships_severance_event.learn_more": "Zisti viac",
|
||||||
"notification.status": "{name} uverejňuje niečo nové",
|
"notification.status": "{name} uverejňuje niečo nové",
|
||||||
"notification.update": "{name} upravuje príspevok",
|
"notification.update": "{name} upravuje príspevok",
|
||||||
|
@ -487,6 +491,7 @@
|
||||||
"notifications.policy.filter_new_accounts_title": "Nové účty",
|
"notifications.policy.filter_new_accounts_title": "Nové účty",
|
||||||
"notifications.policy.filter_not_followers_title": "Ľudia, ktorí ťa nenasledujú",
|
"notifications.policy.filter_not_followers_title": "Ľudia, ktorí ťa nenasledujú",
|
||||||
"notifications.policy.filter_not_following_title": "Ľudia, ktorých nenasleduješ",
|
"notifications.policy.filter_not_following_title": "Ľudia, ktorých nenasleduješ",
|
||||||
|
"notifications.policy.filter_private_mentions_title": "Nevyžiadané priame spomenutia",
|
||||||
"notifications.policy.title": "Filtrovať oznámenia od…",
|
"notifications.policy.title": "Filtrovať oznámenia od…",
|
||||||
"notifications_permission_banner.enable": "Povoliť upozornenia na ploche",
|
"notifications_permission_banner.enable": "Povoliť upozornenia na ploche",
|
||||||
"notifications_permission_banner.how_to_control": "Ak chcete dostávať upozornenia, keď Mastodon nie je otvorený, povoľte upozornenia na ploche. Po ich zapnutí môžete presne kontrolovať, ktoré typy interakcií generujú upozornenia na ploche, a to prostredníctvom tlačidla {icon} vyššie.",
|
"notifications_permission_banner.how_to_control": "Ak chcete dostávať upozornenia, keď Mastodon nie je otvorený, povoľte upozornenia na ploche. Po ich zapnutí môžete presne kontrolovať, ktoré typy interakcií generujú upozornenia na ploche, a to prostredníctvom tlačidla {icon} vyššie.",
|
||||||
|
|
|
@ -308,6 +308,8 @@
|
||||||
"follow_requests.unlocked_explanation": "Iako vaš nalog nije zaključan, osoblje {domain} smatra da biste možda želeli da ručno pregledate zahteve za praćenje sa ovih naloga.",
|
"follow_requests.unlocked_explanation": "Iako vaš nalog nije zaključan, osoblje {domain} smatra da biste možda želeli da ručno pregledate zahteve za praćenje sa ovih naloga.",
|
||||||
"follow_suggestions.curated_suggestion": "Izbor osoblja",
|
"follow_suggestions.curated_suggestion": "Izbor osoblja",
|
||||||
"follow_suggestions.dismiss": "Ne prikazuj ponovo",
|
"follow_suggestions.dismiss": "Ne prikazuj ponovo",
|
||||||
|
"follow_suggestions.featured_longer": "Ručno odabrao tim {domain}",
|
||||||
|
"follow_suggestions.friends_of_friends_longer": "Popularno među ljudima koje pratite",
|
||||||
"follow_suggestions.hints.featured": "Ovaj profil je ručno izabrao tim {domain}.",
|
"follow_suggestions.hints.featured": "Ovaj profil je ručno izabrao tim {domain}.",
|
||||||
"follow_suggestions.hints.friends_of_friends": "Ovaj profil je popularan među ljudima koje pratite.",
|
"follow_suggestions.hints.friends_of_friends": "Ovaj profil je popularan među ljudima koje pratite.",
|
||||||
"follow_suggestions.hints.most_followed": "Ovaj profil je jedan od najpraćenijih na {domain}.",
|
"follow_suggestions.hints.most_followed": "Ovaj profil je jedan od najpraćenijih na {domain}.",
|
||||||
|
@ -315,6 +317,8 @@
|
||||||
"follow_suggestions.hints.similar_to_recently_followed": "Ovaj profil je sličan profilima koje ste nedavno zapratili.",
|
"follow_suggestions.hints.similar_to_recently_followed": "Ovaj profil je sličan profilima koje ste nedavno zapratili.",
|
||||||
"follow_suggestions.personalized_suggestion": "Personalizovani predlog",
|
"follow_suggestions.personalized_suggestion": "Personalizovani predlog",
|
||||||
"follow_suggestions.popular_suggestion": "Popularni predlog",
|
"follow_suggestions.popular_suggestion": "Popularni predlog",
|
||||||
|
"follow_suggestions.popular_suggestion_longer": "Popularno na {domain}",
|
||||||
|
"follow_suggestions.similar_to_recently_followed_longer": "Slično profilima koje ste nedavno zapratili",
|
||||||
"follow_suggestions.view_all": "Prikaži sve",
|
"follow_suggestions.view_all": "Prikaži sve",
|
||||||
"follow_suggestions.who_to_follow": "Koga pratiti",
|
"follow_suggestions.who_to_follow": "Koga pratiti",
|
||||||
"followed_tags": "Praćene heš oznake",
|
"followed_tags": "Praćene heš oznake",
|
||||||
|
@ -469,6 +473,15 @@
|
||||||
"notification.follow": "{name} vas je zapratio",
|
"notification.follow": "{name} vas je zapratio",
|
||||||
"notification.follow_request": "{name} je zatražio da vas prati",
|
"notification.follow_request": "{name} je zatražio da vas prati",
|
||||||
"notification.mention": "{name} vas je pomenuo",
|
"notification.mention": "{name} vas je pomenuo",
|
||||||
|
"notification.moderation-warning.learn_more": "Saznajte više",
|
||||||
|
"notification.moderation_warning": "Dobili ste moderatorsko upozorenje",
|
||||||
|
"notification.moderation_warning.action_delete_statuses": "Neke od vaših objava su uklonjene.",
|
||||||
|
"notification.moderation_warning.action_disable": "Vaš nalog je onemogućen.",
|
||||||
|
"notification.moderation_warning.action_mark_statuses_as_sensitive": "Neke od vaših objava su obeležene kao osetljive.",
|
||||||
|
"notification.moderation_warning.action_none": "Vaš nalog je dobio moderatorsko upozorenje.",
|
||||||
|
"notification.moderation_warning.action_sensitive": "Vaše objave će ubuduće biti označene kao osetljive.",
|
||||||
|
"notification.moderation_warning.action_silence": "Vaš nalog je ograničen.",
|
||||||
|
"notification.moderation_warning.action_suspend": "Vaš nalog je suspendovan.",
|
||||||
"notification.own_poll": "Vaša anketa je završena",
|
"notification.own_poll": "Vaša anketa je završena",
|
||||||
"notification.poll": "Završena je anketa u kojoj ste glasali",
|
"notification.poll": "Završena je anketa u kojoj ste glasali",
|
||||||
"notification.reblog": "{name} je podržao vašu objavu",
|
"notification.reblog": "{name} je podržao vašu objavu",
|
||||||
|
|
|
@ -308,6 +308,8 @@
|
||||||
"follow_requests.unlocked_explanation": "Иако ваш налог није закључан, особље {domain} сматра да бисте можда желели да ручно прегледате захтеве за праћење са ових налога.",
|
"follow_requests.unlocked_explanation": "Иако ваш налог није закључан, особље {domain} сматра да бисте можда желели да ручно прегледате захтеве за праћење са ових налога.",
|
||||||
"follow_suggestions.curated_suggestion": "Избор особља",
|
"follow_suggestions.curated_suggestion": "Избор особља",
|
||||||
"follow_suggestions.dismiss": "Не приказуј поново",
|
"follow_suggestions.dismiss": "Не приказуј поново",
|
||||||
|
"follow_suggestions.featured_longer": "Ручно одабрао тим {domain}",
|
||||||
|
"follow_suggestions.friends_of_friends_longer": "Популарно међу људима које пратите",
|
||||||
"follow_suggestions.hints.featured": "Овај профил је ручно изабрао тим {domain}.",
|
"follow_suggestions.hints.featured": "Овај профил је ручно изабрао тим {domain}.",
|
||||||
"follow_suggestions.hints.friends_of_friends": "Овај профил је популаран међу људима које пратите.",
|
"follow_suggestions.hints.friends_of_friends": "Овај профил је популаран међу људима које пратите.",
|
||||||
"follow_suggestions.hints.most_followed": "Овај профил је један од најпраћенијих на {domain}.",
|
"follow_suggestions.hints.most_followed": "Овај профил је један од најпраћенијих на {domain}.",
|
||||||
|
@ -315,6 +317,8 @@
|
||||||
"follow_suggestions.hints.similar_to_recently_followed": "Овај профил је сличан профилима које сте недавно запратили.",
|
"follow_suggestions.hints.similar_to_recently_followed": "Овај профил је сличан профилима које сте недавно запратили.",
|
||||||
"follow_suggestions.personalized_suggestion": "Персонализовани предлог",
|
"follow_suggestions.personalized_suggestion": "Персонализовани предлог",
|
||||||
"follow_suggestions.popular_suggestion": "Популарни предлог",
|
"follow_suggestions.popular_suggestion": "Популарни предлог",
|
||||||
|
"follow_suggestions.popular_suggestion_longer": "Популарно на {domain}",
|
||||||
|
"follow_suggestions.similar_to_recently_followed_longer": "Слично профилима које сте недавно запратили",
|
||||||
"follow_suggestions.view_all": "Прикажи све",
|
"follow_suggestions.view_all": "Прикажи све",
|
||||||
"follow_suggestions.who_to_follow": "Кога пратити",
|
"follow_suggestions.who_to_follow": "Кога пратити",
|
||||||
"followed_tags": "Праћене хеш ознаке",
|
"followed_tags": "Праћене хеш ознаке",
|
||||||
|
@ -469,6 +473,15 @@
|
||||||
"notification.follow": "{name} вас је запратио",
|
"notification.follow": "{name} вас је запратио",
|
||||||
"notification.follow_request": "{name} је затражио да вас прати",
|
"notification.follow_request": "{name} је затражио да вас прати",
|
||||||
"notification.mention": "{name} вас је поменуо",
|
"notification.mention": "{name} вас је поменуо",
|
||||||
|
"notification.moderation-warning.learn_more": "Сазнајте више",
|
||||||
|
"notification.moderation_warning": "Добили сте модераторско упозорење",
|
||||||
|
"notification.moderation_warning.action_delete_statuses": "Неке од ваших објава су уклоњене.",
|
||||||
|
"notification.moderation_warning.action_disable": "Ваш налог је онемогућен.",
|
||||||
|
"notification.moderation_warning.action_mark_statuses_as_sensitive": "Неке од ваших објава су обележене као осетљиве.",
|
||||||
|
"notification.moderation_warning.action_none": "Ваш налог је добио модераторско упозорење.",
|
||||||
|
"notification.moderation_warning.action_sensitive": "Ваше објаве ће убудуће бити означене као осетљиве.",
|
||||||
|
"notification.moderation_warning.action_silence": "Ваш налог је ограничен.",
|
||||||
|
"notification.moderation_warning.action_suspend": "Ваш налог је суспендован.",
|
||||||
"notification.own_poll": "Ваша анкета је завршена",
|
"notification.own_poll": "Ваша анкета је завршена",
|
||||||
"notification.poll": "Завршена је анкета у којој сте гласали",
|
"notification.poll": "Завршена је анкета у којој сте гласали",
|
||||||
"notification.reblog": "{name} је подржао вашу објаву",
|
"notification.reblog": "{name} је подржао вашу објаву",
|
||||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue